working plugin disable, not tested extensively
Builder Win / Build PluginLoader for Win (push) Has been cancelled
Builder / Build PluginLoader (push) Has been cancelled
Push Updated Plugin Stub to Template / copy-stub (push) Has been cancelled
Lint / Run linters (push) Has been cancelled
Type Check / Run type checkers (push) Has been cancelled

This commit is contained in:
marios
2025-10-07 02:40:41 +03:00
parent 6fac72112c
commit 968c8b113c
4 changed files with 47 additions and 12 deletions
+3 -1
View File
@@ -80,6 +80,8 @@ class Utilities:
context.ws.add_route("utilities/restart_webhelper", self.restart_webhelper) context.ws.add_route("utilities/restart_webhelper", self.restart_webhelper)
context.ws.add_route("utilities/close_cef_socket", self.close_cef_socket) context.ws.add_route("utilities/close_cef_socket", self.close_cef_socket)
context.ws.add_route("utilities/_call_legacy_utility", self._call_legacy_utility) context.ws.add_route("utilities/_call_legacy_utility", self._call_legacy_utility)
context.ws.add_route("utilities/enable_plugin", self.enable_plugin)
context.ws.add_route("utilities/disable_plugin", self.disable_plugin)
context.web_app.add_routes([ context.web_app.add_routes([
post("/methods/{method_name}", self._handle_legacy_server_method_call) post("/methods/{method_name}", self._handle_legacy_server_method_call)
@@ -481,7 +483,7 @@ class Utilities:
await self.set_setting("disabled_plugins", disabled_plugins) await self.set_setting("disabled_plugins", disabled_plugins)
await self.context.plugin_loader.plugins[name].stop() await self.context.plugin_loader.plugins[name].stop()
await self.context.ws.emit("loader/unload_plugin", name) await self.context.ws.emit("loader/disable_plugin", name)
async def enable_plugin(self, name: str): async def enable_plugin(self, name: str):
disabled_plugins: List[str] = await self.get_setting("disabled_plugins", []) disabled_plugins: List[str] = await self.get_setting("disabled_plugins", [])
@@ -1,15 +1,16 @@
import { FC } from 'react'; import { FC } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FaEyeSlash, FaLock } from 'react-icons/fa'; import { FaEyeSlash, FaLock, FaMoon } from 'react-icons/fa';
interface PluginListLabelProps { interface PluginListLabelProps {
frozen: boolean; frozen: boolean;
hidden: boolean; hidden: boolean;
disabled: boolean;
name: string; name: string;
version?: string; version?: string;
} }
const PluginListLabel: FC<PluginListLabelProps> = ({ name, frozen, hidden, version }) => { const PluginListLabel: FC<PluginListLabelProps> = ({ name, frozen, hidden, version, disabled }) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
@@ -43,6 +44,20 @@ const PluginListLabel: FC<PluginListLabelProps> = ({ name, frozen, hidden, versi
{t('PluginListLabel.hidden')} {t('PluginListLabel.hidden')}
</div> </div>
)} )}
{disabled && (
<div
style={{
fontSize: '0.8rem',
color: '#dcdedf',
display: 'flex',
alignItems: 'center',
gap: '10px',
}}
>
<FaMoon />
{t('PluginListLabel.disabled')}
</div>
)}
</div> </div>
); );
}; };
@@ -13,7 +13,7 @@ import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FaDownload, FaEllipsisH, FaRecycle } from 'react-icons/fa'; import { FaDownload, FaEllipsisH, FaRecycle } from 'react-icons/fa';
import { InstallType } from '../../../../plugin'; import { enablePlugin, InstallType } from '../../../../plugin';
import { import {
StorePluginVersion, StorePluginVersion,
getPluginList, getPluginList,
@@ -84,9 +84,11 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginTableData> }
{t('PluginListIndex.uninstall')} {t('PluginListIndex.uninstall')}
</MenuItem> </MenuItem>
{disabled ? {disabled ?
// implement enabler <MenuItem
<> onSelected={() => enablePlugin(name)}
</> : >
{t('PluginListIndex.plugin_enable')}
</MenuItem> :
<MenuItem <MenuItem
onSelected={() => onSelected={() =>
DeckyPluginLoader.disablePlugin( DeckyPluginLoader.disablePlugin(
@@ -188,7 +190,8 @@ export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) {
const hidden = hiddenPlugins.includes(name); const hidden = hiddenPlugins.includes(name);
return { return {
label: <PluginListLabel name={name} frozen={frozen} hidden={hidden} version={version} />, label: <PluginListLabel name={name} frozen={frozen} hidden={hidden} version={version}
disabled={disabled.find(p => p.name == name) !== undefined} />,
position: pluginOrder.indexOf(name), position: pluginOrder.indexOf(name),
data: { data: {
name, name,
+19 -4
View File
@@ -92,6 +92,7 @@ class PluginLoader extends Logger {
DeckyBackend.addEventListener('loader/notify_updates', this.notifyUpdates.bind(this)); DeckyBackend.addEventListener('loader/notify_updates', this.notifyUpdates.bind(this));
DeckyBackend.addEventListener('loader/import_plugin', this.importPlugin.bind(this)); DeckyBackend.addEventListener('loader/import_plugin', this.importPlugin.bind(this));
DeckyBackend.addEventListener('loader/unload_plugin', this.unloadPlugin.bind(this)); DeckyBackend.addEventListener('loader/unload_plugin', this.unloadPlugin.bind(this));
DeckyBackend.addEventListener('loader/disable_plugin', this.doDisablePlugin.bind(this));
DeckyBackend.addEventListener('loader/add_plugin_install_prompt', this.addPluginInstallPrompt.bind(this)); DeckyBackend.addEventListener('loader/add_plugin_install_prompt', this.addPluginInstallPrompt.bind(this));
DeckyBackend.addEventListener( DeckyBackend.addEventListener(
'loader/add_multiple_plugins_install_prompt', 'loader/add_multiple_plugins_install_prompt',
@@ -207,10 +208,10 @@ class PluginLoader extends Logger {
let registration: any; let registration: any;
const uiMode = await new Promise( const uiMode = await new Promise(
(r) => (r) =>
(registration = SteamClient.UI.RegisterForUIModeChanged((mode: EUIMode) => { (registration = SteamClient.UI.RegisterForUIModeChanged((mode: EUIMode) => {
r(mode); r(mode);
registration.unregister(); registration.unregister();
})), })),
); );
if (uiMode == EUIMode.GamePad) { if (uiMode == EUIMode.GamePad) {
// wait for SP window to exist before loading plugins // wait for SP window to exist before loading plugins
@@ -384,6 +385,17 @@ class PluginLoader extends Logger {
this.errorBoundaryHook.deinit(); this.errorBoundaryHook.deinit();
} }
public doDisablePlugin(name: string) {
const plugin = this.plugins.find((plugin) => plugin.name === name);
if (plugin == undefined) return;
plugin?.onDismount?.();
this.plugins = this.plugins.filter((p) => p !== plugin);
this.deckyState.setDisabledPlugins([...this.deckyState.publicState().disabled,
{ name: plugin.name, version: plugin.version }]);
this.deckyState.setPlugins(this.plugins);
}
public unloadPlugin(name: string, skipStateUpdate: boolean = false) { public unloadPlugin(name: string, skipStateUpdate: boolean = false) {
const plugin = this.plugins.find((plugin) => plugin.name === name); const plugin = this.plugins.find((plugin) => plugin.name === name);
plugin?.onDismount?.(); plugin?.onDismount?.();
@@ -403,12 +415,15 @@ class PluginLoader extends Logger {
return; return;
} }
this.deckyState.setDisabledPlugins(this.deckyState.publicState().disabled.filter(d => d.name !== name))
try { try {
if (useQueue) this.reloadLock = true; if (useQueue) this.reloadLock = true;
this.log(`Trying to load ${name}`); this.log(`Trying to load ${name}`);
this.unloadPlugin(name, true); this.unloadPlugin(name, true);
const startTime = performance.now(); const startTime = performance.now();
await this.importReactPlugin(name, version, loadType); await this.importReactPlugin(name, version, loadType);
const endTime = performance.now(); const endTime = performance.now();