fix(plugins/settings): show Reload Required dialog before settings modules load
This commit is contained in:
parent
d54623aa20
commit
6df0716ec5
4 changed files with 139 additions and 135 deletions
|
|
@ -1,16 +1,10 @@
|
|||
import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
|
||||
import { AlertActionCreators } from '@revenge-mod/discord/actions'
|
||||
import { Design } from '@revenge-mod/discord/design'
|
||||
import { BundleUpdaterManager } from '@revenge-mod/discord/native'
|
||||
import { isPluginEnabled, pEmitter, pList } from '@revenge-mod/plugins/_'
|
||||
import { PluginFlags } from '@revenge-mod/plugins/constants'
|
||||
import { debounce } from '@revenge-mod/utils/callback'
|
||||
import { useReRender } from '@revenge-mod/utils/react'
|
||||
import { useEffect } from 'react'
|
||||
import { RouteNames, Setting } from '../constants'
|
||||
import defer * as RevengePluginsSettingScreen from '../screens/RevengePluginsSettingScreen'
|
||||
import type { SettingsItem } from '@revenge-mod/discord/modules/settings'
|
||||
import type { AnyPlugin } from '@revenge-mod/plugins/_'
|
||||
|
||||
const RevengePluginsSetting: SettingsItem = {
|
||||
parent: null,
|
||||
|
|
@ -52,60 +46,4 @@ function useEnabledPluginCount() {
|
|||
return enabledCount
|
||||
}
|
||||
|
||||
const { AlertActionButton, AlertModal, Text } = Design
|
||||
|
||||
pEmitter.on(
|
||||
'flagUpdate',
|
||||
debounce(function showReloadRequiredAlertIfNeeded(plugin: AnyPlugin) {
|
||||
if (plugin.flags & PluginFlags.ReloadRequired) {
|
||||
const plugins = [...pList.values()].filter(
|
||||
plugin => plugin.flags & PluginFlags.ReloadRequired,
|
||||
)
|
||||
|
||||
AlertActionCreators.openAlert(
|
||||
'plugin-reload-required',
|
||||
<PluginReloadRequiredAlert plugins={plugins} />,
|
||||
)
|
||||
}
|
||||
}, 500),
|
||||
)
|
||||
|
||||
function PluginReloadRequiredAlert({ plugins }: { plugins: AnyPlugin[] }) {
|
||||
return (
|
||||
<AlertModal
|
||||
title="Reload required"
|
||||
content={
|
||||
<Text variant="text-md/medium" color="header-secondary">
|
||||
The following plugins require a reload to apply changes:
|
||||
{'\n'}
|
||||
{plugins.map((plugin, index) => (
|
||||
<>
|
||||
{index ? ' ,' : null}
|
||||
<Text
|
||||
key={plugin.manifest.id}
|
||||
variant="text-md/bold"
|
||||
color="text-normal"
|
||||
>
|
||||
{plugin.manifest.name}
|
||||
</Text>
|
||||
</>
|
||||
))}
|
||||
</Text>
|
||||
}
|
||||
actions={
|
||||
<>
|
||||
<AlertActionButton
|
||||
variant="destructive"
|
||||
text="Reload"
|
||||
onPress={() => {
|
||||
BundleUpdaterManager.reload()
|
||||
}}
|
||||
/>
|
||||
<AlertActionButton variant="secondary" text="Not now" />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default RevengePluginsSetting
|
||||
|
|
|
|||
|
|
@ -8,13 +8,11 @@ import { withName } from '@revenge-mod/modules/finders/filters'
|
|||
import { instead } from '@revenge-mod/patcher'
|
||||
import { InternalPluginFlags, registerPlugin } from '@revenge-mod/plugins/_'
|
||||
import { PluginFlags } from '@revenge-mod/plugins/constants'
|
||||
import { useEffect } from 'react'
|
||||
import type { FC } from 'react'
|
||||
|
||||
import './register-routes'
|
||||
import { React } from '@revenge-mod/react'
|
||||
import { noop } from '@revenge-mod/utils/callback'
|
||||
import { useReRender } from '@revenge-mod/utils/react'
|
||||
import { useEffect } from 'react'
|
||||
import type { FC } from 'react'
|
||||
|
||||
const pluginSettings = registerPlugin(
|
||||
{
|
||||
|
|
@ -26,6 +24,9 @@ const pluginSettings = registerPlugin(
|
|||
},
|
||||
{
|
||||
start() {
|
||||
// @as-require
|
||||
import('./plugins')
|
||||
|
||||
onSettingsModulesLoaded(() => {
|
||||
// @as-require
|
||||
import('./register')
|
||||
|
|
|
|||
134
src/plugins/start/settings/plugins.tsx
Normal file
134
src/plugins/start/settings/plugins.tsx
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
|
||||
import { AlertActionCreators } from '@revenge-mod/discord/actions'
|
||||
import { Design } from '@revenge-mod/discord/design'
|
||||
import {
|
||||
refreshSettingsNavigator,
|
||||
registerSettingsItem,
|
||||
} from '@revenge-mod/discord/modules/settings'
|
||||
import { BundleUpdaterManager } from '@revenge-mod/discord/native'
|
||||
import { pEmitter, pList } from '@revenge-mod/plugins/_'
|
||||
import { PluginFlags } from '@revenge-mod/plugins/constants'
|
||||
import { debounce } from '@revenge-mod/utils/callback'
|
||||
import { useLayoutEffect } from 'react'
|
||||
import defer * as NavigatorHeaderWithIcon from './components/NavigatorHeaderWithIcon'
|
||||
import { Setting } from './constants'
|
||||
import type { StackScreenProps } from '@react-navigation/stack'
|
||||
import type { ReactNavigationParamList } from '@revenge-mod/externals/react-navigation'
|
||||
import type { AnyPlugin } from '@revenge-mod/plugins/_'
|
||||
import type { PluginApi } from '@revenge-mod/plugins/types'
|
||||
|
||||
/// SETTINGS ROUTES
|
||||
|
||||
pEmitter.on('started', plugin => {
|
||||
if (plugin.SettingsComponent) {
|
||||
const api = plugin.api as PluginApi<any>
|
||||
const Component = plugin.SettingsComponent!
|
||||
|
||||
function PluginSettings({
|
||||
navigation,
|
||||
}: StackScreenProps<ReactNavigationParamList>) {
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: We only want to set options once
|
||||
useLayoutEffect(() => {
|
||||
if (plugin.manifest.icon)
|
||||
navigation.setOptions({
|
||||
headerTitle: () => (
|
||||
<NavigatorHeaderWithIcon.default
|
||||
title={plugin.manifest.name}
|
||||
icon={plugin.manifest.icon!}
|
||||
/>
|
||||
),
|
||||
})
|
||||
else
|
||||
navigation.setOptions({
|
||||
title: plugin.manifest.name,
|
||||
})
|
||||
}, [])
|
||||
|
||||
return <Component api={api} />
|
||||
}
|
||||
|
||||
api.cleanup(
|
||||
registerSettingsItem(plugin.manifest.id, {
|
||||
parent: Setting.Revenge,
|
||||
type: 'route',
|
||||
IconComponent: plugin.manifest.icon
|
||||
? () => <TableRowAssetIcon name={plugin.manifest.icon!} />
|
||||
: undefined,
|
||||
title: () => plugin.manifest.name,
|
||||
screen: {
|
||||
route: plugin.manifest.id,
|
||||
getComponent: () => PluginSettings,
|
||||
},
|
||||
}),
|
||||
refreshSettingsNavigator,
|
||||
// TODO(PalmDevs): In the future, we may allow pinning plugin settings, so we'll need this cleanup
|
||||
// () => refreshSettingsOverviewScreen(),
|
||||
)
|
||||
|
||||
refreshSettingsNavigator()
|
||||
}
|
||||
})
|
||||
|
||||
/// RELOAD REQUIRED ALERT
|
||||
|
||||
const { AlertActionButton, AlertModal, Text } = Design
|
||||
|
||||
function showReloadRequiredAlertIfNeeded() {
|
||||
const plugins = [...pList.values()].filter(
|
||||
plugin => plugin.flags & PluginFlags.ReloadRequired,
|
||||
)
|
||||
|
||||
if (!plugins.length) return
|
||||
|
||||
AlertActionCreators.openAlert(
|
||||
'plugin-reload-required',
|
||||
<PluginReloadRequiredAlert plugins={plugins} />,
|
||||
)
|
||||
}
|
||||
|
||||
pEmitter.on(
|
||||
'flagUpdate',
|
||||
debounce(plugin => {
|
||||
if (plugin.flags & PluginFlags.ReloadRequired)
|
||||
showReloadRequiredAlertIfNeeded()
|
||||
}, 500),
|
||||
)
|
||||
showReloadRequiredAlertIfNeeded()
|
||||
|
||||
function PluginReloadRequiredAlert({ plugins }: { plugins: AnyPlugin[] }) {
|
||||
return (
|
||||
<AlertModal
|
||||
title="Reload Required"
|
||||
content={
|
||||
<Text variant="text-md/medium" color="header-secondary">
|
||||
The following plugins require a reload to apply changes:
|
||||
{'\n'}
|
||||
{plugins.map((plugin, index) => (
|
||||
<>
|
||||
{index ? ', ' : null}
|
||||
<Text
|
||||
key={plugin.manifest.id}
|
||||
variant="text-md/bold"
|
||||
color="text-normal"
|
||||
>
|
||||
{plugin.manifest.name}
|
||||
</Text>
|
||||
</>
|
||||
))}
|
||||
</Text>
|
||||
}
|
||||
actions={
|
||||
<>
|
||||
<AlertActionButton
|
||||
variant="destructive"
|
||||
text="Reload"
|
||||
onPress={() => {
|
||||
BundleUpdaterManager.reload()
|
||||
}}
|
||||
/>
|
||||
<AlertActionButton variant="secondary" text="Not now" />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
|
||||
import {
|
||||
refreshSettingsNavigator,
|
||||
registerSettingsItem,
|
||||
} from '@revenge-mod/discord/modules/settings'
|
||||
import { pEmitter } from '@revenge-mod/plugins/_'
|
||||
import { proxify } from '@revenge-mod/utils/proxy'
|
||||
import { useLayoutEffect } from 'react'
|
||||
import defer * as NavigatorHeaderWithIcon_ from './components/NavigatorHeaderWithIcon'
|
||||
import { Setting } from './constants'
|
||||
import type { StackScreenProps } from '@react-navigation/stack'
|
||||
import type { ReactNavigationParamList } from '@revenge-mod/externals/react-navigation'
|
||||
import type { PluginApi } from '@revenge-mod/plugins/types'
|
||||
|
||||
type NavigatorHeaderWithIcon = (typeof NavigatorHeaderWithIcon_)['default']
|
||||
|
||||
let NavigatorHeaderWithIcon: NavigatorHeaderWithIcon = proxify(
|
||||
() => (NavigatorHeaderWithIcon = NavigatorHeaderWithIcon_.default),
|
||||
)
|
||||
|
||||
pEmitter.on('started', plugin => {
|
||||
if (plugin.SettingsComponent) {
|
||||
refreshSettingsNavigator()
|
||||
|
||||
const api = plugin.api as PluginApi<any>
|
||||
|
||||
function PluginSettings({
|
||||
navigation,
|
||||
}: StackScreenProps<ReactNavigationParamList>) {
|
||||
const SC = plugin.SettingsComponent!
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: We only want to set options once
|
||||
useLayoutEffect(() => {
|
||||
if (plugin.manifest.icon)
|
||||
navigation.setOptions({
|
||||
headerTitle: () => (
|
||||
<NavigatorHeaderWithIcon
|
||||
title={plugin.manifest.name}
|
||||
icon={plugin.manifest.icon!}
|
||||
/>
|
||||
),
|
||||
})
|
||||
else
|
||||
navigation.setOptions({
|
||||
title: plugin.manifest.name,
|
||||
})
|
||||
}, [])
|
||||
|
||||
return <SC api={api} />
|
||||
}
|
||||
|
||||
api.cleanup(
|
||||
registerSettingsItem(plugin.manifest.id, {
|
||||
parent: Setting.Revenge,
|
||||
type: 'route',
|
||||
IconComponent: plugin.manifest.icon
|
||||
? () => <TableRowAssetIcon name={plugin.manifest.icon!} />
|
||||
: undefined,
|
||||
title: () => plugin.manifest.name,
|
||||
screen: {
|
||||
route: plugin.manifest.id,
|
||||
getComponent: () => PluginSettings,
|
||||
},
|
||||
}),
|
||||
// TODO(PalmDevs): In the future, we may allow pinning plugin settings, so we'll need this cleanup
|
||||
// () => refreshSettingsOverviewScreen(),
|
||||
)
|
||||
}
|
||||
})
|
||||
Loading…
Add table
Reference in a new issue