diff --git a/bun.lock b/bun.lock
index 72d8526..14ccc22 100644
--- a/bun.lock
+++ b/bun.lock
@@ -29,6 +29,9 @@
"lib/assets": {
"name": "@revenge-mod/assets",
},
+ "lib/components": {
+ "name": "@revenge-mod/components",
+ },
"lib/discord": {
"name": "@revenge-mod/discord",
},
@@ -437,6 +440,8 @@
"@revenge-mod/assets": ["@revenge-mod/assets@workspace:lib/assets"],
+ "@revenge-mod/components": ["@revenge-mod/components@workspace:lib/components"],
+
"@revenge-mod/discord": ["@revenge-mod/discord@workspace:lib/discord"],
"@revenge-mod/externals": ["@revenge-mod/externals@workspace:lib/externals"],
diff --git a/lib/assets/src/index.ts b/lib/assets/src/index.ts
index 846d2a4..6ee41ad 100644
--- a/lib/assets/src/index.ts
+++ b/lib/assets/src/index.ts
@@ -1,4 +1,4 @@
-import { ReactNative } from '@revenge-mod/react'
+import { Platform } from 'react-native'
import { _customs, _overrides } from './_internal'
import { cache } from './caches'
import { AssetsRegistry } from './preinit'
@@ -16,8 +16,7 @@ export {
} from './preinit'
// iOS cannot display SVGs
-let _preferredType: Asset['type'] =
- ReactNative.Platform.OS === 'ios' ? 'png' : 'svg'
+let _preferredType: Asset['type'] = Platform.OS === 'ios' ? 'png' : 'svg'
/**
* Set the preferred asset type. This is used to determine which asset to use when multiple types are available.
diff --git a/lib/components/package.json b/lib/components/package.json
new file mode 100644
index 0000000..e71d27a
--- /dev/null
+++ b/lib/components/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "@revenge-mod/components",
+ "private": true,
+ "type": "module",
+ "exports": {
+ "./FormSwitch": {
+ "default": "./src/FormSwitch.tsx"
+ },
+ "./Page": {
+ "default": "./src/Page.tsx"
+ },
+ "./SearchInput": {
+ "default": "./src/SearchInput.tsx"
+ },
+ "./TableRowAssetIcon": {
+ "default": "./src/TableRowAssetIcon.tsx"
+ },
+ "./init": {
+ "default": "./src/init.ts"
+ },
+ "./types": {
+ "types": "./src/types.ts"
+ }
+ }
+}
diff --git a/src/components/FormSwitch.tsx b/lib/components/src/FormSwitch.tsx
similarity index 67%
rename from src/components/FormSwitch.tsx
rename to lib/components/src/FormSwitch.tsx
index 2faa857..85e1f8c 100644
--- a/src/components/FormSwitch.tsx
+++ b/lib/components/src/FormSwitch.tsx
@@ -1,5 +1,5 @@
import { FormSwitch as Switch } from '@revenge-mod/discord/design'
-import { ReactNative } from '@revenge-mod/react'
+import { StyleSheet, View } from 'react-native'
import type { DiscordModules } from '@revenge-mod/discord/types'
/**
@@ -9,13 +9,13 @@ export default function FormSwitch(
props: DiscordModules.Components.FormSwitchProps,
) {
return (
-
+
-
+
)
}
-const styles = ReactNative.StyleSheet.create({
+const styles = StyleSheet.create({
disabled: {
opacity: 0.5,
},
diff --git a/src/components/Page.tsx b/lib/components/src/Page.tsx
similarity index 81%
rename from src/components/Page.tsx
rename to lib/components/src/Page.tsx
index d417289..1678900 100644
--- a/src/components/Page.tsx
+++ b/lib/components/src/Page.tsx
@@ -1,5 +1,5 @@
import { Design } from '@revenge-mod/discord/design'
-import { ReactNative } from '@revenge-mod/react'
+import { StyleSheet } from 'react-native'
import type { DiscordModules } from '@revenge-mod/discord/types'
export default function Page(props: DiscordModules.Components.StackProps) {
@@ -10,7 +10,7 @@ export default function Page(props: DiscordModules.Components.StackProps) {
)
}
-const styles = ReactNative.StyleSheet.create({
+const styles = StyleSheet.create({
page: {
flex: 1,
paddingHorizontal: 16,
diff --git a/src/components/SearchInput.tsx b/lib/components/src/SearchInput.tsx
similarity index 100%
rename from src/components/SearchInput.tsx
rename to lib/components/src/SearchInput.tsx
diff --git a/src/components/TableRowAssetIcon.tsx b/lib/components/src/TableRowAssetIcon.tsx
similarity index 100%
rename from src/components/TableRowAssetIcon.tsx
rename to lib/components/src/TableRowAssetIcon.tsx
diff --git a/lib/components/src/index.ts b/lib/components/src/index.ts
new file mode 100644
index 0000000..cd31643
--- /dev/null
+++ b/lib/components/src/index.ts
@@ -0,0 +1,4 @@
+export { default as FormSwitch } from './FormSwitch'
+export { default as Page } from './Page'
+export { default as SearchInput } from './SearchInput'
+export { default as TableRowAssetIcon } from './TableRowAssetIcon'
diff --git a/lib/components/src/init.ts b/lib/components/src/init.ts
new file mode 100644
index 0000000..bee7837
--- /dev/null
+++ b/lib/components/src/init.ts
@@ -0,0 +1,11 @@
+/** biome-ignore-all lint/complexity/useArrowFunction: Rolldown issue: Bug requires us to use normal functions instead of arrow functions */
+
+import { _uapi } from '@revenge-mod/plugins/_'
+import { defineLazyProperty } from '@revenge-mod/utils/objects'
+import type { UnscopedInitPluginApi } from '@revenge-mod/plugins/types'
+
+const uapi = _uapi as UnscopedInitPluginApi
+
+defineLazyProperty(uapi, 'components', function () {
+ return require('./index')
+})
diff --git a/lib/components/src/types.ts b/lib/components/src/types.ts
new file mode 100644
index 0000000..dbde261
--- /dev/null
+++ b/lib/components/src/types.ts
@@ -0,0 +1,12 @@
+export interface PluginApiComponents {
+ FormSwitch: typeof import('@revenge-mod/components/FormSwitch').default
+ Page: typeof import('@revenge-mod/components/Page').default
+ SearchInput: typeof import('@revenge-mod/components/SearchInput').default
+ TableRowAssetIcon: typeof import('@revenge-mod/components/TableRowAssetIcon').default
+}
+
+declare module '@revenge-mod/plugins/types' {
+ export interface UnscopedInitPluginApi {
+ components: PluginApiComponents
+ }
+}
diff --git a/lib/storage/src/index.ts b/lib/storage/src/index.ts
index bc5e59a..6c9b307 100644
--- a/lib/storage/src/index.ts
+++ b/lib/storage/src/index.ts
@@ -1,6 +1,7 @@
// TODO(storage): Implement using NativeModules interop instead
import { FileModule } from '@revenge-mod/discord/native'
+// This file is usually imported way too early, so we can't import our shim
import { React } from '@revenge-mod/react'
import { mergeDeep } from '@revenge-mod/utils/objects'
import { useReRender } from '@revenge-mod/utils/react'
diff --git a/lib/utils/src/react.ts b/lib/utils/src/react.ts
index 5951fc8..4cc1b59 100644
--- a/lib/utils/src/react.ts
+++ b/lib/utils/src/react.ts
@@ -1,3 +1,4 @@
+// @revenge-mod/storage depends on this file, and it is imported way too early, so we can't import our shim
import { React } from '@revenge-mod/react'
import { findInTree } from './trees'
import type { ReactNode } from 'react'
diff --git a/scripts/build.ts b/scripts/build.ts
index f732ebf..44c4c26 100644
--- a/scripts/build.ts
+++ b/scripts/build.ts
@@ -61,10 +61,21 @@ export default async function build(dev = false, log = true) {
find: 'react/jsx-runtime',
replacement: `${ShimsDir}/react~jsx-runtime.ts`,
},
+ // Do not move React to the top!
+ // If you do that, react/jsx-runtime would resolve to ${ShimsDir}/react.ts/jsx-runtime instead.
+ {
+ find: 'react',
+ replacement: `${ShimsDir}/react.ts`,
+ },
+ {
+ find: 'react-native',
+ replacement: `${ShimsDir}/react-native.ts`,
+ },
],
}),
importGlobPlugin(),
swcPlugin(),
+ sourceURLPlugin(),
hermesCPlugin({
flags: [
dev ? '-Og' : '-O',
@@ -102,7 +113,6 @@ export default async function build(dev = false, log = true) {
minify: {},
file: 'dist/revenge.js',
format: 'iife',
- footer: '//# sourceURL=Revenge',
})
if (log)
@@ -113,6 +123,18 @@ export default async function build(dev = false, log = true) {
)
}
+function sourceURLPlugin() {
+ return {
+ name: 'footer',
+ renderChunk(code) {
+ return {
+ code: `${code}\n//# sourceURL=Revenge`,
+ map: null,
+ }
+ },
+ } satisfies RolldownPlugin
+}
+
function swcPlugin() {
return {
name: 'swc',
diff --git a/shims/react-native.ts b/shims/react-native.ts
new file mode 100644
index 0000000..e0d31df
--- /dev/null
+++ b/shims/react-native.ts
@@ -0,0 +1,3 @@
+import { ReactNative } from '@revenge-mod/react'
+
+module.exports = ReactNative
diff --git a/shims/react.ts b/shims/react.ts
new file mode 100644
index 0000000..5f263ed
--- /dev/null
+++ b/shims/react.ts
@@ -0,0 +1,3 @@
+import { React } from '@revenge-mod/react'
+
+module.exports = React
diff --git a/shims/react~jsx-runtime.ts b/shims/react~jsx-runtime.ts
index 555ed21..b807092 100644
--- a/shims/react~jsx-runtime.ts
+++ b/shims/react~jsx-runtime.ts
@@ -19,4 +19,4 @@ const jsxs = ((type, ...args) =>
...args,
)) as typeof _jsxs
-export { jsx, jsxs, Fragment }
+module.exports = { jsx, jsxs, Fragment }
diff --git a/src/index.ts b/src/index.ts
index 0d3ce82..20e45d7 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -37,6 +37,7 @@ onModuleFirstRequired(IndexModuleId, function onIndexRequired() {
// Initialize init libraries
require('@revenge-mod/externals/init')
require('@revenge-mod/discord/init')
+ require('@revenge-mod/components/init')
// Run all init plugins
require('~/plugins/init')
diff --git a/src/plugins/init/developer-settings/definitions/AssetBrowserSetting.tsx b/src/plugins/init/developer-settings/definitions/AssetBrowserSetting.tsx
index 7b3d130..760893d 100644
--- a/src/plugins/init/developer-settings/definitions/AssetBrowserSetting.tsx
+++ b/src/plugins/init/developer-settings/definitions/AssetBrowserSetting.tsx
@@ -1,4 +1,4 @@
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import { MobileSetting, UserSettingsSections } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
diff --git a/src/plugins/init/developer-settings/definitions/EvaluateJavaScriptSetting.tsx b/src/plugins/init/developer-settings/definitions/EvaluateJavaScriptSetting.tsx
index 95b6546..e0b5c05 100644
--- a/src/plugins/init/developer-settings/definitions/EvaluateJavaScriptSetting.tsx
+++ b/src/plugins/init/developer-settings/definitions/EvaluateJavaScriptSetting.tsx
@@ -1,9 +1,9 @@
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import { AlertActionCreators } from '@revenge-mod/discord/actions'
import { Design } from '@revenge-mod/discord/design'
import { nodeUtil } from '@revenge-mod/externals/browserify'
-import { React } from '@revenge-mod/react'
import { getErrorStack } from '@revenge-mod/utils/errors'
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import { useRef, useState } from 'react'
import { api } from '..'
import { MobileSetting } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
@@ -34,11 +34,11 @@ const {
} = Design
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)
+ const code = useRef('')
+ const [awaitResult, setAwaitResult] = useState(true)
+ const [showHidden, setShowHidden] = useState(true)
+ const [inspectDepth, setInspectDepth] = useState(3)
+ const [loading, setLoading] = useState(false)
return (
{
+ useEffect(() => {
const sub: Subscription = e => (e === 1 || e === 2) && rerender()
subscriptions.add(sub)
return () => {
subscriptions.delete(sub)
}
- }, [])
+ }, [rerender])
return DevToolsContext.open
}
diff --git a/src/plugins/init/developer-settings/screens/AssetBrowserSettingScreen.tsx b/src/plugins/init/developer-settings/screens/AssetBrowserSettingScreen.tsx
index 24113eb..e0eddf0 100644
--- a/src/plugins/init/developer-settings/screens/AssetBrowserSettingScreen.tsx
+++ b/src/plugins/init/developer-settings/screens/AssetBrowserSettingScreen.tsx
@@ -1,4 +1,7 @@
import { getAssets } from '@revenge-mod/assets'
+import Page from '@revenge-mod/components/Page'
+import SearchInput from '@revenge-mod/components/SearchInput'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import {
AlertActionCreators,
ToastActionCreators,
@@ -6,15 +9,13 @@ import {
import { Design } from '@revenge-mod/discord/design'
import { Clipboard } from '@revenge-mod/externals/react-native-clipboard'
import { FlashList } from '@revenge-mod/externals/shopify'
-import { React, ReactNative } from '@revenge-mod/react'
+import { debounce } from '@revenge-mod/utils/callbacks'
import { lookupGeneratedIconComponent } from '@revenge-mod/utils/discord'
-import Page from '~/components/Page'
-import SearchInput from '~/components/SearchInput'
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import { useCallback, useMemo, useState } from 'react'
+import { Image, StyleSheet } from 'react-native'
import type { Asset, AssetId } from '@revenge-mod/assets/types'
import type { Metro } from '@revenge-mod/modules/types'
-const { Image, StyleSheet } = ReactNative
const { AlertModal, AlertActionButton, TableRow, TableRowGroup, Text } = Design
const Displayable = new Set(['png', 'jpg', 'svg', 'webp'])
@@ -27,10 +28,11 @@ const UndisplayableFallback = {
}
export default function AssetBrowserSettingScreen() {
- const [search, setSearch] = React.useState('')
- const assets = React.useMemo(() => [...getAssets()], [getAssets])
+ const [search, setSearch] = useState('')
+ const debouncedSetSearch = useCallback(debounce(setSearch, 100), [])
+ const assets = useMemo(() => [...getAssets()], [])
- const filteredAssets = React.useMemo(
+ const filteredAssets = useMemo(
() =>
!search.length
? assets
@@ -42,7 +44,10 @@ export default function AssetBrowserSettingScreen() {
return (
- setSearch(v)} size="md" />
+ debouncedSetSearch(v)}
+ size="md"
+ />
s.devtools?.address)
return (
-
+
(DevToolsContext.address = text)}
returnKeyType="done"
/>
-
+
)
}
diff --git a/src/plugins/init/settings/definitions/HermesVersionSetting.tsx b/src/plugins/init/settings/definitions/HermesVersionSetting.tsx
index 66de0a5..00b1c89 100644
--- a/src/plugins/init/settings/definitions/HermesVersionSetting.tsx
+++ b/src/plugins/init/settings/definitions/HermesVersionSetting.tsx
@@ -1,4 +1,4 @@
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import { MobileSetting } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
diff --git a/src/plugins/init/settings/definitions/ReactNativeVersionSetting.tsx b/src/plugins/init/settings/definitions/ReactNativeVersionSetting.tsx
index 7c609dc..2d41f47 100644
--- a/src/plugins/init/settings/definitions/ReactNativeVersionSetting.tsx
+++ b/src/plugins/init/settings/definitions/ReactNativeVersionSetting.tsx
@@ -1,10 +1,10 @@
-import { ReactNative } from '@revenge-mod/react'
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
+import { Platform } from 'react-native'
import { MobileSetting } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
const { major, minor, patch, prerelease } =
- ReactNative.Platform.constants.reactNativeVersion
+ Platform.constants.reactNativeVersion
const version = `${major}.${minor}.${patch}${prerelease ? `-${prerelease}` : ''}`
const ReactNativeVersionSetting: SettingsItem = {
diff --git a/src/plugins/init/settings/definitions/ReactVersionSetting.tsx b/src/plugins/init/settings/definitions/ReactVersionSetting.tsx
index 9a6acee..33e1300 100644
--- a/src/plugins/init/settings/definitions/ReactVersionSetting.tsx
+++ b/src/plugins/init/settings/definitions/ReactVersionSetting.tsx
@@ -1,5 +1,5 @@
-import { React } from '@revenge-mod/react'
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
+import { version } from 'react'
import { MobileSetting } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
@@ -7,7 +7,7 @@ const ReactVersionSetting: SettingsItem = {
parent: MobileSetting.REVENGE,
IconComponent: () => ,
title: () => 'React',
- useDescription: () => React.version,
+ useDescription: () => version,
type: 'static',
}
diff --git a/src/plugins/init/settings/definitions/ReloadAppSetting.tsx b/src/plugins/init/settings/definitions/ReloadAppSetting.tsx
index 7bcbd03..7a1847f 100644
--- a/src/plugins/init/settings/definitions/ReloadAppSetting.tsx
+++ b/src/plugins/init/settings/definitions/ReloadAppSetting.tsx
@@ -1,5 +1,5 @@
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import { BundleUpdaterManager } from '@revenge-mod/discord/native'
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
import { MobileSetting } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
diff --git a/src/plugins/init/settings/definitions/RevengeDiscordServerSetting.tsx b/src/plugins/init/settings/definitions/RevengeDiscordServerSetting.tsx
index b47127f..aba2730 100644
--- a/src/plugins/init/settings/definitions/RevengeDiscordServerSetting.tsx
+++ b/src/plugins/init/settings/definitions/RevengeDiscordServerSetting.tsx
@@ -1,5 +1,5 @@
-import { ReactNative } from '@revenge-mod/react'
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
+import { Linking } from 'react-native'
import { DiscordServerURL } from '~/constants'
import { MobileSetting } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
@@ -8,7 +8,7 @@ const RevengeDiscordServerSetting: SettingsItem = {
parent: MobileSetting.REVENGE,
IconComponent: () => ,
title: () => 'Discord Server',
- onPress: () => ReactNative.Linking.openURL(DiscordServerURL),
+ onPress: () => Linking.openURL(DiscordServerURL),
type: 'pressable',
}
diff --git a/src/plugins/init/settings/definitions/RevengeFontsSetting.tsx b/src/plugins/init/settings/definitions/RevengeFontsSetting.tsx
index 66081b3..69b3df3 100644
--- a/src/plugins/init/settings/definitions/RevengeFontsSetting.tsx
+++ b/src/plugins/init/settings/definitions/RevengeFontsSetting.tsx
@@ -1,4 +1,4 @@
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import { MobileSetting, UserSettingsSections } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
diff --git a/src/plugins/init/settings/definitions/RevengeGitHubOrganizationSetting.tsx b/src/plugins/init/settings/definitions/RevengeGitHubOrganizationSetting.tsx
index 12cf1ee..3957369 100644
--- a/src/plugins/init/settings/definitions/RevengeGitHubOrganizationSetting.tsx
+++ b/src/plugins/init/settings/definitions/RevengeGitHubOrganizationSetting.tsx
@@ -1,5 +1,5 @@
-import { ReactNative } from '@revenge-mod/react'
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
+import { Linking } from 'react-native'
import { GitHubOrganizationURL } from '~/constants'
import { MobileSetting } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
@@ -10,7 +10,7 @@ const RevengeGitHubOrganizationSetting: SettingsItem = {
),
title: () => 'GitHub',
- onPress: () => ReactNative.Linking.openURL(GitHubOrganizationURL),
+ onPress: () => Linking.openURL(GitHubOrganizationURL),
type: 'pressable',
}
diff --git a/src/plugins/init/settings/definitions/RevengeNotImplementedSetting.tsx b/src/plugins/init/settings/definitions/RevengeNotImplementedSetting.tsx
index 8ccd5ed..5985a02 100644
--- a/src/plugins/init/settings/definitions/RevengeNotImplementedSetting.tsx
+++ b/src/plugins/init/settings/definitions/RevengeNotImplementedSetting.tsx
@@ -1,4 +1,4 @@
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
const RevengeNotImplementedSetting: SettingsItem = {
diff --git a/src/plugins/init/settings/definitions/RevengePluginsSetting.tsx b/src/plugins/init/settings/definitions/RevengePluginsSetting.tsx
index 9c17481..445f249 100644
--- a/src/plugins/init/settings/definitions/RevengePluginsSetting.tsx
+++ b/src/plugins/init/settings/definitions/RevengePluginsSetting.tsx
@@ -1,6 +1,6 @@
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import { _plugins } from '@revenge-mod/plugins/_'
import { PluginFlags } from '@revenge-mod/plugins/constants'
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
import { MobileSetting, UserSettingsSections } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
diff --git a/src/plugins/init/settings/definitions/RevengeSetting.tsx b/src/plugins/init/settings/definitions/RevengeSetting.tsx
index cdf1b03..d14c852 100644
--- a/src/plugins/init/settings/definitions/RevengeSetting.tsx
+++ b/src/plugins/init/settings/definitions/RevengeSetting.tsx
@@ -1,4 +1,4 @@
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import RevengeIcon from '~assets/RevengeIcon'
import { MobileSetting, UserSettingsSections } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
diff --git a/src/plugins/init/settings/definitions/RevengeThemesSetting.tsx b/src/plugins/init/settings/definitions/RevengeThemesSetting.tsx
index a4e6526..d4dea0a 100644
--- a/src/plugins/init/settings/definitions/RevengeThemesSetting.tsx
+++ b/src/plugins/init/settings/definitions/RevengeThemesSetting.tsx
@@ -1,4 +1,4 @@
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import { MobileSetting, UserSettingsSections } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
diff --git a/src/plugins/init/settings/definitions/RevengeVersionSetting.tsx b/src/plugins/init/settings/definitions/RevengeVersionSetting.tsx
index fdf58a7..a628def 100644
--- a/src/plugins/init/settings/definitions/RevengeVersionSetting.tsx
+++ b/src/plugins/init/settings/definitions/RevengeVersionSetting.tsx
@@ -1,4 +1,4 @@
-import TableRowAssetIcon from '~/components/TableRowAssetIcon'
+import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import RevengeIcon from '~assets/RevengeIcon'
import { MobileSetting } from '../constants'
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
diff --git a/src/plugins/init/settings/screens/RevengeCustomPageScreen.tsx b/src/plugins/init/settings/screens/RevengeCustomPageScreen.tsx
index 73a3e4c..fd3c5e3 100644
--- a/src/plugins/init/settings/screens/RevengeCustomPageScreen.tsx
+++ b/src/plugins/init/settings/screens/RevengeCustomPageScreen.tsx
@@ -1,4 +1,4 @@
-import { React } from '@revenge-mod/react'
+import { useEffect } from 'react'
import type { StackScreenProps } from '@react-navigation/stack'
import type { ReactNavigationParamList } from '@revenge-mod/externals/react-navigation'
import type { MobileSetting, UserSettingsSections } from '../constants'
@@ -12,7 +12,8 @@ export default function RevengeCustomPageScreen({
>) {
const { render: PageComponent, options } = route.params
- React.useEffect(() => {
+ // biome-ignore lint/correctness/useExhaustiveDependencies: We only want to set options once
+ useEffect(() => {
if (options) navigation.setOptions(options)
}, [])
diff --git a/src/plugins/init/settings/screens/RevengePluginsSettingScreen.tsx b/src/plugins/init/settings/screens/RevengePluginsSettingScreen.tsx
index ebbae57..cbe786e 100644
--- a/src/plugins/init/settings/screens/RevengePluginsSettingScreen.tsx
+++ b/src/plugins/init/settings/screens/RevengePluginsSettingScreen.tsx
@@ -1,4 +1,7 @@
import { getAssetIdByName } from '@revenge-mod/assets'
+import FormSwitch from '@revenge-mod/components/FormSwitch'
+import Page from '@revenge-mod/components/Page'
+import SearchInput from '@revenge-mod/components/SearchInput'
import { Tokens } from '@revenge-mod/discord/common'
import { Design } from '@revenge-mod/discord/design'
import { FlashList } from '@revenge-mod/externals/shopify'
@@ -12,31 +15,30 @@ import {
startPlugin,
} from '@revenge-mod/plugins/_'
import { PluginFlags } from '@revenge-mod/plugins/constants'
-import { React, ReactNative } from '@revenge-mod/react'
+import { debounce } from '@revenge-mod/utils/callbacks'
import { useReRender } from '@revenge-mod/utils/react'
-import FormSwitch from '~/components/FormSwitch'
-import Page from '~/components/Page'
-import SearchInput from '~/components/SearchInput'
+import { useCallback, useMemo, useState } from 'react'
+import { Image, useWindowDimensions } from 'react-native'
import type { InternalPlugin } from '@revenge-mod/plugins/_'
-const { Image, useWindowDimensions } = ReactNative
const { Card, Text, Stack } = Design
export default function RevengePluginsSettingScreen() {
- const [search, setSearch] = React.useState('')
+ const [search, setSearch] = useState('')
+ const debouncedSetSearch = useCallback(debounce(setSearch, 100), [])
const { width } = useWindowDimensions()
const numColumns = Math.floor((width - 16) / 448)
- const plugins = React.useMemo(
+ const plugins = useMemo(
() =>
[..._plugins.values()].map(
plugin => [plugin, _metas.get(plugin.manifest.id)![2]] as const,
),
- [_plugins],
+ [],
)
- const filteredPlugins = React.useMemo(
+ const filteredPlugins = useMemo(
() =>
plugins.filter(([plugin]) => {
const { name, description, author } = plugin.manifest
@@ -52,7 +54,10 @@ export default function RevengePluginsSettingScreen() {
return (
- setSearch(v)} size="md" />
+ debouncedSetSearch(v)}
+ size="md"
+ />
(
pattern: ImportMetaGlobPattern,