refactor(api/assets): rename func & rewrite scrap logic

This commit is contained in:
amsyarasyiq 2024-05-23 01:41:43 +08:00
parent 829e7d59ca
commit de79efe1dd
21 changed files with 115 additions and 106 deletions

View file

@ -1,5 +1,5 @@
import { Strings } from "@core/i18n";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { isThemeSupported } from "@lib/api/native/loader";
import { after } from "@lib/api/patcher";
import { useProxy } from "@lib/api/storage";
@ -77,7 +77,7 @@ function useInstaller(thread: any, firstMessage = null, actionSheet = false): [t
try {
await postMap[postType].installOrRemove(url);
} catch (e: any) {
showToast(e.message, getAssetIDByName("Small"));
showToast(e.message, requireAssetIndex("Small"));
} finally {
setIsInstalling(false);
}
@ -119,7 +119,7 @@ const installButtonPatch = () => after("MostCommonForumPostReaction", forumReact
variant={installed ? "secondary" : "primary"}
text={installed ? Strings.UNINSTALL : Strings.INSTALL}
onPress={installOrRemove}
icon={getAssetIDByName(installed ? "ic_message_delete" : "DownloadIcon")}
icon={requireAssetIndex(installed ? "ic_message_delete" : "DownloadIcon")}
style={{ marginLeft: 8 }}
/>
</ErrorBoundary>

View file

@ -1,5 +1,5 @@
import { formatString, Strings } from "@core/i18n";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { isThemeSupported } from "@lib/api/native/loader";
import { after, instead } from "@lib/api/patcher";
import { installPlugin } from "@lib/managers/plugins";
@ -30,10 +30,10 @@ function typeFromUrl(url: string) {
function installWithToast(type: "plugin" | "theme", url: string) {
(type === "plugin" ? installPlugin : installTheme)(url)
.then(() => {
showToast(Strings.SUCCESSFULLY_INSTALLED, getAssetIDByName("Check"));
showToast(Strings.SUCCESSFULLY_INSTALLED, requireAssetIndex("Check"));
})
.catch((e: Error) => {
showToast(e.message, getAssetIDByName("Small"));
showToast(e.message, requireAssetIndex("Small"));
});
}

View file

@ -1,6 +1,6 @@
import { Strings } from "@core/i18n";
import { CardWrapper } from "@core/ui/components/Card";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { useProxy } from "@lib/api/storage";
import { settings } from "@lib/settings";
import { HTTP_REGEX_MULTI } from "@lib/utils/constants";
@ -85,7 +85,7 @@ export default function AddonPage<T>({ floatingButtonText, fetchFunction, items,
/>
<FloatingActionButton
text={floatingButtonText}
icon={getAssetIDByName("PlusLargeIcon")}
icon={requireAssetIndex("PlusLargeIcon")}
state={{ collapseText }}
onPress={onFABPress ?? (() => {
// from ./InstallButton.tsx

View file

@ -1,4 +1,4 @@
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { lazyDestructure } from "@lib/utils/lazy";
import { ReactNative as RN } from "@metro/common";
import { findByProps } from "@metro/utils";
@ -96,7 +96,7 @@ export default function Card(props: CardProps) {
return (
<RN.View style={[styles.card, { marginTop: props.index !== 0 ? 15 : 0 }]}>
<ImageBackground
source={props.headerIcon && getAssetIDByName(props.headerIcon) || {}}
source={props.headerIcon && requireAssetIndex(props.headerIcon) || {}}
resizeMode="cover"
imageStyle={styles.iconStyle}
>
@ -119,14 +119,14 @@ export default function Card(props: CardProps) {
key: "CardOverflow",
header: {
title: props.overflowTitle,
icon: props.headerIcon && <FormRow.Icon style={{ marginRight: 8 }} source={getAssetIDByName(props.headerIcon)} />,
icon: props.headerIcon && <FormRow.Icon style={{ marginRight: 8 }} source={requireAssetIndex(props.headerIcon)} />,
onClose: () => hideActionSheet(),
},
options: props.overflowActions?.map(i => ({ ...i, icon: getAssetIDByName(i.icon) })),
options: props.overflowActions?.map(i => ({ ...i, icon: requireAssetIndex(i.icon) })),
})}
size="sm"
variant="secondary"
icon={getAssetIDByName("CircleInformationIcon-primary")}
icon={requireAssetIndex("CircleInformationIcon-primary")}
/>}
{props.actions?.map(({ icon, onPress, disabled }) => (
<IconButton
@ -134,7 +134,7 @@ export default function Card(props: CardProps) {
disabled={disabled}
size="sm"
variant="secondary"
icon={getAssetIDByName(icon)}
icon={requireAssetIndex(icon)}
/>
))}
</View>

View file

@ -1,6 +1,6 @@
import { Strings } from "@core/i18n";
import { CardWrapper } from "@core/ui/components/Card";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { useProxy } from "@lib/api/storage";
import { FontDefinition, fonts, removeFont, selectFont } from "@lib/managers/fonts";
import { FormCheckbox, IconButton, TableRow, TableRowGroup } from "@ui/components/discord/Redesign";
@ -23,13 +23,13 @@ export default function FontCard({ item: font, index }: CardWrapper<FontDefiniti
trailing={
<Pressable onPress={() => {
selectFont(selected ? null : font.name).then(() => {
showToast(Strings.RESTART_REQUIRED_TO_TAKE_EFFECT, getAssetIDByName("WarningIcon"));
showToast(Strings.RESTART_REQUIRED_TO_TAKE_EFFECT, requireAssetIndex("WarningIcon"));
});
}}>
{!removeMode ? <FormCheckbox checked={selected} /> : <IconButton
size="sm"
variant="secondary"
icon={getAssetIDByName("TrashIcon")}
icon={requireAssetIndex("TrashIcon")}
onPress={() => removeFont(font.name)}
/>}
</Pressable>

View file

@ -1,5 +1,5 @@
import { Strings } from "@core/i18n";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { HTTP_REGEX_MULTI } from "@lib/utils/constants";
import { clipboard } from "@metro/common";
import { showInputAlert } from "@ui/alerts";
@ -35,7 +35,7 @@ export default function InstallButton({ alertTitle, installFunction: fetchFuncti
})
)
}>
<Image style={styles.icon} source={getAssetIDByName("ic_add_24px")} />
<Image style={styles.icon} source={requireAssetIndex("ic_add_24px")} />
</TouchableOpacity>
);
}

View file

@ -1,6 +1,6 @@
import { formatString, Strings } from "@core/i18n";
import Card, { CardWrapper } from "@core/ui/components/Card";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { purgeStorage, useProxy } from "@lib/api/storage";
import { BunnyPlugin, fetchPlugin, getSettings, removePlugin, startPlugin, stopPlugin } from "@lib/managers/plugins";
import { ButtonColors } from "@lib/utils/types";
@ -37,7 +37,7 @@ export default function PluginCard({ item: plugin, index }: CardWrapper<BunnyPlu
try {
if (v) startPlugin(plugin.id); else stopPlugin(plugin.id);
} catch (e) {
showToast((e as Error).message, getAssetIDByName("Small"));
showToast((e as Error).message, requireAssetIndex("Small"));
}
}}
descriptionLabel={plugin.manifest.description}
@ -65,9 +65,9 @@ export default function PluginCard({ item: plugin, index }: CardWrapper<BunnyPlu
onPress: async () => {
stopThenStart(plugin, () => {
fetchPlugin(plugin.id).then(async () => {
showToast(Strings.PLUGIN_REFETCH_SUCCESSFUL, getAssetIDByName("toast_image_saved"));
showToast(Strings.PLUGIN_REFETCH_SUCCESSFUL, requireAssetIndex("toast_image_saved"));
}).catch(() => {
showToast(Strings.PLUGIN_REFETCH_FAILED, getAssetIDByName("Small"));
showToast(Strings.PLUGIN_REFETCH_FAILED, requireAssetIndex("Small"));
});
});
},
@ -85,7 +85,7 @@ export default function PluginCard({ item: plugin, index }: CardWrapper<BunnyPlu
label: plugin.update ? Strings.DISABLE_UPDATES : Strings.ENABLE_UPDATES,
onPress: () => {
plugin.update = !plugin.update;
showToast(formatString("TOASTS_PLUGIN_UPDATE", { update: plugin.update, name: plugin.manifest.name }), getAssetIDByName("toast_image_saved"));
showToast(formatString("TOASTS_PLUGIN_UPDATE", { update: plugin.update, name: plugin.manifest.name }), requireAssetIndex("toast_image_saved"));
}
},
{
@ -102,9 +102,9 @@ export default function PluginCard({ item: plugin, index }: CardWrapper<BunnyPlu
stopThenStart(plugin, () => {
try {
purgeStorage(plugin.id);
showToast(formatString("CLEAR_DATA_SUCCESSFUL", { name: plugin.manifest.name }), getAssetIDByName("trash"));
showToast(formatString("CLEAR_DATA_SUCCESSFUL", { name: plugin.manifest.name }), requireAssetIndex("trash"));
} catch {
showToast(formatString("CLEAR_DATA_FAILED", { name: plugin.manifest.name }), getAssetIDByName("Small"));
showToast(formatString("CLEAR_DATA_FAILED", { name: plugin.manifest.name }), requireAssetIndex("Small"));
}
});
}
@ -125,7 +125,7 @@ export default function PluginCard({ item: plugin, index }: CardWrapper<BunnyPlu
removePlugin(plugin.id);
setRemoved(true);
} catch (e) {
showToast((e as Error).message, getAssetIDByName("Small"));
showToast((e as Error).message, requireAssetIndex("Small"));
}
}
}),

View file

@ -1,6 +1,6 @@
import { formatString, Strings } from "@core/i18n";
import Card, { CardWrapper } from "@core/ui/components/Card";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { useProxy } from "@lib/api/storage";
import { applyTheme, fetchTheme, removeTheme, selectTheme, Theme } from "@lib/managers/themes";
import { settings } from "@lib/settings";
@ -46,9 +46,9 @@ export default function ThemeCard({ item: theme, index }: CardWrapper<Theme>) {
label: Strings.REFETCH,
onPress: () => {
fetchTheme(theme.id, theme.selected).then(() => {
showToast(Strings.THEME_REFETCH_SUCCESSFUL, getAssetIDByName("toast_image_saved"));
showToast(Strings.THEME_REFETCH_SUCCESSFUL, requireAssetIndex("toast_image_saved"));
}).catch(() => {
showToast(Strings.THEME_REFETCH_FAILED, getAssetIDByName("Small"));
showToast(Strings.THEME_REFETCH_FAILED, requireAssetIndex("Small"));
});
},
},
@ -75,7 +75,7 @@ export default function ThemeCard({ item: theme, index }: CardWrapper<Theme>) {
setRemoved(true);
if (wasSelected) selectAndApply(false, theme);
}).catch((e: Error) => {
showToast(e.message, getAssetIDByName("Small"));
showToast(e.message, requireAssetIndex("Small"));
});
}
})

