mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-06-13 04:05:04 +03:00
Add functionality to hide plugins from quick access menu (#468)
This commit is contained in:
+16
-4
@@ -122,10 +122,7 @@ class PluginBrowser:
|
|||||||
logger.debug("Plugin %s was stopped", name)
|
logger.debug("Plugin %s was stopped", name)
|
||||||
del self.plugins[name]
|
del self.plugins[name]
|
||||||
logger.debug("Plugin %s was removed from the dictionary", name)
|
logger.debug("Plugin %s was removed from the dictionary", name)
|
||||||
current_plugin_order = self.settings.getSetting("pluginOrder")
|
self.cleanup_plugin_settings(name)
|
||||||
current_plugin_order.remove(name)
|
|
||||||
self.settings.setSetting("pluginOrder", current_plugin_order)
|
|
||||||
logger.debug("Plugin %s was removed from the pluginOrder setting", name)
|
|
||||||
logger.debug("removing files %s" % str(name))
|
logger.debug("removing files %s" % str(name))
|
||||||
rmtree(plugin_dir)
|
rmtree(plugin_dir)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
@@ -234,3 +231,18 @@ class PluginBrowser:
|
|||||||
|
|
||||||
def cancel_plugin_install(self, request_id):
|
def cancel_plugin_install(self, request_id):
|
||||||
self.install_requests.pop(request_id)
|
self.install_requests.pop(request_id)
|
||||||
|
|
||||||
|
def cleanup_plugin_settings(self, name):
|
||||||
|
"""Removes any settings related to a plugin. Propably called when a plugin is uninstalled.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (string): The name of the plugin
|
||||||
|
"""
|
||||||
|
hidden_plugins = self.settings.getSetting("hiddenPlugins", [])
|
||||||
|
hidden_plugins.remove(name)
|
||||||
|
self.settings.setSetting("hiddenPlugins", hidden_plugins)
|
||||||
|
|
||||||
|
plugin_order = self.settings.getSetting("pluginOrder")
|
||||||
|
plugin_order.remove(name)
|
||||||
|
self.settings.setSetting("pluginOrder", plugin_order)
|
||||||
|
logger.debug("Removed any settings for plugin %s", name)
|
||||||
|
|||||||
@@ -17,6 +17,13 @@
|
|||||||
"select": "Use this folder"
|
"select": "Use this folder"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"PluginView": {
|
||||||
|
"hidden_one": "1 plugin is hidden from this list",
|
||||||
|
"hidden_other": "{{count}} plugins are hidden from this list"
|
||||||
|
},
|
||||||
|
"PluginListLabel": {
|
||||||
|
"hidden": "Hidden from the quick access menu"
|
||||||
|
},
|
||||||
"PluginCard": {
|
"PluginCard": {
|
||||||
"plugin_full_access": "This plugin has full access to your Steam Deck.",
|
"plugin_full_access": "This plugin has full access to your Steam Deck.",
|
||||||
"plugin_install": "Install",
|
"plugin_install": "Install",
|
||||||
@@ -73,6 +80,8 @@
|
|||||||
"reload": "Reload",
|
"reload": "Reload",
|
||||||
"uninstall": "Uninstall",
|
"uninstall": "Uninstall",
|
||||||
"update_to": "Update to {{name}}",
|
"update_to": "Update to {{name}}",
|
||||||
|
"show": "Quick access: Show",
|
||||||
|
"hide": "Quick access: Hide",
|
||||||
"update_all_one": "Update 1 plugin",
|
"update_all_one": "Update 1 plugin",
|
||||||
"update_all_other": "Update {{count}} plugins"
|
"update_all_other": "Update {{count}} plugins"
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ class SettingsManager:
|
|||||||
for file in listdir(wrong_dir):
|
for file in listdir(wrong_dir):
|
||||||
if file.endswith(".json"):
|
if file.endswith(".json"):
|
||||||
rename(path.join(wrong_dir,file),
|
rename(path.join(wrong_dir,file),
|
||||||
path.join(settings_directory, file))
|
path.join(settings_directory, file))
|
||||||
self.path = path.join(settings_directory, name + ".json")
|
self.path = path.join(settings_directory, name + ".json")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,3 +2,5 @@ node_modules/
|
|||||||
|
|
||||||
.yalc
|
.yalc
|
||||||
yalc.lock
|
yalc.lock
|
||||||
|
|
||||||
|
stats.html
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
"rollup-plugin-delete": "^2.0.0",
|
"rollup-plugin-delete": "^2.0.0",
|
||||||
"rollup-plugin-external-globals": "^0.6.1",
|
"rollup-plugin-external-globals": "^0.6.1",
|
||||||
"rollup-plugin-polyfill-node": "^0.10.2",
|
"rollup-plugin-polyfill-node": "^0.10.2",
|
||||||
|
"rollup-plugin-visualizer": "^5.9.0",
|
||||||
"tslib": "^2.5.2",
|
"tslib": "^2.5.2",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+94
@@ -93,6 +93,9 @@ devDependencies:
|
|||||||
rollup-plugin-polyfill-node:
|
rollup-plugin-polyfill-node:
|
||||||
specifier: ^0.10.2
|
specifier: ^0.10.2
|
||||||
version: 0.10.2(rollup@2.79.1)
|
version: 0.10.2(rollup@2.79.1)
|
||||||
|
rollup-plugin-visualizer:
|
||||||
|
specifier: ^5.9.0
|
||||||
|
version: 5.9.0(rollup@2.79.1)
|
||||||
tslib:
|
tslib:
|
||||||
specifier: ^2.5.2
|
specifier: ^2.5.2
|
||||||
version: 2.5.2
|
version: 2.5.2
|
||||||
@@ -1235,6 +1238,15 @@ packages:
|
|||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/cliui@8.0.1:
|
||||||
|
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
string-width: 4.2.3
|
||||||
|
strip-ansi: 6.0.1
|
||||||
|
wrap-ansi: 7.0.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/clone-buffer@1.0.0:
|
/clone-buffer@1.0.0:
|
||||||
resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==}
|
resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==}
|
||||||
engines: {node: '>= 0.10'}
|
engines: {node: '>= 0.10'}
|
||||||
@@ -1414,6 +1426,11 @@ packages:
|
|||||||
clone: 1.0.4
|
clone: 1.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/define-lazy-prop@2.0.0:
|
||||||
|
resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/define-properties@1.2.0:
|
/define-properties@1.2.0:
|
||||||
resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
|
resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -1770,6 +1787,11 @@ packages:
|
|||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/get-caller-file@2.0.5:
|
||||||
|
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
|
||||||
|
engines: {node: 6.* || 8.* || >= 10.*}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/get-intrinsic@1.2.1:
|
/get-intrinsic@1.2.1:
|
||||||
resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
|
resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2126,6 +2148,12 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/is-docker@2.2.1:
|
||||||
|
resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
hasBin: true
|
||||||
|
dev: true
|
||||||
|
|
||||||
/is-extglob@2.1.1:
|
/is-extglob@2.1.1:
|
||||||
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -2222,6 +2250,13 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/is-wsl@2.2.0:
|
||||||
|
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
is-docker: 2.2.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/isarray@1.0.0:
|
/isarray@1.0.0:
|
||||||
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -2891,6 +2926,15 @@ packages:
|
|||||||
mimic-fn: 2.1.0
|
mimic-fn: 2.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/open@8.4.2:
|
||||||
|
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
define-lazy-prop: 2.0.0
|
||||||
|
is-docker: 2.2.1
|
||||||
|
is-wsl: 2.2.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/ora@5.4.1:
|
/ora@5.4.1:
|
||||||
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
|
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -3237,6 +3281,11 @@ packages:
|
|||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/require-directory@2.1.1:
|
||||||
|
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/resolve-from@3.0.0:
|
/resolve-from@3.0.0:
|
||||||
resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==}
|
resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -3318,6 +3367,23 @@ packages:
|
|||||||
rollup: 2.79.1
|
rollup: 2.79.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/rollup-plugin-visualizer@5.9.0(rollup@2.79.1):
|
||||||
|
resolution: {integrity: sha512-bbDOv47+Bw4C/cgs0czZqfm8L82xOZssk4ayZjG40y9zbXclNk7YikrZTDao6p7+HDiGxrN0b65SgZiVm9k1Cg==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
rollup: 2.x || 3.x
|
||||||
|
peerDependenciesMeta:
|
||||||
|
rollup:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
open: 8.4.2
|
||||||
|
picomatch: 2.3.1
|
||||||
|
rollup: 2.79.1
|
||||||
|
source-map: 0.7.4
|
||||||
|
yargs: 17.7.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/rollup@2.79.1:
|
/rollup@2.79.1:
|
||||||
resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==}
|
resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==}
|
||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
@@ -3425,6 +3491,11 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/source-map@0.7.4:
|
||||||
|
resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/sourcemap-codec@1.4.8:
|
/sourcemap-codec@1.4.8:
|
||||||
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
||||||
deprecated: Please use @jridgewell/sourcemap-codec instead
|
deprecated: Please use @jridgewell/sourcemap-codec instead
|
||||||
@@ -3958,10 +4029,33 @@ packages:
|
|||||||
engines: {node: '>=0.4'}
|
engines: {node: '>=0.4'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/y18n@5.0.8:
|
||||||
|
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/yallist@3.1.1:
|
/yallist@3.1.1:
|
||||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/yargs-parser@21.1.1:
|
||||||
|
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/yargs@17.7.2:
|
||||||
|
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
cliui: 8.0.1
|
||||||
|
escalade: 3.1.1
|
||||||
|
get-caller-file: 2.0.5
|
||||||
|
require-directory: 2.1.1
|
||||||
|
string-width: 4.2.3
|
||||||
|
y18n: 5.0.8
|
||||||
|
yargs-parser: 21.1.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/zwitch@2.0.4:
|
/zwitch@2.0.4:
|
||||||
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import typescript from '@rollup/plugin-typescript';
|
|||||||
import { defineConfig } from 'rollup';
|
import { defineConfig } from 'rollup';
|
||||||
import del from 'rollup-plugin-delete';
|
import del from 'rollup-plugin-delete';
|
||||||
import externalGlobals from 'rollup-plugin-external-globals';
|
import externalGlobals from 'rollup-plugin-external-globals';
|
||||||
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
|
|
||||||
const hiddenWarnings = ['THIS_IS_UNDEFINED', 'EVAL'];
|
const hiddenWarnings = ['THIS_IS_UNDEFINED', 'EVAL'];
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ export default defineConfig({
|
|||||||
del({ targets: '../backend/static/*', force: true }),
|
del({ targets: '../backend/static/*', force: true }),
|
||||||
commonjs(),
|
commonjs(),
|
||||||
nodeResolve({
|
nodeResolve({
|
||||||
browser: true
|
browser: true,
|
||||||
}),
|
}),
|
||||||
externalGlobals({
|
externalGlobals({
|
||||||
react: 'SP_REACT',
|
react: 'SP_REACT',
|
||||||
@@ -33,6 +34,7 @@ export default defineConfig({
|
|||||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||||
}),
|
}),
|
||||||
image(),
|
image(),
|
||||||
|
visualizer(),
|
||||||
],
|
],
|
||||||
preserveEntrySignatures: false,
|
preserveEntrySignatures: false,
|
||||||
output: {
|
output: {
|
||||||
@@ -46,4 +48,4 @@ export default defineConfig({
|
|||||||
if (hiddenWarnings.some((warning) => message.code === warning)) return;
|
if (hiddenWarnings.some((warning) => message.code === warning)) return;
|
||||||
handleWarning(message);
|
handleWarning(message);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { VerInfo } from '../updater';
|
|||||||
interface PublicDeckyState {
|
interface PublicDeckyState {
|
||||||
plugins: Plugin[];
|
plugins: Plugin[];
|
||||||
pluginOrder: string[];
|
pluginOrder: string[];
|
||||||
|
hiddenPlugins: string[];
|
||||||
activePlugin: Plugin | null;
|
activePlugin: Plugin | null;
|
||||||
updates: PluginUpdateMapping | null;
|
updates: PluginUpdateMapping | null;
|
||||||
hasLoaderUpdate?: boolean;
|
hasLoaderUpdate?: boolean;
|
||||||
@@ -17,6 +18,7 @@ interface PublicDeckyState {
|
|||||||
export class DeckyState {
|
export class DeckyState {
|
||||||
private _plugins: Plugin[] = [];
|
private _plugins: Plugin[] = [];
|
||||||
private _pluginOrder: string[] = [];
|
private _pluginOrder: string[] = [];
|
||||||
|
private _hiddenPlugins: string[] = [];
|
||||||
private _activePlugin: Plugin | null = null;
|
private _activePlugin: Plugin | null = null;
|
||||||
private _updates: PluginUpdateMapping | null = null;
|
private _updates: PluginUpdateMapping | null = null;
|
||||||
private _hasLoaderUpdate: boolean = false;
|
private _hasLoaderUpdate: boolean = false;
|
||||||
@@ -29,6 +31,7 @@ export class DeckyState {
|
|||||||
return {
|
return {
|
||||||
plugins: this._plugins,
|
plugins: this._plugins,
|
||||||
pluginOrder: this._pluginOrder,
|
pluginOrder: this._pluginOrder,
|
||||||
|
hiddenPlugins: this._hiddenPlugins,
|
||||||
activePlugin: this._activePlugin,
|
activePlugin: this._activePlugin,
|
||||||
updates: this._updates,
|
updates: this._updates,
|
||||||
hasLoaderUpdate: this._hasLoaderUpdate,
|
hasLoaderUpdate: this._hasLoaderUpdate,
|
||||||
@@ -52,6 +55,11 @@ export class DeckyState {
|
|||||||
this.notifyUpdate();
|
this.notifyUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setHiddenPlugins(hiddenPlugins: string[]) {
|
||||||
|
this._hiddenPlugins = hiddenPlugins;
|
||||||
|
this.notifyUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
setActivePlugin(name: string) {
|
setActivePlugin(name: string) {
|
||||||
this._activePlugin = this._plugins.find((plugin) => plugin.name === name) ?? null;
|
this._activePlugin = this._plugins.find((plugin) => plugin.name === name) ?? null;
|
||||||
this.notifyUpdate();
|
this.notifyUpdate();
|
||||||
@@ -111,11 +119,11 @@ export const DeckyStateContextProvider: FC<Props> = ({ children, deckyState }) =
|
|||||||
return () => deckyState.eventBus.removeEventListener('update', onUpdate);
|
return () => deckyState.eventBus.removeEventListener('update', onUpdate);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const setIsLoaderUpdating = (hasUpdate: boolean) => deckyState.setIsLoaderUpdating(hasUpdate);
|
const setIsLoaderUpdating = deckyState.setIsLoaderUpdating.bind(deckyState);
|
||||||
const setVersionInfo = (versionInfo: VerInfo) => deckyState.setVersionInfo(versionInfo);
|
const setVersionInfo = deckyState.setVersionInfo.bind(deckyState);
|
||||||
const setActivePlugin = (name: string) => deckyState.setActivePlugin(name);
|
const setActivePlugin = deckyState.setActivePlugin.bind(deckyState);
|
||||||
const closeActivePlugin = () => deckyState.closeActivePlugin();
|
const closeActivePlugin = deckyState.closeActivePlugin.bind(deckyState);
|
||||||
const setPluginOrder = (pluginOrder: string[]) => deckyState.setPluginOrder(pluginOrder);
|
const setPluginOrder = deckyState.setPluginOrder.bind(deckyState);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DeckyStateContext.Provider
|
<DeckyStateContext.Provider
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import {
|
|||||||
staticClasses,
|
staticClasses,
|
||||||
} from 'decky-frontend-lib';
|
} from 'decky-frontend-lib';
|
||||||
import { VFC, useEffect, useState } from 'react';
|
import { VFC, useEffect, useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { FaEyeSlash } from 'react-icons/fa';
|
||||||
|
|
||||||
import { Plugin } from '../plugin';
|
import { Plugin } from '../plugin';
|
||||||
import { useDeckyState } from './DeckyState';
|
import { useDeckyState } from './DeckyState';
|
||||||
@@ -16,8 +18,10 @@ import { useQuickAccessVisible } from './QuickAccessVisibleState';
|
|||||||
import TitleView from './TitleView';
|
import TitleView from './TitleView';
|
||||||
|
|
||||||
const PluginView: VFC = () => {
|
const PluginView: VFC = () => {
|
||||||
|
const { hiddenPlugins } = useDeckyState();
|
||||||
const { plugins, updates, activePlugin, pluginOrder, setActivePlugin, closeActivePlugin } = useDeckyState();
|
const { plugins, updates, activePlugin, pluginOrder, setActivePlugin, closeActivePlugin } = useDeckyState();
|
||||||
const visible = useQuickAccessVisible();
|
const visible = useQuickAccessVisible();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [pluginList, setPluginList] = useState<Plugin[]>(
|
const [pluginList, setPluginList] = useState<Plugin[]>(
|
||||||
plugins.sort((a, b) => pluginOrder.indexOf(a.name) - pluginOrder.indexOf(b.name)),
|
plugins.sort((a, b) => pluginOrder.indexOf(a.name) - pluginOrder.indexOf(b.name)),
|
||||||
@@ -48,6 +52,7 @@ const PluginView: VFC = () => {
|
|||||||
<PanelSection>
|
<PanelSection>
|
||||||
{pluginList
|
{pluginList
|
||||||
.filter((p) => p.content)
|
.filter((p) => p.content)
|
||||||
|
.filter(({ name }) => !hiddenPlugins.includes(name))
|
||||||
.map(({ name, icon }) => (
|
.map(({ name, icon }) => (
|
||||||
<PanelSectionRow key={name}>
|
<PanelSectionRow key={name}>
|
||||||
<ButtonItem layout="below" onClick={() => setActivePlugin(name)}>
|
<ButtonItem layout="below" onClick={() => setActivePlugin(name)}>
|
||||||
@@ -59,6 +64,12 @@ const PluginView: VFC = () => {
|
|||||||
</ButtonItem>
|
</ButtonItem>
|
||||||
</PanelSectionRow>
|
</PanelSectionRow>
|
||||||
))}
|
))}
|
||||||
|
{hiddenPlugins.length > 0 && (
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', fontSize: '0.8rem', marginTop: '10px' }}>
|
||||||
|
<FaEyeSlash />
|
||||||
|
<div>{t('PluginView.hidden', { count: hiddenPlugins.length })}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</PanelSection>
|
</PanelSection>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { ConfirmModal } from 'decky-frontend-lib';
|
||||||
|
import { FC } from 'react';
|
||||||
|
|
||||||
|
interface PluginUninstallModalProps {
|
||||||
|
name: string;
|
||||||
|
title: string;
|
||||||
|
buttonText: string;
|
||||||
|
description: string;
|
||||||
|
closeModal?(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PluginUninstallModal: FC<PluginUninstallModalProps> = ({ name, title, buttonText, description, closeModal }) => {
|
||||||
|
return (
|
||||||
|
<ConfirmModal
|
||||||
|
closeModal={closeModal}
|
||||||
|
onOK={async () => {
|
||||||
|
await window.DeckyPluginLoader.callServerMethod('uninstall_plugin', { name });
|
||||||
|
// 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 window.DeckyPluginLoader.hiddenPluginsService.invalidate();
|
||||||
|
}}
|
||||||
|
strTitle={title}
|
||||||
|
strOKButtonText={buttonText}
|
||||||
|
>
|
||||||
|
{description}
|
||||||
|
</ConfirmModal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PluginUninstallModal;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { FaEyeSlash } from 'react-icons/fa';
|
||||||
|
|
||||||
|
interface PluginListLabelProps {
|
||||||
|
hidden: boolean;
|
||||||
|
name: string;
|
||||||
|
version?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PluginListLabel: FC<PluginListLabelProps> = ({ name, hidden, version }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
|
||||||
|
<div>{version ? `${name} - ${version}` : name}</div>
|
||||||
|
{hidden && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '0.8rem',
|
||||||
|
color: '#dcdedf',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '10px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FaEyeSlash />
|
||||||
|
{t('PluginListLabel.hidden')}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PluginListLabel;
|
||||||
@@ -22,10 +22,7 @@ import {
|
|||||||
} from '../../../../store';
|
} from '../../../../store';
|
||||||
import { useSetting } from '../../../../utils/hooks/useSetting';
|
import { useSetting } from '../../../../utils/hooks/useSetting';
|
||||||
import { useDeckyState } from '../../../DeckyState';
|
import { useDeckyState } from '../../../DeckyState';
|
||||||
|
import PluginListLabel from './PluginListLabel';
|
||||||
function labelToName(pluginLabel: string, pluginVersion?: string): string {
|
|
||||||
return pluginVersion ? pluginLabel.substring(0, pluginLabel.indexOf(` - ${pluginVersion}`)) : pluginLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function reinstallPlugin(pluginName: string, currentVersion?: string) {
|
async function reinstallPlugin(pluginName: string, currentVersion?: string) {
|
||||||
const serverData = await getPluginList();
|
const serverData = await getPluginList();
|
||||||
@@ -36,10 +33,17 @@ async function reinstallPlugin(pluginName: string, currentVersion?: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
|
type PluginTableData = PluginData & { name: string; hidden: boolean; onHide(): void; onShow(): void };
|
||||||
const data = props.entry.data;
|
|
||||||
|
function PluginInteractables(props: { entry: ReorderableEntry<PluginTableData> }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
let pluginName = labelToName(props.entry.label, data?.version);
|
|
||||||
|
// nothing to display without this data...
|
||||||
|
if (!props.entry.data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { name, update, version, onHide, onShow, hidden } = props.entry.data;
|
||||||
|
|
||||||
const showCtxMenu = (e: MouseEvent | GamepadEvent) => {
|
const showCtxMenu = (e: MouseEvent | GamepadEvent) => {
|
||||||
showContextMenu(
|
showContextMenu(
|
||||||
@@ -47,7 +51,7 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
onSelected={() => {
|
onSelected={() => {
|
||||||
try {
|
try {
|
||||||
fetch(`http://127.0.0.1:1337/plugins/${pluginName}/reload`, {
|
fetch(`http://127.0.0.1:1337/plugins/${name}/reload`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -58,7 +62,7 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
|
|||||||
console.error('Error Reloading Plugin Backend', err);
|
console.error('Error Reloading Plugin Backend', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.DeckyPluginLoader.importPlugin(pluginName, data?.version);
|
window.DeckyPluginLoader.importPlugin(name, version);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t('PluginListIndex.reload')}
|
{t('PluginListIndex.reload')}
|
||||||
@@ -66,15 +70,20 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
onSelected={() =>
|
onSelected={() =>
|
||||||
window.DeckyPluginLoader.uninstallPlugin(
|
window.DeckyPluginLoader.uninstallPlugin(
|
||||||
pluginName,
|
name,
|
||||||
t('PluginLoader.plugin_uninstall.title', { name: pluginName }),
|
t('PluginLoader.plugin_uninstall.title', { name }),
|
||||||
t('PluginLoader.plugin_uninstall.button'),
|
t('PluginLoader.plugin_uninstall.button'),
|
||||||
t('PluginLoader.plugin_uninstall.desc', { name: pluginName }),
|
t('PluginLoader.plugin_uninstall.desc', { name }),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{t('PluginListIndex.uninstall')}
|
{t('PluginListIndex.uninstall')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
{hidden ? (
|
||||||
|
<MenuItem onSelected={onShow}>{t('PluginListIndex.show')}</MenuItem>
|
||||||
|
) : (
|
||||||
|
<MenuItem onSelected={onHide}>{t('PluginListIndex.hide')}</MenuItem>
|
||||||
|
)}
|
||||||
</Menu>,
|
</Menu>,
|
||||||
e.currentTarget ?? window,
|
e.currentTarget ?? window,
|
||||||
);
|
);
|
||||||
@@ -82,22 +91,22 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{data?.update ? (
|
{update ? (
|
||||||
<DialogButton
|
<DialogButton
|
||||||
style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
|
style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
|
||||||
onClick={() => requestPluginInstall(pluginName, data?.update as StorePluginVersion, InstallType.UPDATE)}
|
onClick={() => requestPluginInstall(name, update, InstallType.UPDATE)}
|
||||||
onOKButton={() => requestPluginInstall(pluginName, data?.update as StorePluginVersion, InstallType.UPDATE)}
|
onOKButton={() => requestPluginInstall(name, update, InstallType.UPDATE)}
|
||||||
>
|
>
|
||||||
<div style={{ display: 'flex', minWidth: '180px', justifyContent: 'space-between', alignItems: 'center' }}>
|
<div style={{ display: 'flex', minWidth: '180px', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
{t('PluginListIndex.update_to', { name: data?.update?.name })}
|
{t('PluginListIndex.update_to', { name: update.name })}
|
||||||
<FaDownload style={{ paddingLeft: '1rem' }} />
|
<FaDownload style={{ paddingLeft: '1rem' }} />
|
||||||
</div>
|
</div>
|
||||||
</DialogButton>
|
</DialogButton>
|
||||||
) : (
|
) : (
|
||||||
<DialogButton
|
<DialogButton
|
||||||
style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
|
style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
|
||||||
onClick={() => reinstallPlugin(pluginName, data?.version)}
|
onClick={() => reinstallPlugin(name, version)}
|
||||||
onOKButton={() => reinstallPlugin(pluginName, data?.version)}
|
onOKButton={() => reinstallPlugin(name, version)}
|
||||||
>
|
>
|
||||||
<div style={{ display: 'flex', minWidth: '180px', justifyContent: 'space-between', alignItems: 'center' }}>
|
<div style={{ display: 'flex', minWidth: '180px', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
{t('PluginListIndex.reinstall')}
|
{t('PluginListIndex.reinstall')}
|
||||||
@@ -130,7 +139,7 @@ type PluginData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function PluginList() {
|
export default function PluginList() {
|
||||||
const { plugins, updates, pluginOrder, setPluginOrder } = useDeckyState();
|
const { plugins, updates, pluginOrder, setPluginOrder, hiddenPlugins } = useDeckyState();
|
||||||
const [_, setPluginOrderSetting] = useSetting<string[]>(
|
const [_, setPluginOrderSetting] = useSetting<string[]>(
|
||||||
'pluginOrder',
|
'pluginOrder',
|
||||||
plugins.map((plugin) => plugin.name),
|
plugins.map((plugin) => plugin.name),
|
||||||
@@ -141,22 +150,29 @@ export default function PluginList() {
|
|||||||
window.DeckyPluginLoader.checkPluginUpdates();
|
window.DeckyPluginLoader.checkPluginUpdates();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [pluginEntries, setPluginEntries] = useState<ReorderableEntry<PluginData>[]>([]);
|
const [pluginEntries, setPluginEntries] = useState<ReorderableEntry<PluginTableData>[]>([]);
|
||||||
|
const hiddenPluginsService = window.DeckyPluginLoader.hiddenPluginsService;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPluginEntries(
|
setPluginEntries(
|
||||||
plugins.map((plugin) => {
|
plugins.map(({ name, version }) => {
|
||||||
|
const hidden = hiddenPlugins.includes(name);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: plugin.version ? `${plugin.name} - ${plugin.version}` : plugin.name,
|
label: <PluginListLabel name={name} hidden={hidden} version={version} />,
|
||||||
|
position: pluginOrder.indexOf(name),
|
||||||
data: {
|
data: {
|
||||||
update: updates?.get(plugin.name),
|
name,
|
||||||
version: plugin.version,
|
hidden,
|
||||||
|
version,
|
||||||
|
update: updates?.get(name),
|
||||||
|
onHide: () => hiddenPluginsService.update([...hiddenPlugins, name]),
|
||||||
|
onShow: () => hiddenPluginsService.update(hiddenPlugins.filter((pluginName) => name !== pluginName)),
|
||||||
},
|
},
|
||||||
position: pluginOrder.indexOf(plugin.name),
|
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}, [plugins, updates]);
|
}, [plugins, updates, hiddenPlugins]);
|
||||||
|
|
||||||
if (plugins.length === 0) {
|
if (plugins.length === 0) {
|
||||||
return (
|
return (
|
||||||
@@ -166,8 +182,8 @@ export default function PluginList() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSave(entries: ReorderableEntry<PluginData>[]) {
|
function onSave(entries: ReorderableEntry<PluginTableData>[]) {
|
||||||
const newOrder = entries.map((entry) => labelToName(entry.label, entry?.data?.version));
|
const newOrder = entries.map((entry) => entry.data!.name);
|
||||||
console.log(newOrder);
|
console.log(newOrder);
|
||||||
setPluginOrder(newOrder);
|
setPluginOrder(newOrder);
|
||||||
setPluginOrderSetting(newOrder);
|
setPluginOrderSetting(newOrder);
|
||||||
@@ -200,7 +216,7 @@ export default function PluginList() {
|
|||||||
</DialogButton>
|
</DialogButton>
|
||||||
)}
|
)}
|
||||||
<DialogControlsSection style={{ marginTop: 0 }}>
|
<DialogControlsSection style={{ marginTop: 0 }}>
|
||||||
<ReorderableList<PluginData> entries={pluginEntries} onSave={onSave} interactables={PluginInteractables} />
|
<ReorderableList<PluginTableData> entries={pluginEntries} onSave={onSave} interactables={PluginInteractables} />
|
||||||
</DialogControlsSection>
|
</DialogControlsSection>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { DeckyState } from './components/DeckyState';
|
||||||
|
import { getSetting, setSetting } from './utils/settings';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Service class for managing the state and actions related to the hidden plugins feature
|
||||||
|
*
|
||||||
|
* It's mostly responsible for sending setting updates to the server and keeping the local state in sync.
|
||||||
|
*/
|
||||||
|
export class HiddenPluginsService {
|
||||||
|
constructor(private deckyState: DeckyState) {}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
getSetting<string[]>('hiddenPlugins', []).then((hiddenPlugins) => {
|
||||||
|
this.deckyState.setHiddenPlugins(hiddenPlugins);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the new hidden plugins list to the server and persists it locally in the decky state
|
||||||
|
*
|
||||||
|
* @param hiddenPlugins The new list of hidden plugins
|
||||||
|
*/
|
||||||
|
async update(hiddenPlugins: string[]) {
|
||||||
|
await setSetting('hiddenPlugins', hiddenPlugins);
|
||||||
|
this.deckyState.setHiddenPlugins(hiddenPlugins);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refreshes the state of hidden plugins in the local state
|
||||||
|
*/
|
||||||
|
async invalidate() {
|
||||||
|
this.deckyState.setHiddenPlugins(await getSetting('hiddenPlugins', []));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
ConfirmModal,
|
|
||||||
ModalRoot,
|
ModalRoot,
|
||||||
PanelSection,
|
PanelSection,
|
||||||
PanelSectionRow,
|
PanelSectionRow,
|
||||||
@@ -18,9 +17,11 @@ import LegacyPlugin from './components/LegacyPlugin';
|
|||||||
import { deinitFilepickerPatches, initFilepickerPatches } from './components/modals/filepicker/patches';
|
import { deinitFilepickerPatches, initFilepickerPatches } from './components/modals/filepicker/patches';
|
||||||
import MultiplePluginsInstallModal from './components/modals/MultiplePluginsInstallModal';
|
import MultiplePluginsInstallModal from './components/modals/MultiplePluginsInstallModal';
|
||||||
import PluginInstallModal from './components/modals/PluginInstallModal';
|
import PluginInstallModal from './components/modals/PluginInstallModal';
|
||||||
|
import PluginUninstallModal from './components/modals/PluginUninstallModal';
|
||||||
import NotificationBadge from './components/NotificationBadge';
|
import NotificationBadge from './components/NotificationBadge';
|
||||||
import PluginView from './components/PluginView';
|
import PluginView from './components/PluginView';
|
||||||
import WithSuspense from './components/WithSuspense';
|
import WithSuspense from './components/WithSuspense';
|
||||||
|
import { HiddenPluginsService } from './hidden-plugins-service';
|
||||||
import Logger from './logger';
|
import Logger from './logger';
|
||||||
import { InstallType, Plugin } from './plugin';
|
import { InstallType, Plugin } from './plugin';
|
||||||
import RouterHook from './router-hook';
|
import RouterHook from './router-hook';
|
||||||
@@ -45,6 +46,7 @@ class PluginLoader extends Logger {
|
|||||||
private routerHook: RouterHook = new RouterHook();
|
private routerHook: RouterHook = new RouterHook();
|
||||||
public toaster: Toaster = new Toaster();
|
public toaster: Toaster = new Toaster();
|
||||||
private deckyState: DeckyState = new DeckyState();
|
private deckyState: DeckyState = new DeckyState();
|
||||||
|
public hiddenPluginsService = new HiddenPluginsService(this.deckyState);
|
||||||
|
|
||||||
private reloadLock: boolean = false;
|
private reloadLock: boolean = false;
|
||||||
// stores a list of plugin names which requested to be reloaded
|
// stores a list of plugin names which requested to be reloaded
|
||||||
@@ -182,21 +184,8 @@ class PluginLoader extends Logger {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uninstallPlugin(name: string, title: string, button_text: string, description: string) {
|
public uninstallPlugin(name: string, title: string, buttonText: string, description: string) {
|
||||||
showModal(
|
showModal(<PluginUninstallModal name={name} title={title} buttonText={buttonText} description={description} />);
|
||||||
<ConfirmModal
|
|
||||||
onOK={async () => {
|
|
||||||
await this.callServerMethod('uninstall_plugin', { name });
|
|
||||||
}}
|
|
||||||
onCancel={() => {
|
|
||||||
// do nothing
|
|
||||||
}}
|
|
||||||
strTitle={title}
|
|
||||||
strOKButtonText={button_text}
|
|
||||||
>
|
|
||||||
{description}
|
|
||||||
</ConfirmModal>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasPlugin(name: string) {
|
public hasPlugin(name: string) {
|
||||||
@@ -220,6 +209,8 @@ class PluginLoader extends Logger {
|
|||||||
console.log(pluginOrder);
|
console.log(pluginOrder);
|
||||||
this.deckyState.setPluginOrder(pluginOrder);
|
this.deckyState.setPluginOrder(pluginOrder);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.hiddenPluginsService.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public deinit() {
|
public deinit() {
|
||||||
|
|||||||
Reference in New Issue
Block a user