[UI > QuickInstall] Implement (#45)
* [UI > QuickInstall] Init * [Constants] Update PROXY_PREFIX * [TS] Type additional constants * [Style] Move Metro filter imports to top of imports
This commit is contained in:
parent
3082c840c8
commit
5148fdb15f
6 changed files with 118 additions and 1 deletions
5
src/def.d.ts
vendored
5
src/def.d.ts
vendored
|
@ -369,8 +369,13 @@ interface VendettaObject {
|
|||
};
|
||||
constants: {
|
||||
DISCORD_SERVER: string;
|
||||
DISCORD_SERVER_ID: string;
|
||||
PLUGINS_CHANNEL_ID: string;
|
||||
THEMES_CHANNEL_ID: string;
|
||||
GITHUB: string;
|
||||
PROXY_PREFIX: string;
|
||||
HTTP_REGEX: RegExp;
|
||||
HTTP_REGEX_MULTI: RegExp;
|
||||
};
|
||||
utils: {
|
||||
findInReactTree: (tree: SearchTree, filter: SearchFilter) => any;
|
||||
|
|
|
@ -2,6 +2,7 @@ import { patchLogHook } from "@lib/debug";
|
|||
import { patchCommands } from "@lib/commands";
|
||||
import { initPlugins } from "@lib/plugins";
|
||||
import { patchAssets } from "@ui/assets";
|
||||
import initQuickInstall from "@ui/quickInstall";
|
||||
import initSettings from "@ui/settings";
|
||||
import initFixes from "@lib/fixes";
|
||||
import logger from "@lib/logger";
|
||||
|
@ -15,6 +16,7 @@ export default async () => {
|
|||
patchCommands(),
|
||||
initFixes(),
|
||||
initSettings(),
|
||||
initQuickInstall(),
|
||||
]);
|
||||
|
||||
// Assign window object
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
export const DISCORD_SERVER = "https://discord.gg/n9QQ4XhhJP";
|
||||
export const DISCORD_SERVER_ID = "1015931589865246730";
|
||||
export const PLUGINS_CHANNEL_ID = "1091880384561684561";
|
||||
export const THEMES_CHANNEL_ID = "1091880434939482202";
|
||||
export const GITHUB = "https://github.com/vendetta-mod";
|
||||
export const PROXY_PREFIX = "https://vd-plugins.github.io/proxy";
|
||||
export const HTTP_REGEX = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/;
|
||||
export const HTTP_REGEX_MULTI = /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g;
|
65
src/ui/quickInstall/forumPost.tsx
Normal file
65
src/ui/quickInstall/forumPost.tsx
Normal file
|
@ -0,0 +1,65 @@
|
|||
import { findByName, findByProps } from "@metro/filters";
|
||||
import { DISCORD_SERVER_ID, PLUGINS_CHANNEL_ID, THEMES_CHANNEL_ID, HTTP_REGEX_MULTI, PROXY_PREFIX } from "@lib/constants";
|
||||
import { after } from "@lib/patcher";
|
||||
import { installPlugin } from "@lib/plugins";
|
||||
import { installTheme } from "@lib/themes";
|
||||
import { findInReactTree } from "@lib/utils";
|
||||
import { getAssetIDByName } from "@ui/assets";
|
||||
import { Forms } from "@ui/components";
|
||||
import { showToast } from "@ui/toasts";
|
||||
|
||||
const ForumPostLongPressActionSheet = findByName("ForumPostLongPressActionSheet", false);
|
||||
const { FormRow } = Forms;
|
||||
// Discord uses this Icon in action sheets. FormRow.Icon is too dark.
|
||||
const Icon = findByName("Icon");
|
||||
|
||||
const { useFirstForumPostMessage } = findByProps("useFirstForumPostMessage");
|
||||
const { hideActionSheet } = findByProps("openLazy", "hideActionSheet");
|
||||
|
||||
export default () => after("default", ForumPostLongPressActionSheet, ([{ thread }], res) => {
|
||||
if (thread.guild_id !== DISCORD_SERVER_ID) return;
|
||||
|
||||
// Determine what type of addon this is.
|
||||
let postType: string;
|
||||
if (thread.parent_id === PLUGINS_CHANNEL_ID) {
|
||||
postType = "Plugin";
|
||||
} else if (thread.parent_id === THEMES_CHANNEL_ID) {
|
||||
postType = "Theme";
|
||||
} else return;
|
||||
|
||||
const { firstMessage } = useFirstForumPostMessage(thread);
|
||||
|
||||
let urls = firstMessage?.content?.match(HTTP_REGEX_MULTI);
|
||||
if (!urls) return;
|
||||
|
||||
if (postType === "Plugin") {
|
||||
urls = urls.filter((url: string) => url.startsWith(PROXY_PREFIX));
|
||||
} else {
|
||||
urls = urls.filter((url: string) => url.endsWith(".json"));
|
||||
};
|
||||
|
||||
const url = urls[0];
|
||||
if (!url) return;
|
||||
|
||||
/* Assuming that the actions array is at index 1
|
||||
could break in the future, but I doubt Discord
|
||||
will add more to the post action sheet and
|
||||
index 0 will either be quick add reactions or false.
|
||||
*/
|
||||
const actions = findInReactTree(res, (t) => t.props?.bottom === true).props.children.props.children[1];
|
||||
const ActionsSection = actions[0].type;
|
||||
|
||||
actions.unshift(<ActionsSection key="install">
|
||||
<FormRow
|
||||
leading={<Icon source={getAssetIDByName("ic_download_24px")} />}
|
||||
label={`Install ${postType}`}
|
||||
onPress={() =>
|
||||
(postType === "Plugin" ? installPlugin : installTheme)(url).then(() => {
|
||||
showToast(`Successfully installed ${thread.name}`, getAssetIDByName("Check"));
|
||||
}).catch((e: Error) => {
|
||||
showToast(e.message, getAssetIDByName("Small"));
|
||||
}).finally(() => hideActionSheet())
|
||||
}
|
||||
/>
|
||||
</ActionsSection>);
|
||||
});
|
11
src/ui/quickInstall/index.ts
Normal file
11
src/ui/quickInstall/index.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import patchForumPost from "@ui/quickInstall/forumPost";
|
||||
import patchUrl from "@ui/quickInstall/url";
|
||||
|
||||
export default function initQuickInstall() {
|
||||
const patches = new Array<Function>;
|
||||
|
||||
patches.push(patchForumPost());
|
||||
patches.push(patchUrl());
|
||||
|
||||
return () => patches.forEach(p => p());
|
||||
};
|
29
src/ui/quickInstall/url.ts
Normal file
29
src/ui/quickInstall/url.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { findByProps } from "@metro/filters";
|
||||
import { PROXY_PREFIX } from "@lib/constants";
|
||||
import { after } from "@lib/patcher";
|
||||
import { installPlugin } from "@lib/plugins";
|
||||
import { installTheme } from "@lib/themes";
|
||||
import { getAssetIDByName } from "@ui/assets";
|
||||
import { showToast } from "@ui/toasts";
|
||||
|
||||
const showSimpleActionSheet = findByProps("showSimpleActionSheet");
|
||||
|
||||
export default () => after("showSimpleActionSheet", showSimpleActionSheet, ([{ key, header: { title: url }, options }]) => {
|
||||
if (key !== "LongPressUrl") return;
|
||||
|
||||
let urlType: string;
|
||||
if (url.startsWith(PROXY_PREFIX)) {
|
||||
urlType = "Plugin";
|
||||
} else if (url.endsWith(".json")) {
|
||||
urlType = "Theme";
|
||||
} else return;
|
||||
|
||||
options.push({
|
||||
label: `Install ${urlType}`, onPress: () =>
|
||||
(urlType === "Plugin" ? installPlugin : installTheme)(url).then(() => {
|
||||
showToast("Successfully installed", getAssetIDByName("Check"));
|
||||
}).catch((e: Error) => {
|
||||
showToast(e.message, getAssetIDByName("Small"));
|
||||
}),
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue