65 lines
2.6 KiB
TypeScript
65 lines
2.6 KiB
TypeScript
import { DISCORD_SERVER_ID, PLUGINS_CHANNEL_ID, THEMES_CHANNEL_ID, HTTP_REGEX_MULTI, PROXY_PREFIX } from "@lib/constants";
|
|
import { findByName, findByProps } from "@metro/filters";
|
|
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 { showToast } from "@ui/toasts";
|
|
import { Forms } from "@ui/components";
|
|
|
|
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: "Plugin" | "Theme";
|
|
if (thread.parent_id === PLUGINS_CHANNEL_ID) {
|
|
postType = "Plugin";
|
|
} else if (thread.parent_id === THEMES_CHANNEL_ID && window.__vendetta_loader?.features.themes) {
|
|
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>);
|
|
});
|