feat: see commit description
- Shim React and React Native - Move src/components to lib/components - Exposed lib/components to `unscoped.components` - scipts/build: Properly set footer sourceURL - plugins/developer-settings: Debounce searching in Asset Browser - plugins/settings: Debounce searching in Plugins
This commit is contained in:
parent
f453a82dab
commit
5b3a8bc5ab
42 changed files with 174 additions and 71 deletions
5
bun.lock
5
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"],
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
25
lib/components/package.json
Normal file
25
lib/components/package.json
Normal file
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 (
|
||||
<ReactNative.View style={props.disabled && styles.disabled}>
|
||||
<View style={props.disabled && styles.disabled}>
|
||||
<Switch {...props} />
|
||||
</ReactNative.View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = ReactNative.StyleSheet.create({
|
||||
const styles = StyleSheet.create({
|
||||
disabled: {
|
||||
opacity: 0.5,
|
||||
},
|
||||
|
|
@ -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,
|
||||
4
lib/components/src/index.ts
Normal file
4
lib/components/src/index.ts
Normal file
|
|
@ -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'
|
||||
11
lib/components/src/init.ts
Normal file
11
lib/components/src/init.ts
Normal file
|
|
@ -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')
|
||||
})
|
||||
12
lib/components/src/types.ts
Normal file
12
lib/components/src/types.ts
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
3
shims/react-native.ts
Normal file
3
shims/react-native.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { ReactNative } from '@revenge-mod/react'
|
||||
|
||||
module.exports = ReactNative
|
||||
3
shims/react.ts
Normal file
3
shims/react.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { React } from '@revenge-mod/react'
|
||||
|
||||
module.exports = React
|
||||
|
|
@ -19,4 +19,4 @@ const jsxs = ((type, ...args) =>
|
|||
...args,
|
||||
)) as typeof _jsxs
|
||||
|
||||
export { jsx, jsxs, Fragment }
|
||||
module.exports = { jsx, jsxs, Fragment }
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<AlertModal
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import TableRowAssetIcon from '~/components/TableRowAssetIcon'
|
||||
import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
|
||||
import { api } from '..'
|
||||
import { MobileSetting } from '../constants'
|
||||
import { DevToolsContext } from '../react-devtools'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import TableRowAssetIcon from '~/components/TableRowAssetIcon'
|
||||
import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
|
||||
import { MobileSetting } from '../constants'
|
||||
import {
|
||||
connectToDevTools,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import TableRowAssetIcon from '~/components/TableRowAssetIcon'
|
||||
import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
|
||||
import { MobileSetting } from '../constants'
|
||||
import { disconnectFromDevTools, useIsDevToolsOpen } from '../react-devtools'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import TableRowAssetIcon from '~/components/TableRowAssetIcon'
|
||||
import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
|
||||
import { MobileSetting } from '../constants'
|
||||
import { DevToolsContext } from '../react-devtools'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { ToastActionCreators } from '@revenge-mod/discord/actions'
|
||||
import { React } from '@revenge-mod/react'
|
||||
import { lookupGeneratedIconComponent } from '@revenge-mod/utils/discord'
|
||||
import { getErrorStack } from '@revenge-mod/utils/errors'
|
||||
import { useReRender } from '@revenge-mod/utils/react'
|
||||
import { useEffect } from 'react'
|
||||
import { api } from '.'
|
||||
|
||||
export const DevToolsContext: {
|
||||
|
|
@ -80,14 +80,14 @@ export function disconnectFromDevTools() {
|
|||
export function useIsDevToolsOpen() {
|
||||
const rerender = useReRender()
|
||||
|
||||
React.useEffect(() => {
|
||||
useEffect(() => {
|
||||
const sub: Subscription = e => (e === 1 || e === 2) && rerender()
|
||||
subscriptions.add(sub)
|
||||
|
||||
return () => {
|
||||
subscriptions.delete(sub)
|
||||
}
|
||||
}, [])
|
||||
}, [rerender])
|
||||
|
||||
return DevToolsContext.open
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Page spacing={16}>
|
||||
<SearchInput onChange={(v: string) => setSearch(v)} size="md" />
|
||||
<SearchInput
|
||||
onChange={(v: string) => debouncedSetSearch(v)}
|
||||
size="md"
|
||||
/>
|
||||
<FlashList.FlashList
|
||||
data={filteredAssets}
|
||||
contentContainerStyle={styles.listContainer}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { ToastActionCreators } from '@revenge-mod/discord/actions'
|
||||
import { Design } from '@revenge-mod/discord/design'
|
||||
import { SettingListRenderer } from '@revenge-mod/discord/modules/settings/renderer'
|
||||
import { ReactNative } from '@revenge-mod/react'
|
||||
import { lookupGeneratedIconComponent } from '@revenge-mod/utils/discord'
|
||||
import { View } from 'react-native'
|
||||
import { api } from '..'
|
||||
import { MobileSetting } from '../constants'
|
||||
import { DevToolsContext, useIsDevToolsOpen } from '../react-devtools'
|
||||
|
|
@ -49,7 +49,7 @@ export function ReactDevToolsAddressSetting() {
|
|||
const settings = api.storage.use(s => s.devtools?.address)
|
||||
|
||||
return (
|
||||
<ReactNative.View style={{ paddingHorizontal: 16, paddingTop: 16 }}>
|
||||
<View style={{ paddingHorizontal: 16, paddingTop: 16 }}>
|
||||
<Design.TextInput
|
||||
defaultValue={
|
||||
settings?.devtools.address ?? DevToolsContext.address
|
||||
|
|
@ -76,6 +76,6 @@ export function ReactDevToolsAddressSetting() {
|
|||
onChange={text => (DevToolsContext.address = text)}
|
||||
returnKeyType="done"
|
||||
/>
|
||||
</ReactNative.View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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: () => <TableRowAssetIcon name="ScienceIcon" />,
|
||||
title: () => 'React',
|
||||
useDescription: () => React.version,
|
||||
useDescription: () => version,
|
||||
type: 'static',
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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: () => <TableRowAssetIcon name="Discord" />,
|
||||
title: () => 'Discord Server',
|
||||
onPress: () => ReactNative.Linking.openURL(DiscordServerURL),
|
||||
onPress: () => Linking.openURL(DiscordServerURL),
|
||||
type: 'pressable',
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = {
|
|||
<TableRowAssetIcon name="img_account_sync_github_white" />
|
||||
),
|
||||
title: () => 'GitHub',
|
||||
onPress: () => ReactNative.Linking.openURL(GitHubOrganizationURL),
|
||||
onPress: () => Linking.openURL(GitHubOrganizationURL),
|
||||
type: 'pressable',
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}, [])
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Page spacing={16}>
|
||||
<SearchInput onChange={(v: string) => setSearch(v)} size="md" />
|
||||
<SearchInput
|
||||
onChange={(v: string) => debouncedSetSearch(v)}
|
||||
size="md"
|
||||
/>
|
||||
<FlashList.MasonryFlashList
|
||||
data={filteredPlugins}
|
||||
estimatedItemSize={108}
|
||||
|
|
|
|||
5
types.d.ts
vendored
5
types.d.ts
vendored
|
|
@ -8,6 +8,11 @@ declare global {
|
|||
|
||||
const __BUILD_FLAG_LOG_PROMISE_REJECTIONS__: boolean
|
||||
|
||||
// CommonJS modules, we don't want to depend on @types/node
|
||||
const module: {
|
||||
exports: any
|
||||
}
|
||||
|
||||
export interface ImportMeta {
|
||||
glob<T = any>(
|
||||
pattern: ImportMetaGlobPattern,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue