feat(plugins/settings): new api, remove ErrorBoundary trigger, add eval JS
This commit is contained in:
parent
9959b5be6c
commit
0cc3e215eb
16 changed files with 157 additions and 55 deletions
|
|
@ -15,7 +15,9 @@ export const MobileSetting = {
|
|||
HERMES_VERSION: 'HERMES_VERSION',
|
||||
|
||||
CALL_GARBAGE_COLLECTOR: 'CALL_GARBAGE_COLLECTOR',
|
||||
TRIGGER_ERROR_BOUNDARY: 'TRIGGER_ERROR_BOUNDARY',
|
||||
EVALUATE_JAVASCRIPT: 'EVALUATE_JAVASCRIPT',
|
||||
EVALUATE_JAVASCRIPT_INSPECT_DEPTH: 'EVALUATE_JAVASCRIPT_INSPECT_DEPTH',
|
||||
EVALUATE_JAVASCRIPT_AWAIT_RESULT: 'EVALUATE_JAVASCRIPT_AWAIT_RESULT',
|
||||
|
||||
REVENGE_NOT_IMPLEMENTED: 'REVENGE_NOT_IMPLEMENTED',
|
||||
} as const
|
||||
|
|
@ -26,7 +28,6 @@ export const UserSettingsSections = {
|
|||
[MobileSetting.REVENGE_THEMES]: 'Revenge Themes',
|
||||
[MobileSetting.REVENGE_FONTS]: 'Revenge Fonts',
|
||||
[MobileSetting.REVENGE_DEVELOPER]: 'Revenge Developer',
|
||||
[MobileSetting.TRIGGER_ERROR_BOUNDARY]: 'Trigger Error Boundary',
|
||||
} as const
|
||||
|
||||
export const AlwaysHidden = () => false
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import { React } from '@revenge-mod/react'
|
|||
|
||||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const CallGarbageCollectorSetting: SettingsRowConfig = {
|
||||
const CallGarbageCollectorSetting: SettingsItem = {
|
||||
parent: null,
|
||||
IconComponent: () => <AssetIcon name="FireIcon" />,
|
||||
title: () => 'Call Garbage Collector',
|
||||
|
|
|
|||
121
src/plugins/settings/definitions/EvaluateJavaScriptSetting.tsx
Normal file
121
src/plugins/settings/definitions/EvaluateJavaScriptSetting.tsx
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
import { React } from '@revenge-mod/react'
|
||||
|
||||
import { AlertActionCreators } from '@revenge-mod/discord/actions'
|
||||
import { nodeUtils } from '@revenge-mod/discord/polyfills'
|
||||
import { Components } from '@revenge-mod/discord/ui'
|
||||
|
||||
import { getErrorStack } from '@revenge-mod/utils/errors'
|
||||
|
||||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const ALERT_KEY = 'evaluate-javascript'
|
||||
|
||||
const EvaluateJavaScriptSetting: SettingsItem = {
|
||||
parent: null,
|
||||
IconComponent: () => <AssetIcon name="FileIcon" />,
|
||||
title: () => 'Evaluate JavaScript',
|
||||
useDescription: () => 'Runs a JavaScript code snippet.',
|
||||
onPress: () => AlertActionCreators.openAlert(ALERT_KEY, <EvaluateJavaScriptAlert />),
|
||||
type: 'pressable',
|
||||
}
|
||||
|
||||
const {
|
||||
AlertActionButton,
|
||||
AlertModal,
|
||||
Button,
|
||||
Slider,
|
||||
Stack,
|
||||
TableRow,
|
||||
TableRowGroup,
|
||||
TableSwitchRow,
|
||||
Text,
|
||||
TextArea,
|
||||
} = Components
|
||||
|
||||
function EvaluateJavaScriptAlert() {
|
||||
const code = React.useRef('')
|
||||
const [awaitResult, setAwaitResult] = React.useState(true)
|
||||
const [showHidden, setShowHidden] = React.useState(true)
|
||||
const [inspectDepth, setInspectDepth] = React.useState(3)
|
||||
const [loading, setLoading] = React.useState(false)
|
||||
|
||||
return (
|
||||
<AlertModal
|
||||
title="Evaluate JavaScript"
|
||||
extraContent={
|
||||
<Stack>
|
||||
<TextArea
|
||||
autoFocus
|
||||
label="Code"
|
||||
size="md"
|
||||
placeholder="ReactNative.NativeModules.BundleUpdaterManager.reload()"
|
||||
onChange={v => (code.current = v)}
|
||||
/>
|
||||
<TableRowGroup>
|
||||
<TableSwitchRow
|
||||
label="Await result"
|
||||
subLabel="Wait for the result of the code before displaying it."
|
||||
value={awaitResult}
|
||||
onValueChange={setAwaitResult}
|
||||
/>
|
||||
<TableSwitchRow
|
||||
label="Show hidden"
|
||||
subLabel="Show hidden properties of the object."
|
||||
value={showHidden}
|
||||
onValueChange={setShowHidden}
|
||||
/>
|
||||
<TableRow
|
||||
label="Inspect depth"
|
||||
subLabel="The depth of the object to inspect."
|
||||
trailing={<Text>{inspectDepth}</Text>}
|
||||
/>
|
||||
<Slider
|
||||
startIcon={<Text>1</Text>}
|
||||
endIcon={<Text>10</Text>}
|
||||
step={1}
|
||||
minimumValue={1}
|
||||
maximumValue={10}
|
||||
value={inspectDepth}
|
||||
onValueChange={setInspectDepth}
|
||||
/>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
}
|
||||
actions={
|
||||
<Stack>
|
||||
<Button
|
||||
text="Evaluate"
|
||||
variant="primary"
|
||||
loading={loading}
|
||||
// Async arrow functions are not supported
|
||||
onPress={async function onPress() {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
// Do a no-local-scope-access eval
|
||||
// biome-ignore lint/security/noGlobalEval: This is intentional
|
||||
const res = globalThis.eval?.(code.current)
|
||||
alert(
|
||||
nodeUtils.inspect(awaitResult && res instanceof Promise ? await res : res, {
|
||||
depth: inspectDepth,
|
||||
showHidden,
|
||||
}),
|
||||
)
|
||||
} catch (e) {
|
||||
alert(getErrorStack(e))
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
AlertActionCreators.dismissAlert(ALERT_KEY)
|
||||
}}
|
||||
/>
|
||||
<AlertActionButton text="Cancel" variant="secondary" />
|
||||
</Stack>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default EvaluateJavaScriptSetting
|
||||
|
|
@ -3,12 +3,12 @@ import { React } from '@revenge-mod/react'
|
|||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
import { MobileSetting } from '../SettingsConstants'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
// @ts-expect-error
|
||||
const props = HermesInternal.getRuntimeProperties()
|
||||
|
||||
const HermesVersionSetting: SettingsRowConfig = {
|
||||
const HermesVersionSetting: SettingsItem = {
|
||||
parent: MobileSetting.REVENGE,
|
||||
IconComponent: () => <AssetIcon name="TranscriptOutlineIcon" />,
|
||||
title: () => 'Hermes',
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ import { React, ReactNative } from '@revenge-mod/react'
|
|||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
import { MobileSetting } from '../SettingsConstants'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const { major, minor, patch, prerelease } = ReactNative.Platform.constants.reactNativeVersion
|
||||
const version = `${major}.${minor}.${patch}${prerelease ? `-${prerelease}` : ''}`
|
||||
|
||||
const ReactNativeVersionSetting: SettingsRowConfig = {
|
||||
const ReactNativeVersionSetting: SettingsItem = {
|
||||
parent: MobileSetting.REVENGE,
|
||||
IconComponent: () => <AssetIcon name="ScienceIcon" />,
|
||||
title: () => 'React Native',
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import { React } from '@revenge-mod/react'
|
|||
|
||||
import { MobileSetting } from '../SettingsConstants'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const ReactVersionSetting: SettingsRowConfig = {
|
||||
const ReactVersionSetting: SettingsItem = {
|
||||
parent: MobileSetting.REVENGE,
|
||||
IconComponent: () => <Components.TableRow.Icon source={getAssetByName('ScienceIcon')!.id} />,
|
||||
title: () => 'React',
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { MobileSetting, UserSettingsSections } from '../SettingsConstants'
|
||||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const RevengeDeveloperSetting: SettingsRowConfig = {
|
||||
const RevengeDeveloperSetting: SettingsItem = {
|
||||
parent: null,
|
||||
type: 'route',
|
||||
IconComponent: () => <AssetIcon name="WrenchIcon" />,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { AlwaysHidden, MobileSetting, UserSettingsSections } from '../SettingsConstants'
|
||||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const RevengeFontsSetting: SettingsRowConfig = {
|
||||
const RevengeFontsSetting: SettingsItem = {
|
||||
parent: null,
|
||||
type: 'route',
|
||||
IconComponent: () => <AssetIcon name="TextIcon" />,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import { React } from '@revenge-mod/react'
|
|||
|
||||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const RevengeNotImplementedSetting: SettingsRowConfig = {
|
||||
const RevengeNotImplementedSetting: SettingsItem = {
|
||||
parent: null,
|
||||
IconComponent: () => <AssetIcon name="CircleXIcon-primary" variant="danger" />,
|
||||
title: () => 'Not Implemented',
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ import { getEnabledPluginsCount } from '@revenge-mod/plugins/_'
|
|||
import { AlwaysHidden, MobileSetting, UserSettingsSections } from '../SettingsConstants'
|
||||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const RevengePluginsSetting: SettingsRowConfig = {
|
||||
const RevengePluginsSetting: SettingsItem = {
|
||||
parent: null,
|
||||
type: 'route',
|
||||
IconComponent: () => <AssetIcon name="PuzzlePieceIcon" />,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import RevengeIcon from '../components/icons/RevengeIcon'
|
||||
import { MobileSetting, UserSettingsSections } from '../SettingsConstants'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const RevengeSetting: SettingsRowConfig = {
|
||||
const RevengeSetting: SettingsItem = {
|
||||
parent: null,
|
||||
type: 'route',
|
||||
IconComponent: RevengeIcon,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { AlwaysHidden, MobileSetting, UserSettingsSections } from '../SettingsConstants'
|
||||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const RevengeThemesSetting: SettingsRowConfig = {
|
||||
const RevengeThemesSetting: SettingsItem = {
|
||||
parent: null,
|
||||
type: 'route',
|
||||
IconComponent: () => <AssetIcon name="PaintPaletteIcon" />,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import RevengeIcon from '../components/icons/RevengeIcon'
|
||||
import { MobileSetting } from '../SettingsConstants'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const RevengeVersionSetting: SettingsRowConfig = {
|
||||
const RevengeVersionSetting: SettingsItem = {
|
||||
parent: MobileSetting.REVENGE,
|
||||
IconComponent: RevengeIcon,
|
||||
title: () => 'Revenge',
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
import { React } from '@revenge-mod/react'
|
||||
|
||||
import AssetIcon from '../components/icons/AssetIcon'
|
||||
import { MobileSetting, UserSettingsSections } from '../SettingsConstants'
|
||||
|
||||
import type { SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
|
||||
const TriggerErrorBoundarySetting: SettingsRowConfig = {
|
||||
parent: MobileSetting.REVENGE_DEVELOPER,
|
||||
IconComponent: () => <AssetIcon name="ScreenXIcon" variant="danger" />,
|
||||
title: () => 'Trigger Error Boundary',
|
||||
variant: 'danger',
|
||||
useDescription: () => 'This will crash the app.',
|
||||
type: 'route',
|
||||
screen: {
|
||||
route: UserSettingsSections[MobileSetting.TRIGGER_ERROR_BOUNDARY],
|
||||
getComponent: () => require('../screens/TriggerErrorBoundarySettingScreen').default,
|
||||
},
|
||||
}
|
||||
|
||||
export default TriggerErrorBoundarySetting
|
||||
|
|
@ -4,7 +4,7 @@ import { InternalPluginFlags, registerPlugin } from '@revenge-mod/plugins/_'
|
|||
import { waitForModules } from '@revenge-mod/modules/finders'
|
||||
import { byName, byProps } from '@revenge-mod/modules/finders/filters'
|
||||
|
||||
import { registerSetting, registerSettingsSection, type SettingsRowConfig } from '@revenge-mod/discord/ui/settings'
|
||||
import { registerSettingsItem, registerSettingsSection, type SettingsItem } from '@revenge-mod/discord/ui/settings'
|
||||
import { _suiData } from '@revenge-mod/discord/_/ui/settings'
|
||||
|
||||
import { after } from '@revenge-mod/patcher'
|
||||
|
|
@ -21,8 +21,8 @@ import ReactNativeVersionSetting from './definitions/ReactNativeVersionSetting'
|
|||
import RevengeVersionSetting from './definitions/RevengeVersionSetting'
|
||||
import HermesVersionSetting from './definitions/HermesVersionSetting'
|
||||
import CallGarbageCollectorSetting from './definitions/CallGarbageCollectorSetting'
|
||||
import TriggerErrorBoundarySetting from './definitions/TriggerErrorBoundarySetting'
|
||||
import RevengeNotImplementedSetting from './definitions/RevengeNotImplementedSetting'
|
||||
import EvaluateJavaScriptSetting from './definitions/EvaluateJavaScriptSetting'
|
||||
|
||||
import type { FC } from 'react'
|
||||
|
||||
|
|
@ -47,10 +47,10 @@ registerPlugin(
|
|||
[MobileSetting.REACT_NATIVE_VERSION, ReactNativeVersionSetting],
|
||||
[MobileSetting.HERMES_VERSION, HermesVersionSetting],
|
||||
[MobileSetting.CALL_GARBAGE_COLLECTOR, CallGarbageCollectorSetting],
|
||||
[MobileSetting.TRIGGER_ERROR_BOUNDARY, TriggerErrorBoundarySetting],
|
||||
[MobileSetting.EVALUATE_JAVASCRIPT, EvaluateJavaScriptSetting],
|
||||
[MobileSetting.REVENGE_NOT_IMPLEMENTED, RevengeNotImplementedSetting],
|
||||
] as Array<[string, SettingsRowConfig]>)
|
||||
registerSetting(key, setting)
|
||||
] as Array<[string, SettingsItem]>)
|
||||
registerSettingsItem(key, setting)
|
||||
|
||||
registerSettingsSection('REVENGE', {
|
||||
label: 'Revenge',
|
||||
|
|
@ -67,7 +67,7 @@ registerPlugin(
|
|||
unsubForRendererConfig()
|
||||
|
||||
const SettingRendererConfig = exports as {
|
||||
SETTING_RENDERER_CONFIG: Record<string, SettingsRowConfig>
|
||||
SETTING_RENDERER_CONFIG: Record<string, SettingsItem>
|
||||
}
|
||||
|
||||
let ORIGINAL_RENDERER_CONFIG = SettingRendererConfig.SETTING_RENDERER_CONFIG
|
||||
|
|
@ -77,7 +77,7 @@ registerPlugin(
|
|||
({
|
||||
...ORIGINAL_RENDERER_CONFIG,
|
||||
..._suiData.config,
|
||||
}) as Record<string, SettingsRowConfig>,
|
||||
}) as Record<string, SettingsItem>,
|
||||
set: v => (ORIGINAL_RENDERER_CONFIG = v),
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@ export default function RevengeDeveloperSettingScreen() {
|
|||
<SettingListRenderer.SettingsList
|
||||
sections={[
|
||||
{
|
||||
settings: [MobileSetting.CALL_GARBAGE_COLLECTOR],
|
||||
label: 'React DevTools',
|
||||
settings: [MobileSetting.REVENGE_NOT_IMPLEMENTED],
|
||||
},
|
||||
{
|
||||
label: 'Tests',
|
||||
settings: [MobileSetting.TRIGGER_ERROR_BOUNDARY],
|
||||
label: 'Tools',
|
||||
settings: [MobileSetting.EVALUATE_JAVASCRIPT, MobileSetting.CALL_GARBAGE_COLLECTOR],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue