From 1ae6519209c9bf079d8dff80d5bceb5a847b08b1 Mon Sep 17 00:00:00 2001 From: Jesse Bofill Date: Mon, 6 Oct 2025 14:29:39 -0600 Subject: implement frontend diisable functions/ modal --- .../src/components/modals/PluginDisablelModal.tsx | 46 ++++++++++++++++++++++ .../settings/pages/plugin_list/index.tsx | 22 ++++++++++- frontend/src/plugin-loader.tsx | 4 ++ frontend/src/plugin.ts | 2 + 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/modals/PluginDisablelModal.tsx (limited to 'frontend/src') diff --git a/frontend/src/components/modals/PluginDisablelModal.tsx b/frontend/src/components/modals/PluginDisablelModal.tsx new file mode 100644 index 00000000..89cda293 --- /dev/null +++ b/frontend/src/components/modals/PluginDisablelModal.tsx @@ -0,0 +1,46 @@ +import { ConfirmModal, Spinner } from '@decky/ui'; +import { FC, useState } from 'react'; + +import { disablePlugin, uninstallPlugin } from '../../plugin'; + +interface PluginUninstallModalProps { + name: string; + title: string; + buttonText: string; + description: string; + closeModal?(): void; +} + +const PluginDisableModal: FC = ({ name, title, buttonText, description, closeModal }) => { + const [disabling, setDisabling] = useState(false); + return ( + { + setDisabling(true); + await disablePlugin(name); + + //not sure about this yet + + // uninstalling a plugin resets the hidden setting for it server-side + // we invalidate here so if you re-install it, you won't have an out-of-date hidden filter + await DeckyPluginLoader.frozenPluginsService.invalidate(); + await DeckyPluginLoader.hiddenPluginsService.invalidate(); + closeModal?.(); + }} + bOKDisabled={disabling} + bCancelDisabled={disabling} + strTitle={ +
+ {title} + {disabling && } +
+ } + strOKButtonText={buttonText} + > + {description} +
+ ); +}; + +export default PluginDisableModal; diff --git a/frontend/src/components/settings/pages/plugin_list/index.tsx b/frontend/src/components/settings/pages/plugin_list/index.tsx index e244b8a9..f13cbe2b 100644 --- a/frontend/src/components/settings/pages/plugin_list/index.tsx +++ b/frontend/src/components/settings/pages/plugin_list/index.tsx @@ -35,6 +35,7 @@ async function reinstallPlugin(pluginName: string, currentVersion?: string) { type PluginTableData = PluginData & { name: string; + disabled: boolean; frozen: boolean; onFreeze(): void; onUnfreeze(): void; @@ -54,7 +55,7 @@ function PluginInteractables(props: { entry: ReorderableEntry } return null; } - const { name, update, version, onHide, onShow, hidden, onFreeze, onUnfreeze, frozen, isDeveloper } = props.entry.data; + const { name, update, version, onHide, onShow, hidden, onFreeze, onUnfreeze, frozen, isDeveloper, disabled } = props.entry.data; const showCtxMenu = (e: MouseEvent | GamepadEvent) => { showContextMenu( @@ -82,6 +83,22 @@ function PluginInteractables(props: { entry: ReorderableEntry } > {t('PluginListIndex.uninstall')} + {disabled ? + DeckyPluginLoader.disablePlugin( + name, + t('PluginLoader.plugin_disable.title', { name }), + t('PluginLoader.plugin_disable.button'), + t('PluginLoader.plugin_disable.desc', { name }), + ) + } + > + {t('PluginListIndex.plugin_disable')} + : + // implement enabler + <> + + } {hidden ? ( {t('PluginListIndex.show')} ) : ( @@ -147,7 +164,7 @@ type PluginData = { }; export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) { - const { installedPlugins, updates, pluginOrder, setPluginOrder, frozenPlugins, hiddenPlugins } = useDeckyState(); + const { installedPlugins, disabled, updates, pluginOrder, setPluginOrder, frozenPlugins, hiddenPlugins } = useDeckyState(); const [_, setPluginOrderSetting] = useSetting( 'pluginOrder', @@ -174,6 +191,7 @@ export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) { position: pluginOrder.indexOf(name), data: { name, + disabled: disabled.some(disabledPlugin => disabledPlugin.name === name), frozen, hidden, isDeveloper, diff --git a/frontend/src/plugin-loader.tsx b/frontend/src/plugin-loader.tsx index 9d74cbae..755c4460 100644 --- a/frontend/src/plugin-loader.tsx +++ b/frontend/src/plugin-loader.tsx @@ -341,6 +341,10 @@ class PluginLoader extends Logger { showModal(); } + public disablePlugin(name: string, title: string, buttonText: string, description: string) { + showModal(); + } + public hasPlugin(name: string) { return Boolean(this.plugins.find((plugin) => plugin.name == name)); } diff --git a/frontend/src/plugin.ts b/frontend/src/plugin.ts index f53118b2..32d423d5 100644 --- a/frontend/src/plugin.ts +++ b/frontend/src/plugin.ts @@ -57,3 +57,5 @@ type installPluginsArgs = [ export let installPlugins = DeckyBackend.callable('utilities/install_plugins'); export let uninstallPlugin = DeckyBackend.callable<[name: string]>('utilities/uninstall_plugin'); +export let enablePlugin = DeckyBackend.callable<[name: string]>('utilities/enable_plugin'); +export let disablePlugin = DeckyBackend.callable<[name: string]>('utilities/disable_plugin'); -- cgit v1.2.3