feat(plugins/settings): notify user on plugin error

This commit is contained in:
PalmDevs 2025-10-23 00:55:24 +07:00
parent acac384f8b
commit 079577922e
No known key found for this signature in database
GPG key ID: 6FAE8F8677ACA8BA
3 changed files with 138 additions and 53 deletions

View file

@ -0,0 +1,63 @@
import { Design } from '@revenge-mod/discord/design'
import { RootNavigationRef } from '@revenge-mod/discord/modules/main_tabs_v2'
import { RouteNames } from '../constants'
import type { AnyPlugin } from '@revenge-mod/plugins/_'
const { AlertModal, AlertActionButton, Text } = Design
export default function PluginsFailedToStartAlert({
plugins,
}: {
plugins: AnyPlugin[]
}) {
const navigation = RootNavigationRef.getRootNavigationRef()
return (
<AlertModal
title="Plugins failed to start"
content={
<Text variant="text-md/medium" color="header-secondary">
The following plugins encountered errors while starting:
{'\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="primary"
text="View plugins"
onPress={() => {
const params = {
filter: ['Has Errors'],
}
if (
navigation.getCurrentRoute()?.name ===
RouteNames.RevengePlugins
)
navigation.setParams(params)
else
navigation.navigate(
RouteNames.RevengePlugins,
params,
)
}}
/>
<AlertActionButton variant="secondary" text="Got it" />
</>
}
/>
)
}

View file

@ -0,0 +1,48 @@
import { Design } from '@revenge-mod/discord/design'
import { BundleUpdaterManager } from '@revenge-mod/discord/native'
import type { AnyPlugin } from '@revenge-mod/plugins/_'
const { AlertModal, AlertActionButton, Text } = Design
export default function PluginsRequireReloadAlert({
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={() => {
// TODO: Replace with bridge call
BundleUpdaterManager.reload()
}}
/>
<AlertActionButton variant="secondary" text="Not now" />
</>
}
/>
)
}

View file

@ -1,20 +1,18 @@
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 PluginsFailedToStartAlert from './components/PluginsFailedToStartAlert'
import PluginsRequireReloadAlert from './components/PluginsRequireReloadAlert'
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
@ -71,8 +69,6 @@ pEmitter.on('started', plugin => {
/// RELOAD REQUIRED ALERT
const { AlertActionButton, AlertModal, Text } = Design
function showReloadRequiredAlertIfNeeded() {
const plugins = [...pList.values()].filter(
plugin => plugin.flags & PluginFlags.ReloadRequired,
@ -81,54 +77,32 @@ function showReloadRequiredAlertIfNeeded() {
if (!plugins.length) return
AlertActionCreators.openAlert(
'plugin-reload-required',
<PluginReloadRequiredAlert plugins={plugins} />,
'plugins-require-reload',
<PluginsRequireReloadAlert plugins={plugins} />,
)
}
pEmitter.on(
'flagUpdate',
debounce(plugin => {
if (plugin.flags & PluginFlags.ReloadRequired)
showReloadRequiredAlertIfNeeded()
}, 500),
)
function showErrorAlertIfNeeded() {
const plugins = [...pList.values()].filter(
plugin => plugin.flags & PluginFlags.Errored,
)
if (!plugins.length) return
AlertActionCreators.openAlert(
'plugins-failed-to-start',
<PluginsFailedToStartAlert plugins={plugins} />,
)
}
pEmitter.on('flagUpdate', plugin => {
if (plugin.flags & PluginFlags.ReloadRequired)
showReloadRequiredAlertIfNeeded()
})
pEmitter.on('stopped', plugin => {
if (plugin.flags & PluginFlags.Errored) showErrorAlertIfNeeded()
})
showErrorAlertIfNeeded()
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" />
</>
}
/>
)
}