View file

@ -1,4 +1,4 @@
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { clipboard } from "@metro/common";
import { FormText } from "@ui/components/discord/Forms";
import { TableRow } from "@ui/components/discord/Redesign";
@ -14,7 +14,7 @@ export default function Version({ label, version, icon }: VersionProps) {
return (
<TableRow
label={label}
icon={<TableRow.Icon source={getAssetIDByName(icon)} />}
icon={<TableRow.Icon source={requireAssetIndex(icon)} />}
trailing={<FormText>{version}</FormText>}
onPress={() => {
clipboard.setString(`${label} - ${version}`);

View file

@ -1,5 +1,5 @@
import { Strings } from "@core/i18n";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { isFontSupported, isThemeSupported } from "@lib/api/native/loader";
import { useProxy } from "@lib/api/storage";
import { settings } from "@lib/settings";
@ -28,27 +28,27 @@ export default function initSettings() {
{
key: "BUNNY_PLUGINS",
title: () => Strings.PLUGINS,
icon: getAssetIDByName("ActivitiesIcon"),
icon: requireAssetIndex("ActivitiesIcon"),
render: () => import("@core/ui/settings/pages/Plugins")
},
{
key: "BUNNY_THEMES",
title: () => Strings.THEMES,
icon: getAssetIDByName("PaintPaletteIcon"),
icon: requireAssetIndex("PaintPaletteIcon"),
render: () => import("@core/ui/settings/pages/Themes"),
usePredicate: () => isThemeSupported()
},
{
key: "BUNNY_FONTS",
title: () => Strings.FONTS,
icon: getAssetIDByName("ic_add_text"),
icon: requireAssetIndex("ic_add_text"),
render: () => import("@core/ui/settings/pages/Fonts"),
usePredicate: () => isFontSupported()
},
{
key: "BUNNY_DEVELOPER",
title: () => Strings.DEVELOPER,
icon: getAssetIDByName("WrenchIcon"),
icon: requireAssetIndex("WrenchIcon"),
render: () => import("@core/ui/settings/pages/Developer"),
usePredicate: () => useProxy(settings).developerSettings ?? false
}

View file

@ -1,5 +1,5 @@
import AssetDisplay from "@core/ui/components/AssetDisplay";
import { all } from "@lib/api/assets";
import { assetsMap } from "@lib/api/assets";
import { ErrorBoundary, Search } from "@ui/components";
import { FormDivider } from "@ui/components/discord/Forms";
import { FlatList, View } from "react-native";
@ -15,7 +15,7 @@ export default function AssetBrowser() {
onChangeText={(v: string) => setSearch(v)}
/>
<FlatList
data={Object.values(all).filter(a => a.name.includes(search) || a.id.toString() === search)}
data={Object.values(assetsMap).filter(a => a.name.includes(search) || a.id.toString() === search)}
renderItem={({ item }) => <AssetDisplay asset={item} />}
ItemSeparatorComponent={FormDivider}
keyExtractor={item => item.name}

View file

@ -1,7 +1,7 @@
import { Strings } from "@core/i18n";
import { CheckState, useFileExists } from "@core/ui/settings/hooks/useFS";
import AssetBrowser from "@core/ui/settings/pages/AssetBrowser";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { getReactDevToolsProp, getReactDevToolsVersion, isLoaderConfigSupported, isReactDevToolsPreloaded, isVendettaLoader } from "@lib/api/native/loader";
import { useProxy } from "@lib/api/storage";
import { connectToDebugger } from "@lib/debug";
@ -53,13 +53,13 @@ export default function Developer() {
<TableRowGroup title={Strings.DEBUG}>
<TableRow
label={Strings.CONNECT_TO_DEBUG_WEBSOCKET}
icon={<TableRow.Icon source={getAssetIDByName("copy")} />}
icon={<TableRow.Icon source={requireAssetIndex("copy")} />}
onPress={() => connectToDebugger(settings.debuggerUrl)}
/>
{isReactDevToolsPreloaded() && <>
<TableRow
label={Strings.CONNECT_TO_REACT_DEVTOOLS}
icon={<TableRow.Icon source={getAssetIDByName("ic_badge_staff")} />}
icon={<TableRow.Icon source={requireAssetIndex("ic_badge_staff")} />}
onPress={() => window[getReactDevToolsProp() || "__vendetta_rdc"]?.connectToDevTools({
host: settings.debuggerUrl.split(":")?.[0],
resolveRNStyle: StyleSheet.flatten,
@ -72,7 +72,7 @@ export default function Developer() {
<TableSwitchRow
label={Strings.LOAD_FROM_CUSTOM_URL}
subLabel={Strings.LOAD_FROM_CUSTOM_URL_DEC}
icon={<TableRow.Icon source={getAssetIDByName("copy")} />}
icon={<TableRow.Icon source={requireAssetIndex("copy")} />}
value={loaderConfig.customLoadUrl.enabled}
onValueChange={(v: boolean) => {
loaderConfig.customLoadUrl.enabled = v;
@ -88,7 +88,7 @@ export default function Developer() {
{isReactDevToolsPreloaded() && isVendettaLoader() && <TableSwitchRow
label={Strings.LOAD_REACT_DEVTOOLS}
subLabel={`${Strings.VERSION}: ${getReactDevToolsVersion()}`}
icon={<TableRow.Icon source={getAssetIDByName("ic_badge_staff")} />}
icon={<TableRow.Icon source={requireAssetIndex("ic_badge_staff")} />}
value={loaderConfig.loadReactDevTools}
onValueChange={(v: boolean) => {
loaderConfig.loadReactDevTools = v;
@ -100,7 +100,7 @@ export default function Developer() {
<TableRow
arrow
label={Strings.ASSET_BROWSER}
icon={<TableRow.Icon source={getAssetIDByName("ic_image")} />}
icon={<TableRow.Icon source={requireAssetIndex("ic_image")} />}
trailing={TableRow.Arrow}
onPress={() => navigation.push("VendettaCustomPage", {
title: Strings.ASSET_BROWSER,
@ -110,12 +110,12 @@ export default function Developer() {
<TableRow
arrow
label={Strings.ERROR_BOUNDARY_TOOLS_LABEL}
icon={<TableRow.Icon source={getAssetIDByName("ic_warning_24px")} />}
icon={<TableRow.Icon source={requireAssetIndex("ic_warning_24px")} />}
onPress={() => showSimpleActionSheet({
key: "ErrorBoundaryTools",
header: {
title: "Which ErrorBoundary do you want to trip?",
icon: <TableRow.Icon style={{ marginRight: 8 }} source={getAssetIDByName("ic_warning_24px")} />,
icon: <TableRow.Icon style={{ marginRight: 8 }} source={requireAssetIndex("ic_warning_24px")} />,
onClose: () => hideActionSheet(),
},
options: [
@ -129,7 +129,7 @@ export default function Developer() {
<TableRow
label={Strings.INSTALL_REACT_DEVTOOLS}
subLabel={Strings.RESTART_REQUIRED_TO_TAKE_EFFECT}
icon={<TableRow.Icon source={getAssetIDByName("DownloadIcon")} />}
icon={<TableRow.Icon source={requireAssetIndex("DownloadIcon")} />}
trailing={
<Button
size="sm"
@ -144,7 +144,7 @@ export default function Developer() {
fs.removeFile("preloads/reactDevtools.js");
}
}}
icon={getAssetIDByName(rdtFileExists === CheckState.TRUE ? "ic_message_delete" : "DownloadIcon")}
icon={requireAssetIndex(rdtFileExists === CheckState.TRUE ? "ic_message_delete" : "DownloadIcon")}
style={{ marginLeft: 8 }}
/>
}
@ -152,7 +152,7 @@ export default function Developer() {
<TableSwitchRow
label={Strings.ENABLE_EVAL_COMMAND}
subLabel={Strings.ENABLE_EVAL_COMMAND_DESC}
icon={<TableRow.Icon source={getAssetIDByName("PencilIcon")} />}
icon={<TableRow.Icon source={requireAssetIndex("PencilIcon")} />}
value={settings.enableEvalCommand}
onValueChange={(v: boolean) => {
settings.enableEvalCommand = v;

View file

@ -1,5 +1,5 @@
import { formatString, Strings } from "@core/i18n";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { createProxy, useProxy } from "@lib/api/storage";
import { FontDefinition, saveFont, validateFont } from "@lib/managers/fonts";
import { getCurrentTheme } from "@lib/managers/themes";
@ -153,7 +153,7 @@ function EntryRow({ fontEntry }: { fontEntry: Record<string, string>; }) {
size="md"
label={nameSet ? nameRef.current : void 0}
placeholder={nameSet ? "https://path.to/the/file.ttf" : "PostScript name (e.g. ggsans-Bold)"}
leadingIcon={() => nameSet ? null : <TableRow.Icon source={getAssetIDByName("PlusSmallIcon")} />}
leadingIcon={() => nameSet ? null : <TableRow.Icon source={requireAssetIndex("PlusSmallIcon")} />}
leadingText={nameSet ? nameRef.current : ""}
onChange={(text: string) => (nameSet ? urlRef : nameRef).current = text}
errorMessage={error}
@ -167,7 +167,7 @@ function EntryRow({ fontEntry }: { fontEntry: Record<string, string>; }) {
nameRef.current = "";
setNameSet(false);
}}
icon={getAssetIDByName("TrashIcon")}
icon={requireAssetIndex("TrashIcon")}
/>}
<IconButton
size="md"
@ -191,7 +191,7 @@ function EntryRow({ fontEntry }: { fontEntry: Record<string, string>; }) {
}
}
}}
icon={getAssetIDByName(nameSet ? "PlusSmallIcon" : "ArrowLargeRightIcon")}
icon={requireAssetIndex(nameSet ? "PlusSmallIcon" : "ArrowLargeRightIcon")}
/>
</View>;
}
@ -212,13 +212,13 @@ export default function FontImporter() {
{getCurrentTheme()?.data?.fonts && <TableRow
label={Strings.LABEL_EXTRACT_FONTS_FROM_THEME}
subLabel={Strings.DESC_EXTRACT_FONTS_FROM_THEME}
icon={<TableRow.Icon source={getAssetIDByName("HammerIcon")} />}
icon={<TableRow.Icon source={requireAssetIndex("HammerIcon")} />}
onPress={() => promptActionSheet(RevengeFontsExtractor, fontEntries, setName)}
/>}
<TableRow
label={"Import font entries from a link"}
subLabel={"Directly import from a link with a pre-configured JSON file"}
icon={<TableRow.Icon source={getAssetIDByName("LinkIcon")} />}
icon={<TableRow.Icon source={requireAssetIndex("LinkIcon")} />}
onPress={() => promptActionSheet(JsonFontImporter, fontEntries, setName)}
/>
</TableRowGroup>
@ -237,7 +237,7 @@ export default function FontImporter() {
trailing={<IconButton
size="sm"
variant="secondary"
icon={getAssetIDByName("TrashIcon")}
icon={requireAssetIndex("TrashIcon")}
onPress={() => delete fontEntries[name]}
/>}
/>;
@ -264,7 +264,7 @@ export default function FontImporter() {
.then(() => navigation.goBack())
.finally(() => setIsImporting(false));
}}
icon={getAssetIDByName("DownloadIcon")}
icon={requireAssetIndex("DownloadIcon")}
style={{ marginLeft: 8 }}
/>
</View>

View file

@ -1,6 +1,6 @@
import { Strings } from "@core/i18n";
import { PyoncordIcon } from "@core/ui/settings";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { useProxy } from "@lib/api/storage";
import { getDebugInfo, toggleSafeMode } from "@lib/debug";
import { settings } from "@lib/settings";
@ -28,13 +28,13 @@ export default function General() {
/>
<TableRow
label={"Discord"}
icon={<TableRow.Icon source={getAssetIDByName("Discord")} />}
icon={<TableRow.Icon source={requireAssetIndex("Discord")} />}
trailing={<TableRow.TrailingText text={`${debugInfo.discord.version} (${debugInfo.discord.build})`} />}
/>
<TableRow
arrow
label={Strings.ABOUT}
icon={<TableRow.Icon source={getAssetIDByName("CircleInformationIcon-primary")} />}
icon={<TableRow.Icon source={requireAssetIndex("CircleInformationIcon-primary")} />}
trailing={TableRow.Arrow}
onPress={() => navigation.push("VendettaCustomPage", {
title: Strings.ABOUT,
@ -45,13 +45,13 @@ export default function General() {
<TableRowGroup title={Strings.LINKS}>
<TableRow
label={Strings.DISCORD_SERVER}
icon={<TableRow.Icon source={getAssetIDByName("Discord")} />}
icon={<TableRow.Icon source={requireAssetIndex("Discord")} />}
trailing={TableRow.Arrow}
onPress={() => url.openDeeplink(DISCORD_SERVER)}
/>
<TableRow
label={Strings.GITHUB}
icon={<TableRow.Icon source={getAssetIDByName("img_account_sync_github_white")} />}
icon={<TableRow.Icon source={requireAssetIndex("img_account_sync_github_white")} />}
trailing={TableRow.Arrow}
onPress={() => url.openURL(GITHUB)}
/>
@ -59,18 +59,18 @@ export default function General() {
<TableRowGroup title={Strings.ACTIONS}>
<TableRow
label={Strings.RELOAD_DISCORD}
icon={<TableRow.Icon source={getAssetIDByName("ic_message_retry")} />}
icon={<TableRow.Icon source={requireAssetIndex("ic_message_retry")} />}
onPress={() => NativeModules.BundleUpdaterManager.reload()}
/>
<TableRow
label={settings.safeMode?.enabled ? Strings.RELOAD_IN_NORMAL_MODE : Strings.RELOAD_IN_SAFE_MODE}
subLabel={settings.safeMode?.enabled ? Strings.RELOAD_IN_NORMAL_MODE_DESC : Strings.RELOAD_IN_SAFE_MODE_DESC}
icon={<TableRow.Icon source={getAssetIDByName("ic_privacy_24px")} />}
icon={<TableRow.Icon source={requireAssetIndex("ic_privacy_24px")} />}
onPress={toggleSafeMode}
/>
<TableSwitchRow
label={Strings.DEVELOPER_SETTINGS}
icon={<TableRow.Icon source={getAssetIDByName("ic_progress_wrench_24px")} />}
icon={<TableRow.Icon source={requireAssetIndex("ic_progress_wrench_24px")} />}
value={settings.developerSettings}
onValueChange={(v: boolean) => {
settings.developerSettings = v;
@ -81,7 +81,7 @@ export default function General() {
<TableSwitchRow
label={Strings.SETTINGS_ACTIVATE_DISCORD_EXPERIMENTS}
subLabel={Strings.SETTINGS_ACTIVATE_DISCORD_EXPERIMENTS_DESC}
icon={<TableRow.Icon source={getAssetIDByName("ic_progress_wrench_24px")} />}
icon={<TableRow.Icon source={requireAssetIndex("ic_progress_wrench_24px")} />}
value={settings.enableDiscordDeveloperSettings}
onValueChange={(v: boolean) => {
settings.enableDiscordDeveloperSettings = v;

View file

@ -127,11 +127,11 @@ export const initVendettaObject = (): any => {
showInputAlert: (options: any) => alerts.showInputAlert(options)
},
assets: {
all: assets.all,
find: (filter: (a: any) => void) => assets.find(filter),
getAssetByName: (name: string) => assets.getAssetByName(name),
getAssetByID: (id: number) => assets.getAssetByID(id),
getAssetIDByName: (name: string) => assets.getAssetIDByName(name)
all: assets.assetsMap,
find: (filter: (a: any) => void) => assets.findAsset(filter),
getAssetByName: (name: string) => assets.requireAssetByName(name),
getAssetByID: (id: number) => assets.requireAssetByIndex(id),
getAssetIDByName: (name: string) => assets.requireAssetIndex(name)
},
semanticColors: color.semanticColors,
rawColors: color.rawColors

View file

@ -4,11 +4,34 @@ import { after } from "@lib/api/patcher";
import { getMetroCache, registerAssetCacheId } from "@metro/caches";
import { getImportingModuleId, requireModule } from "@metro/modules";
export const all: Record<string, Asset> = {};
export const assetsMap: Record<string, Asset> = new Proxy<any>({}, {
get(target, p) {
if (typeof p !== "string") return undefined;
if (target[p]) return target[p];
const moduleId = getMetroCache().assetsIndex[p];
if (moduleId == null) return undefined;
const assetIndex = requireModule(moduleId);
const assetDefinition = assetsModule.getAssetByID(assetIndex);
assetDefinition.index ??= assetDefinition.id ??= assetIndex;
assetDefinition.moduleId ??= moduleId;
return target[p] = assetDefinition;
},
ownKeys(target) {
const keys = Reflect.ownKeys(getMetroCache().assetsIndex);
for (const key of keys) target[key] = this.get!(target, key, {});
return keys;
},
});
export interface Asset {
name: string;
/** @deprecated */
id: number;
index: number;
name: string;
moduleId: number;
}
@ -26,30 +49,16 @@ export function patchAssets(module: AssetModule) {
if (assetsModule) return;
assetsModule = module;
const unpatch = after("registerAsset", assetsModule, (args: Asset[], id: number) => {
const asset = args[0];
const unpatch = after("registerAsset", assetsModule, ([asset]: Asset[]) => {
const moduleId = getImportingModuleId();
if (moduleId !== -1) registerAssetCacheId(asset.name, moduleId);
all[asset.name] = {
...asset,
id,
moduleId
};
});
for (let id = 1; ; id++) {
const asset = assetsModule.getAssetByID(id);
if (!asset) break;
if (all[asset.name]) continue;
all[asset.name] = { ...asset, id: id };
}
return unpatch;
}
export const find = (filter: (a: any) => void): Asset | null | undefined => Object.values(all).find(filter);
export const getAssetByName = (name: string): Asset => all[name];
export const getAssetByID = (id: number): Asset => assetsModule.getAssetByID(id);
export const getAssetIDByName = (name: string) => all[name]?.id ?? requireModule(getMetroCache().assetsIndex[name]);
export const findAsset = (filter: (a: any) => void): Asset | null | undefined => Object.values(assetsMap).find(filter);
export const requireAssetByName = (name: string): Asset => assetsMap[name];
export const requireAssetByIndex = (id: number): Asset => assetsModule.getAssetByID(id);
export const requireAssetIndex = (name: string) => assetsMap[name]?.index;

View file

@ -1,4 +1,4 @@
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { getLoaderName, getLoaderVersion, isThemeSupported } from "@lib/api/native/loader";
import { BundleUpdaterManager, ClientInfoManager, DeviceManager } from "@lib/api/native/modules";
import { after } from "@lib/api/patcher";
@ -48,13 +48,13 @@ export function connectToDebugger(url: string) {
if (socket !== undefined && socket.readyState !== WebSocket.CLOSED) socket.close();
if (!url) {
showToast("Invalid debugger URL!", getAssetIDByName("Small"));
showToast("Invalid debugger URL!", requireAssetIndex("Small"));
return;
}
socket = new WebSocket(`ws://${url}`);
socket.addEventListener("open", () => showToast("Connected to debugger.", getAssetIDByName("Check")));
socket.addEventListener("open", () => showToast("Connected to debugger.", requireAssetIndex("Check")));
socket.addEventListener("message", (message: any) => {
try {
(0, eval)(message.data);
@ -65,7 +65,7 @@ export function connectToDebugger(url: string) {
socket.addEventListener("error", (err: any) => {
console.log(`Debugger error: ${err.message}`);
showToast("An error occurred with the debugger connection!", getAssetIDByName("Small"));
showToast("An error occurred with the debugger connection!", requireAssetIndex("Small"));
});
}

View file

@ -1,5 +1,5 @@
import { Strings } from "@core/i18n";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { TextInput } from "@ui/components/discord/Redesign";
import ErrorBoundary from "@ui/components/ErrorBoundary";
import { Image, View } from "react-native";
@ -11,7 +11,7 @@ export interface SearchProps {
}
function SearchIcon() {
return <Image style={{ transform: [{ scale: 0.8 }] }} source={getAssetIDByName("search")} />;
return <Image style={{ transform: [{ scale: 0.8 }] }} source={requireAssetIndex("search")} />;
}
export default ({ onChangeText, placeholder, style }: SearchProps) => {

View file

@ -1,4 +1,4 @@
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { FormRow } from "@ui/components/discord/Forms";
import { TableRow } from "@ui/components/discord/Redesign";
import { LayoutAnimation, View } from "react-native";
@ -18,7 +18,7 @@ export default function Summary({ label, icon, noPadding = false, noAnimation =
<>
<TableRow
label={label}
icon={icon && <TableRow.Icon source={getAssetIDByName(icon)} />}
icon={icon && <TableRow.Icon source={requireAssetIndex(icon)} />}
trailing={<FormRow.Arrow style={{ transform: [{ rotate: `${hidden ? 180 : 90}deg` }] }} />}
onPress={() => {
setHidden(!hidden);

View file

@ -1,5 +1,5 @@
import { Strings } from "@core/i18n";
import { getAssetIDByName } from "@lib/api/assets";
import { requireAssetIndex } from "@lib/api/assets";
import { lazyDestructure } from "@lib/utils/lazy";
import { toasts } from "@metro/common";
import { findByProps } from "@metro/utils";
@ -19,6 +19,6 @@ export const showToast = (content: string, asset?: number) => toasts.open({
showToast.showCopyToClipboard = (message = Strings.COPIED_TO_CLIPBOARD) => {
// On Android, only show toast for 12 and lower
if (Platform.OS !== "android" || Platform.Version <= 32) {
showToast(message, getAssetIDByName("toast_copy_link"));
showToast(message, requireAssetIndex("toast_copy_link"));
}
};

View file

@ -1,7 +1,7 @@
import { ClientInfoManager, MMKVManager } from "@lib/api/native/modules";
import { throttle } from "@lib/utils/throttle";
const CACHE_VERSION = 18;
const CACHE_VERSION = 19;
const BUNNY_METRO_CACHE_KEY = `__bunny_metro_cache_key_v${CACHE_VERSION}__`;
export enum ExportsFlags {