Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
2a8496613b
3 changed files with 277 additions and 411 deletions
|
|
@ -4,337 +4,244 @@ import AssetBrowser from "@core/ui/settings/pages/Developer/AssetBrowser";
|
|||
import { useProxy } from "@core/vendetta/storage";
|
||||
import { findAssetId } from "@lib/api/assets";
|
||||
import { connectToDebugger } from "@lib/api/debug";
|
||||
import {
|
||||
getReactDevToolsProp,
|
||||
getReactDevToolsVersion,
|
||||
isLoaderConfigSupported,
|
||||
isReactDevToolsPreloaded,
|
||||
isVendettaLoader,
|
||||
} from "@lib/api/native/loader";
|
||||
import { getReactDevToolsProp, getReactDevToolsVersion, isLoaderConfigSupported, isReactDevToolsPreloaded, isVendettaLoader } from "@lib/api/native/loader";
|
||||
import { loaderConfig, settings } from "@lib/api/settings";
|
||||
import { lazyDestructure } from "@lib/utils/lazy";
|
||||
import { NavigationNative } from "@metro/common";
|
||||
import {
|
||||
Button,
|
||||
LegacyFormText,
|
||||
Stack,
|
||||
TableRow,
|
||||
TableRowGroup,
|
||||
TableSwitchRow,
|
||||
TextInput,
|
||||
} from "@metro/common/components";
|
||||
import { Button, LegacyFormText, Stack, TableRow, TableRowGroup, TableSwitchRow, TextInput } from "@metro/common/components";
|
||||
import { findByProps } from "@metro/wrappers";
|
||||
import { semanticColors } from "@ui/color";
|
||||
import { ErrorBoundary } from "@ui/components";
|
||||
import ErrorBoundaryScreen from "@core/ui/reporter/components/ErrorBoundaryScreen";
|
||||
import { createStyles, TextStyleSheet } from "@ui/styles";
|
||||
import { NativeModules } from "react-native";
|
||||
import { ScrollView, StyleSheet } from "react-native";
|
||||
import { showToast } from "@ui/toasts";
|
||||
|
||||
const { hideActionSheet } = lazyDestructure(() =>
|
||||
findByProps("openLazy", "hideActionSheet"),
|
||||
);
|
||||
const { showSimpleActionSheet } = lazyDestructure(() =>
|
||||
findByProps("showSimpleActionSheet"),
|
||||
);
|
||||
const { openAlert } = lazyDestructure(() =>
|
||||
findByProps("openAlert", "dismissAlert"),
|
||||
);
|
||||
const { AlertModal, AlertActionButton } = lazyDestructure(() =>
|
||||
findByProps("AlertModal", "AlertActions"),
|
||||
);
|
||||
const { hideActionSheet } = lazyDestructure(() => findByProps("openLazy", "hideActionSheet"));
|
||||
const { showSimpleActionSheet } = lazyDestructure(() => findByProps("showSimpleActionSheet"));
|
||||
const { openAlert } = lazyDestructure(() => findByProps("openAlert", "dismissAlert"));
|
||||
const { AlertModal, AlertActionButton } = lazyDestructure(() => findByProps("AlertModal", "AlertActions"));
|
||||
|
||||
const RDT_EMBED_LINK = "https://cdn.bwlok.dev/rdt/devTools.js";
|
||||
|
||||
const useStyles = createStyles({
|
||||
leadingText: {
|
||||
...TextStyleSheet["heading-md/semibold"],
|
||||
color: semanticColors.TEXT_MUTED,
|
||||
marginRight: -4,
|
||||
},
|
||||
inputGroup: {
|
||||
marginTop: 4,
|
||||
borderTopLeftRadius: 16,
|
||||
borderTopRightRadius: 16,
|
||||
overflow: "hidden",
|
||||
},
|
||||
leadingText: {
|
||||
...TextStyleSheet["heading-md/semibold"],
|
||||
color: semanticColors.TEXT_MUTED,
|
||||
marginRight: -4
|
||||
},
|
||||
});
|
||||
|
||||
export default function Developer() {
|
||||
const [rdtFileExists, fs] = useFileExists("preloads/reactDevtools.js");
|
||||
const [rdtFileExists, fs] = useFileExists("preloads/reactDevtools.js");
|
||||
|
||||
const styles = useStyles();
|
||||
const navigation = NavigationNative.useNavigation();
|
||||
const styles = useStyles();
|
||||
const navigation = NavigationNative.useNavigation();
|
||||
|
||||
useProxy(settings);
|
||||
useProxy(loaderConfig);
|
||||
useProxy(settings);
|
||||
useProxy(loaderConfig);
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<ScrollView
|
||||
style={{ flex: 1 }}
|
||||
contentContainerStyle={{ paddingBottom: 38 }}
|
||||
>
|
||||
<Stack
|
||||
style={{ paddingVertical: 24, paddingHorizontal: 12 }}
|
||||
spacing={24}
|
||||
>
|
||||
<TableRowGroup title={Strings.DEBUGGER_URL}>
|
||||
<TextInput
|
||||
placeholder="127.0.0.1:9090"
|
||||
size="md"
|
||||
leadingIcon={() => (
|
||||
<LegacyFormText style={styles.leadingText}>
|
||||
ws://
|
||||
</LegacyFormText>
|
||||
)}
|
||||
defaultValue={settings.debuggerUrl}
|
||||
onChange={(v: string) => (settings.debuggerUrl = v)}
|
||||
/>
|
||||
<Stack style={styles.inputGroup}>
|
||||
<TableRow
|
||||
label={Strings.CONNECT_TO_DEBUG_WEBSOCKET}
|
||||
subLabel="Connect to Chrome DevTools for debugging"
|
||||
icon={<TableRow.Icon source={findAssetId("WrenchIcon")} />}
|
||||
onPress={() => connectToDebugger(settings.debuggerUrl)}
|
||||
/>
|
||||
</Stack>
|
||||
</TableRowGroup>
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 38 }}>
|
||||
<Stack style={{ paddingVertical: 24, paddingHorizontal: 12 }} spacing={24}>
|
||||
|
||||
{isReactDevToolsPreloaded() && (
|
||||
<TableRowGroup title="React Development">
|
||||
<TextInput
|
||||
placeholder="127.0.0.1:8097"
|
||||
size="md"
|
||||
leadingIcon={() => (
|
||||
<LegacyFormText style={styles.leadingText}>
|
||||
ws://
|
||||
</LegacyFormText>
|
||||
)}
|
||||
defaultValue={settings.devToolsUrl}
|
||||
onChange={(v: string) => (settings.devToolsUrl = v)}
|
||||
/>
|
||||
<Stack style={styles.inputGroup}>
|
||||
<TableRow
|
||||
label={Strings.CONNECT_TO_REACT_DEVTOOLS}
|
||||
subLabel="Connect React DevTools for component debugging"
|
||||
icon={
|
||||
<TableRow.Icon source={findAssetId("ic_badge_staff")} />
|
||||
}
|
||||
onPress={async () => {
|
||||
if (!settings.devToolsUrl?.trim()) {
|
||||
showToast("Invalid devTools URL!", findAssetId("Small"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const devTools =
|
||||
window[getReactDevToolsProp() || "__vendetta_rdc"];
|
||||
|
||||
if (!devTools?.connectToDevTools) {
|
||||
showToast(
|
||||
"React DevTools not available",
|
||||
findAssetId("Small"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await devTools.connectToDevTools({
|
||||
host: settings.devToolsUrl.split(":")?.[0],
|
||||
resolveRNStyle: StyleSheet.flatten,
|
||||
});
|
||||
} catch (error) {
|
||||
showToast(
|
||||
"Failed to connect to React DevTools",
|
||||
findAssetId("Small"),
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
{isLoaderConfigSupported() && isVendettaLoader() && (
|
||||
<TableSwitchRow
|
||||
label={Strings.LOAD_REACT_DEVTOOLS}
|
||||
subLabel={`${Strings.VERSION}: ${getReactDevToolsVersion()}`}
|
||||
icon={
|
||||
<TableRow.Icon source={findAssetId("ic_badge_staff")} />
|
||||
}
|
||||
value={loaderConfig.loadReactDevTools}
|
||||
onValueChange={(v: boolean) => {
|
||||
loaderConfig.loadReactDevTools = v;
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</TableRowGroup>
|
||||
)}
|
||||
|
||||
{isLoaderConfigSupported() && (
|
||||
<TableRowGroup title="Loader Configuration">
|
||||
<TableSwitchRow
|
||||
label={Strings.LOAD_FROM_CUSTOM_URL}
|
||||
subLabel={Strings.LOAD_FROM_CUSTOM_URL_DEC}
|
||||
icon={<TableRow.Icon source={findAssetId("LinkIcon")} />}
|
||||
value={loaderConfig.customLoadUrl.enabled}
|
||||
onValueChange={(v: boolean) => {
|
||||
loaderConfig.customLoadUrl.enabled = v;
|
||||
}}
|
||||
/>
|
||||
{loaderConfig.customLoadUrl.enabled && (
|
||||
<TableRow
|
||||
label={
|
||||
<TextInput
|
||||
defaultValue={loaderConfig.customLoadUrl.url}
|
||||
size="md"
|
||||
onChange={(v: string) =>
|
||||
(loaderConfig.customLoadUrl.url = v)
|
||||
}
|
||||
placeholder="http://localhost:4040/shiggycord.js"
|
||||
label={Strings.SHIGGYCORD_URL}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</TableRowGroup>
|
||||
)}
|
||||
|
||||
<TableRowGroup title="Inspection & Testing">
|
||||
<TableRow
|
||||
arrow
|
||||
label={Strings.ASSET_BROWSER}
|
||||
subLabel="Browse and inspect Discord's assets"
|
||||
icon={<TableRow.Icon source={findAssetId("ic_image")} />}
|
||||
trailing={TableRow.Arrow}
|
||||
onPress={() =>
|
||||
navigation.push("SHIGGYCORD_CUSTOM_PAGE", {
|
||||
title: Strings.ASSET_BROWSER,
|
||||
render: AssetBrowser,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<TableRow
|
||||
label={Strings.INSTALL_REACT_DEVTOOLS}
|
||||
subLabel={Strings.RESTART_REQUIRED_TO_TAKE_EFFECT}
|
||||
icon={<TableRow.Icon source={findAssetId("DownloadIcon")} />}
|
||||
trailing={
|
||||
<Button
|
||||
size="sm"
|
||||
loading={rdtFileExists === CheckState.LOADING}
|
||||
disabled={rdtFileExists === CheckState.LOADING}
|
||||
variant={
|
||||
rdtFileExists === CheckState.TRUE ? "secondary" : "primary"
|
||||
}
|
||||
text={
|
||||
rdtFileExists === CheckState.TRUE
|
||||
? Strings.UNINSTALL
|
||||
: Strings.INSTALL
|
||||
}
|
||||
onPress={async () => {
|
||||
if (rdtFileExists === CheckState.FALSE) {
|
||||
fs.downloadFile(
|
||||
RDT_EMBED_LINK,
|
||||
"preloads/reactDevtools.js",
|
||||
);
|
||||
} else if (rdtFileExists === CheckState.TRUE) {
|
||||
fs.removeFile("preloads/reactDevtools.js");
|
||||
}
|
||||
}}
|
||||
icon={findAssetId(
|
||||
rdtFileExists === CheckState.TRUE
|
||||
? "ic_message_delete"
|
||||
: "DownloadIcon",
|
||||
)}
|
||||
style={{ marginLeft: 8 }}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<TableRow
|
||||
arrow
|
||||
label={Strings.ERROR_BOUNDARY_TOOLS_LABEL}
|
||||
subLabel="Test error boundaries and crash handling"
|
||||
icon={<TableRow.Icon source={findAssetId("ic_warning_24px")} />}
|
||||
onPress={() =>
|
||||
showSimpleActionSheet({
|
||||
key: "ErrorBoundaryTools",
|
||||
header: {
|
||||
title: "Which ErrorBoundary do you want to trip?",
|
||||
icon: (
|
||||
<TableRow.Icon
|
||||
style={{ marginRight: 8 }}
|
||||
source={findAssetId("ic_warning_24px")}
|
||||
<TableRowGroup title={Strings.DEBUGGER_URL}>
|
||||
<TextInput
|
||||
placeholder="127.0.0.1:9090"
|
||||
size="md"
|
||||
leadingIcon={() => <LegacyFormText style={styles.leadingText}>ws://</LegacyFormText>}
|
||||
defaultValue={settings.debuggerUrl}
|
||||
onChange={(v: string) => settings.debuggerUrl = v}
|
||||
/>
|
||||
),
|
||||
},
|
||||
options: [
|
||||
{
|
||||
label: Strings.SHIGGYCORD,
|
||||
onPress: () =>
|
||||
navigation.push("SHIGGYCORD_CUSTOM_PAGE", {
|
||||
render: () => (
|
||||
<ErrorBoundaryScreen
|
||||
error={new Error("ShiggyCord test crash")}
|
||||
rerender={() => {}}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: "Discord",
|
||||
isDestructive: true,
|
||||
onPress: () =>
|
||||
navigation.push("SHIGGYCORD_CUSTOM_PAGE", {
|
||||
noErrorBoundary: true,
|
||||
}),
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
/>
|
||||
<TableSwitchRow
|
||||
label={Strings.ENABLE_EVAL_COMMAND}
|
||||
subLabel={Strings.ENABLE_EVAL_COMMAND_DESC}
|
||||
icon={<TableRow.Icon source={findAssetId("PencilIcon")} />}
|
||||
value={!!settings.enableEvalCommand}
|
||||
onValueChange={(v: boolean) => {
|
||||
settings.enableEvalCommand = v;
|
||||
}}
|
||||
/>
|
||||
</TableRowGroup>
|
||||
|
||||
<TableRowGroup title="Dangerous Actions">
|
||||
<TableRow
|
||||
label={Strings.CLEAR_BUNDLE}
|
||||
subLabel="Clear cached bundle and force reload"
|
||||
icon={<TableRow.Icon source={findAssetId("TrashIcon")} />}
|
||||
onPress={() => {
|
||||
openAlert(
|
||||
"shiggycord-clear-bundle-reload-confirmation",
|
||||
<AlertModal
|
||||
title={Strings.MODAL_RELOAD_REQUIRED}
|
||||
content={Strings.MODAL_RELOAD_REQUIRED_DESC}
|
||||
actions={
|
||||
<Stack>
|
||||
<AlertActionButton
|
||||
text={Strings.RELOAD}
|
||||
variant="destructive"
|
||||
onPress={() =>
|
||||
NativeModules.BundleUpdaterManager.reload()
|
||||
}
|
||||
/>
|
||||
<AlertActionButton
|
||||
text={Strings.CANCEL}
|
||||
variant="secondary"
|
||||
<Stack style={{
|
||||
marginTop: 4,
|
||||
borderTopLeftRadius: 16,
|
||||
borderTopRightRadius: 16,
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
<TableSwitchRow
|
||||
label={Strings.AUTO_DEBUGGER}
|
||||
icon={<TableRow.Icon source={findAssetId("copy")} />}
|
||||
value={settings.autoDebugger}
|
||||
onValueChange={(v: boolean) => {
|
||||
settings.autoDebugger = v;
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
}
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
<TableRow
|
||||
label={Strings.CONNECT_TO_DEBUG_WEBSOCKET}
|
||||
icon={<TableRow.Icon source={findAssetId("copy")} />}
|
||||
onPress={() => connectToDebugger(settings.debuggerUrl)}
|
||||
/>
|
||||
|
||||
</TableRowGroup>
|
||||
{isReactDevToolsPreloaded() && <>
|
||||
<TableRowGroup title={Strings.DEVTOOLS_URL}>
|
||||
|
||||
<TextInput
|
||||
placeholder="127.0.0.1:8097"
|
||||
size="md"
|
||||
leadingIcon={() => <LegacyFormText style={styles.leadingText}>ws://</LegacyFormText>}
|
||||
defaultValue={settings.devToolsUrl}
|
||||
onChange={(v: string) => settings.devToolsUrl = v}
|
||||
/>
|
||||
<Stack style={{
|
||||
marginTop: 4,
|
||||
borderTopLeftRadius: 16,
|
||||
borderTopRightRadius: 16,
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
<TableSwitchRow
|
||||
label={Strings.AUTO_DEVTOOLS}
|
||||
icon={<TableRow.Icon source={findAssetId("ic_badge_staff")} />}
|
||||
value={settings.autoDevTools}
|
||||
onValueChange={(v: boolean) => {
|
||||
settings.autoDevTools = v;
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
<TableRow
|
||||
label={Strings.CONNECT_TO_REACT_DEVTOOLS}
|
||||
icon={<TableRow.Icon source={findAssetId("ic_badge_staff")} />}
|
||||
onPress={async () => {
|
||||
if (!settings.devToolsUrl?.trim()) {
|
||||
showToast("Invalid devTools URL!", findAssetId("Small"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const devTools = window[getReactDevToolsProp() || "__vendetta_rdc"];
|
||||
|
||||
if (!devTools?.connectToDevTools) {
|
||||
showToast("Invalid devTools URL!", findAssetId("Small"));
|
||||
return;
|
||||
}
|
||||
|
||||
await devTools.connectToDevTools({
|
||||
host: settings.devToolsUrl.split(":")?.[0],
|
||||
resolveRNStyle: StyleSheet.flatten,
|
||||
});
|
||||
} catch (error) {
|
||||
showToast("Invalid devTools URL!", findAssetId("Small"));
|
||||
}
|
||||
}}
|
||||
|
||||
/>
|
||||
</TableRowGroup>
|
||||
</>}
|
||||
{isLoaderConfigSupported() && <>
|
||||
<TableRowGroup title="Loader config">
|
||||
<TableSwitchRow
|
||||
label={Strings.LOAD_FROM_CUSTOM_URL}
|
||||
subLabel={Strings.LOAD_FROM_CUSTOM_URL_DEC}
|
||||
icon={<TableRow.Icon source={findAssetId("copy")} />}
|
||||
value={loaderConfig.customLoadUrl.enabled}
|
||||
onValueChange={(v: boolean) => {
|
||||
loaderConfig.customLoadUrl.enabled = v;
|
||||
}}
|
||||
/>
|
||||
{loaderConfig.customLoadUrl.enabled && <TableRow label={<TextInput
|
||||
defaultValue={loaderConfig.customLoadUrl.url}
|
||||
size="md"
|
||||
onChange={(v: string) => loaderConfig.customLoadUrl.url = v}
|
||||
placeholder="http://localhost:4040/kettu.js"
|
||||
label={Strings.PUPU_URL}
|
||||
/>} />}
|
||||
{isReactDevToolsPreloaded() && isVendettaLoader() && <TableSwitchRow
|
||||
label={Strings.LOAD_REACT_DEVTOOLS}
|
||||
subLabel={`${Strings.VERSION}: ${getReactDevToolsVersion()}`}
|
||||
icon={<TableRow.Icon source={findAssetId("ic_badge_staff")} />}
|
||||
value={loaderConfig.loadReactDevTools}
|
||||
onValueChange={(v: boolean) => {
|
||||
loaderConfig.loadReactDevTools = v;
|
||||
}}
|
||||
/>}
|
||||
</TableRowGroup>
|
||||
</>}
|
||||
<TableRowGroup title="Other">
|
||||
<TableRow
|
||||
// Thanks for this Revenge team!
|
||||
label={Strings.CLEAR_BUNDLE}
|
||||
|
||||
icon={<TableRow.Icon source={findAssetId("TrashIcon")} />}
|
||||
onPress={() => {
|
||||
openAlert("pupu-clear-bundle-reload-confirmation", <AlertModal
|
||||
title={Strings.MODAL_RELOAD_REQUIRED}
|
||||
content={Strings.MODAL_RELOAD_REQUIRED_DESC}
|
||||
actions={
|
||||
<Stack>
|
||||
<AlertActionButton text={Strings.RELOAD} variant="destructive" onPress={() => NativeModules.BundleUpdaterManager.reload()} />
|
||||
<AlertActionButton text={Strings.CANCEL} variant="secondary" />
|
||||
</Stack>
|
||||
}
|
||||
/>);
|
||||
}}
|
||||
/>
|
||||
<TableRow
|
||||
arrow
|
||||
label={Strings.ASSET_BROWSER}
|
||||
icon={<TableRow.Icon source={findAssetId("ic_image")} />}
|
||||
trailing={TableRow.Arrow}
|
||||
onPress={() => navigation.push("PUPU_CUSTOM_PAGE", {
|
||||
title: Strings.ASSET_BROWSER,
|
||||
render: AssetBrowser,
|
||||
})}
|
||||
/>
|
||||
<TableRow
|
||||
arrow
|
||||
label={Strings.ERROR_BOUNDARY_TOOLS_LABEL}
|
||||
icon={<TableRow.Icon source={findAssetId("ic_warning_24px")} />}
|
||||
onPress={() => showSimpleActionSheet({
|
||||
key: "ErrorBoundaryTools",
|
||||
header: {
|
||||
title: "Which ErrorBoundary do you want to trip?",
|
||||
icon: <TableRow.Icon style={{ marginRight: 8 }} source={findAssetId("ic_warning_24px")} />,
|
||||
onClose: () => hideActionSheet(),
|
||||
},
|
||||
options: [
|
||||
// @ts-expect-error
|
||||
// Of course, to trigger an error, we need to do something incorrectly. The below will do!
|
||||
{ label: Strings.PUPU, onPress: () => navigation.push("PUPU_CUSTOM_PAGE", { render: () => <undefined /> }) },
|
||||
{ label: "Discord", isDestructive: true, onPress: () => navigation.push("PUPU_CUSTOM_PAGE", { noErrorBoundary: true }) },
|
||||
],
|
||||
})}
|
||||
/>
|
||||
<TableRow
|
||||
label={Strings.INSTALL_REACT_DEVTOOLS}
|
||||
subLabel={Strings.RESTART_REQUIRED_TO_TAKE_EFFECT}
|
||||
icon={<TableRow.Icon source={findAssetId("DownloadIcon")} />}
|
||||
trailing={
|
||||
<Button
|
||||
size="sm"
|
||||
loading={rdtFileExists === CheckState.LOADING}
|
||||
disabled={rdtFileExists === CheckState.LOADING}
|
||||
variant={rdtFileExists === CheckState.TRUE ? "secondary" : "primary"}
|
||||
text={rdtFileExists === CheckState.TRUE ? Strings.UNINSTALL : Strings.INSTALL}
|
||||
onPress={async () => {
|
||||
if (rdtFileExists === CheckState.FALSE) {
|
||||
fs.downloadFile(RDT_EMBED_LINK, "preloads/reactDevtools.js");
|
||||
} else if (rdtFileExists === CheckState.TRUE) {
|
||||
fs.removeFile("preloads/reactDevtools.js");
|
||||
}
|
||||
}}
|
||||
icon={findAssetId(rdtFileExists === CheckState.TRUE ? "ic_message_delete" : "DownloadIcon")}
|
||||
style={{ marginLeft: 8 }}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<TableSwitchRow
|
||||
label={Strings.ENABLE_EVAL_COMMAND}
|
||||
subLabel={Strings.ENABLE_EVAL_COMMAND_DESC}
|
||||
icon={<TableRow.Icon source={findAssetId("PencilIcon")} />}
|
||||
value={!!settings.enableEvalCommand}
|
||||
onValueChange={(v: boolean) => {
|
||||
settings.enableEvalCommand = v;
|
||||
}}
|
||||
/>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { getThemeFromLoader, selectTheme, themes } from "@lib/addons/themes";
|
||||
import { findAssetId } from "@lib/api/assets";
|
||||
import { getLoaderName, getLoaderVersion, isThemeSupported } from "@lib/api/native/loader";
|
||||
import { getLoaderName, getLoaderVersion, isThemeSupported, getReactDevToolsProp } from "@lib/api/native/loader";
|
||||
import { BundleUpdaterManager, NativeClientInfoModule, NativeDeviceModule } from "@lib/api/native/modules";
|
||||
import { after } from "@lib/api/patcher";
|
||||
import { settings } from "@lib/api/settings";
|
||||
|
|
@ -8,6 +8,7 @@ import { logger } from "@lib/utils/logger";
|
|||
import { showToast } from "@ui/toasts";
|
||||
import { version } from "bunny-build-info";
|
||||
import { Platform, type PlatformConstants } from "react-native";
|
||||
import { StyleSheet } from "react-native";
|
||||
|
||||
export interface RNConstants extends PlatformConstants {
|
||||
// Android
|
||||
|
|
@ -164,3 +165,37 @@ export function getDebugInfo() {
|
|||
)!
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function initDebugger() {
|
||||
if (settings.autoDebugger) {
|
||||
try {
|
||||
connectToDebugger(settings.debuggerUrl);
|
||||
} catch (e) {
|
||||
logger.error("Failed to connect to Debugger during startup:", e);
|
||||
}
|
||||
}
|
||||
if (settings.autoDevTools) {
|
||||
try {
|
||||
(async () => {
|
||||
const devTools = window[getReactDevToolsProp() || "__vendetta_rdc"];
|
||||
|
||||
if (!devTools?.connectToDevTools) {
|
||||
showToast("Invalid devTools URL!", findAssetId("Small"));
|
||||
return;
|
||||
}
|
||||
|
||||
await devTools.connectToDevTools({
|
||||
host: settings.devToolsUrl.split(":")?.[0],
|
||||
resolveRNStyle: StyleSheet.flatten,
|
||||
});
|
||||
})();
|
||||
} catch (e) {
|
||||
logger.error("Failed to connect to ReactDevTools during startup:", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,111 +1,35 @@
|
|||
import {
|
||||
createFileBackend,
|
||||
createMMKVBackend,
|
||||
createStorage,
|
||||
wrapSync,
|
||||
} from "@core/vendetta/storage";
|
||||
import { createFileBackend, createMMKVBackend, createStorage, wrapSync } from "@core/vendetta/storage";
|
||||
import { getLoaderConfigPath } from "@lib/api/native/loader";
|
||||
|
||||
export interface Settings {
|
||||
debuggerUrl: string;
|
||||
developerSettings: boolean;
|
||||
enableDiscordDeveloperSettings: boolean;
|
||||
safeMode?: {
|
||||
enabled: boolean;
|
||||
currentThemeId?: string;
|
||||
};
|
||||
enableEvalCommand?: boolean;
|
||||
debuggerUrl: string;
|
||||
devToolsUrl: string;
|
||||
autoDebugger: boolean;
|
||||
autoDevTools: boolean;
|
||||
developerSettings: boolean;
|
||||
enableDiscordDeveloperSettings: boolean;
|
||||
safeMode?: {
|
||||
enabled: boolean;
|
||||
currentThemeId?: string;
|
||||
};
|
||||
enableEvalCommand?: boolean;
|
||||
}
|
||||
|
||||
export interface LoaderConfig {
|
||||
customLoadUrl: {
|
||||
enabled: boolean;
|
||||
url: string;
|
||||
};
|
||||
loadReactDevTools: boolean;
|
||||
customLoadUrl: {
|
||||
enabled: boolean;
|
||||
url: string;
|
||||
};
|
||||
loadReactDevTools: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* New: Updater settings persisted in MMKV.
|
||||
* Fields:
|
||||
* - autoUpdateEnabled: whether updates are applied automatically
|
||||
* - checkOnStart: whether to check for updates on app start
|
||||
* - updateChannel: optional update channel (stable/beta/alpha)
|
||||
* - lastChecked: ISO timestamp of last update check
|
||||
*
|
||||
* Plugin-related additions:
|
||||
* - fetchPluginsOnStart: when true, plugins (external repositories) are fetched at startup;
|
||||
* when false, plugin repository fetching is deferred and controlled from the Updater UI.
|
||||
* - repoAutoFetchOverrides: per-repository overrides for auto-fetch behavior
|
||||
* (keyed by repository URL, boolean value overrides fetchPluginsOnStart).
|
||||
*/
|
||||
export interface UpdaterSettings {
|
||||
// Whether updates (bundle-level auto-updates) should be applied automatically
|
||||
autoUpdateEnabled: boolean;
|
||||
// Whether to perform an update check on app start
|
||||
checkOnStart: boolean;
|
||||
// Optional channel preference for updates
|
||||
updateChannel?: "stable" | "beta" | "alpha";
|
||||
// ISO timestamp of the last time the updater checked (plugins + bundle)
|
||||
lastChecked?: string | null;
|
||||
export const settings = wrapSync(createStorage<Settings>(createMMKVBackend("VENDETTA_SETTINGS")));
|
||||
|
||||
// -------------------------
|
||||
// Plugin-related settings
|
||||
// -------------------------
|
||||
// Whether external plugin repositories should be fetched at startup
|
||||
fetchPluginsOnStart?: boolean;
|
||||
// Per-repo override for auto-fetch behavior (repoUrl => boolean)
|
||||
repoAutoFetchOverrides?: Record<string, boolean>;
|
||||
|
||||
// -------------------------
|
||||
// Bundle update settings
|
||||
// -------------------------
|
||||
// How often (in hours) to check the project's releases for bundle updates.
|
||||
// Default should be treated as 3 if unset.
|
||||
bundleCheckIntervalHours?: number;
|
||||
// Releases URL (used for checking the bundle). Defaults to:
|
||||
// https://github.com/kmmiio99o/ShiggyCord/releases/
|
||||
bundleReleasesUrl?: string;
|
||||
// Whether to ignore prerelease releases when checking bundle updates.
|
||||
// Defaults to true.
|
||||
bundleIgnorePrereleases?: boolean;
|
||||
// ISO timestamp of the last bundle check
|
||||
lastBundleChecked?: string | null;
|
||||
// Last known bundle version discovered by the updater (if any)
|
||||
lastBundleVersion?: string | null;
|
||||
|
||||
// Latest discovered bundle tag (extracted from custom URL content or GitHub).
|
||||
// This represents the most recent tag/identifier the updater detected.
|
||||
bundleLatestTag?: string | null;
|
||||
// The URL used to determine the latest bundle (download URL or release page).
|
||||
bundleLatestUrl?: string | null;
|
||||
// Whether a newer bundle than the installed one is available.
|
||||
bundleAvailable?: boolean;
|
||||
}
|
||||
|
||||
export const settings = wrapSync(
|
||||
createStorage<Settings>(createMMKVBackend("VENDETTA_SETTINGS")),
|
||||
);
|
||||
|
||||
export const loaderConfig = wrapSync(
|
||||
createStorage<LoaderConfig>(
|
||||
export const loaderConfig = wrapSync(createStorage<LoaderConfig>(
|
||||
createFileBackend(getLoaderConfigPath(), {
|
||||
customLoadUrl: {
|
||||
enabled: false,
|
||||
url: "http://localhost:4040/shiggycord.js",
|
||||
},
|
||||
loadReactDevTools: false,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Updater settings storage.
|
||||
* Stored under MMKV key: VENDETTA_UPDATER_SETTINGS
|
||||
* Defaults should be handled by UI code when reading values if necessary.
|
||||
*/
|
||||
export const updaterSettings = wrapSync(
|
||||
createStorage<UpdaterSettings>(
|
||||
createMMKVBackend("VENDETTA_UPDATER_SETTINGS"),
|
||||
),
|
||||
);
|
||||
customLoadUrl: {
|
||||
enabled: false,
|
||||
url: "http://localhost:4040/kettu.js"
|
||||
}
|
||||
})
|
||||
));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue