[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
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…
Add table
Add a link
Reference in a new issue