mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-07-11 15:41:58 +00:00
Add plugin reordering (#378)
* feat: started work on saving plugin order * feat: implemented local ReorderableList * feat: reoder complete except for usage of DFL * switched to using dfl reorderableList * fix: added missing file and removed frag * updated to newest dfl * Update defsettings.json * fix: plugin order was missing on init * fix: now await pluginOrder * fix: moved the plugin-order load to plugin-loader * chore: v6 and dfl bump
This commit is contained in:
Vendored
+1
-1
@@ -4,4 +4,4 @@
|
|||||||
"deckpass" : "ssap",
|
"deckpass" : "ssap",
|
||||||
"deckkey" : "-i ${env:HOME}/.ssh/id_rsa",
|
"deckkey" : "-i ${env:HOME}/.ssh/id_rsa",
|
||||||
"deckdir" : "/home/deck"
|
"deckdir" : "/home/deck"
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -30,10 +30,11 @@ class PluginInstallContext:
|
|||||||
self.hash = hash
|
self.hash = hash
|
||||||
|
|
||||||
class PluginBrowser:
|
class PluginBrowser:
|
||||||
def __init__(self, plugin_path, plugins, loader) -> None:
|
def __init__(self, plugin_path, plugins, loader, settings) -> None:
|
||||||
self.plugin_path = plugin_path
|
self.plugin_path = plugin_path
|
||||||
self.plugins = plugins
|
self.plugins = plugins
|
||||||
self.loader = loader
|
self.loader = loader
|
||||||
|
self.settings = settings
|
||||||
self.install_requests = {}
|
self.install_requests = {}
|
||||||
|
|
||||||
def _unzip_to_plugin_dir(self, zip, name, hash):
|
def _unzip_to_plugin_dir(self, zip, name, hash):
|
||||||
@@ -123,6 +124,10 @@ 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")
|
||||||
|
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:
|
||||||
@@ -170,6 +175,11 @@ class PluginBrowser:
|
|||||||
self.loader.plugins[name].stop()
|
self.loader.plugins[name].stop()
|
||||||
self.loader.plugins.pop(name, None)
|
self.loader.plugins.pop(name, None)
|
||||||
await sleep(1)
|
await sleep(1)
|
||||||
|
|
||||||
|
current_plugin_order = self.settings.getSetting("pluginOrder")
|
||||||
|
current_plugin_order.append(name)
|
||||||
|
self.settings.setSetting("pluginOrder", current_plugin_order)
|
||||||
|
logger.debug("Plugin %s was added to the pluginOrder setting", name)
|
||||||
self.loader.import_plugin(path.join(plugin_dir, "main.py"), plugin_folder)
|
self.loader.import_plugin(path.join(plugin_dir, "main.py"), plugin_folder)
|
||||||
else:
|
else:
|
||||||
logger.fatal(f"Failed Downloading Remote Binaries")
|
logger.fatal(f"Failed Downloading Remote Binaries")
|
||||||
|
|||||||
+4
-1
@@ -71,8 +71,8 @@ class PluginManager:
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
self.plugin_loader = Loader(self.web_app, CONFIG["plugin_path"], self.loop, CONFIG["live_reload"])
|
self.plugin_loader = Loader(self.web_app, CONFIG["plugin_path"], self.loop, CONFIG["live_reload"])
|
||||||
self.plugin_browser = PluginBrowser(CONFIG["plugin_path"], self.plugin_loader.plugins, self.plugin_loader)
|
|
||||||
self.settings = SettingsManager("loader", path.join(HOMEBREW_PATH, "settings"))
|
self.settings = SettingsManager("loader", path.join(HOMEBREW_PATH, "settings"))
|
||||||
|
self.plugin_browser = PluginBrowser(CONFIG["plugin_path"], self.plugin_loader.plugins, self.plugin_loader, self.settings)
|
||||||
self.utilities = Utilities(self)
|
self.utilities = Utilities(self)
|
||||||
self.updater = Updater(self)
|
self.updater = Updater(self)
|
||||||
|
|
||||||
@@ -109,6 +109,9 @@ class PluginManager:
|
|||||||
logger.debug("Loading plugins")
|
logger.debug("Loading plugins")
|
||||||
self.plugin_loader.import_plugins()
|
self.plugin_loader.import_plugins()
|
||||||
# await inject_to_tab("SP", "window.syncDeckyPlugins();")
|
# await inject_to_tab("SP", "window.syncDeckyPlugins();")
|
||||||
|
if self.settings.getSetting("pluginOrder", None) == None:
|
||||||
|
self.settings.setSetting("pluginOrder", list(self.plugin_loader.plugins.keys()))
|
||||||
|
logger.debug("Did not find pluginOrder setting, set it to default")
|
||||||
|
|
||||||
async def loader_reinjector(self):
|
async def loader_reinjector(self):
|
||||||
while True:
|
while True:
|
||||||
|
|||||||
+13
-13
@@ -12,28 +12,28 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^21.1.0",
|
"@rollup/plugin-commonjs": "^21.1.0",
|
||||||
"@rollup/plugin-image": "^3.0.1",
|
"@rollup/plugin-image": "^3.0.2",
|
||||||
"@rollup/plugin-json": "^4.1.0",
|
"@rollup/plugin-json": "^4.1.0",
|
||||||
"@rollup/plugin-node-resolve": "^13.3.0",
|
"@rollup/plugin-node-resolve": "^13.3.0",
|
||||||
"@rollup/plugin-replace": "^4.0.0",
|
"@rollup/plugin-replace": "^4.0.0",
|
||||||
"@rollup/plugin-typescript": "^8.3.3",
|
"@rollup/plugin-typescript": "^8.5.0",
|
||||||
"@types/react": "16.14.0",
|
"@types/react": "16.14.0",
|
||||||
"@types/react-file-icon": "^1.0.1",
|
"@types/react-file-icon": "^1.0.1",
|
||||||
"@types/react-router": "5.1.18",
|
"@types/react-router": "5.1.18",
|
||||||
"@types/webpack": "^5.28.0",
|
"@types/webpack": "^5.28.1",
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.3",
|
||||||
"import-sort-style-module": "^6.0.0",
|
"import-sort-style-module": "^6.0.0",
|
||||||
"inquirer": "^8.2.4",
|
"inquirer": "^8.2.5",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.7",
|
||||||
"prettier-plugin-import-sort": "^0.0.7",
|
"prettier-plugin-import-sort": "^0.0.7",
|
||||||
"react": "16.14.0",
|
"react": "16.14.0",
|
||||||
"react-dom": "16.14.0",
|
"react-dom": "16.14.0",
|
||||||
"rollup": "^2.76.0",
|
"rollup": "^2.79.1",
|
||||||
"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",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.5.0",
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"importSort": {
|
"importSort": {
|
||||||
".js, .jsx, .ts, .tsx": {
|
".js, .jsx, .ts, .tsx": {
|
||||||
@@ -42,10 +42,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"decky-frontend-lib": "^3.19.1",
|
"decky-frontend-lib": "^3.20.0",
|
||||||
"react-file-icon": "^1.2.0",
|
"react-file-icon": "^1.3.0",
|
||||||
"react-icons": "^4.4.0",
|
"react-icons": "^4.8.0",
|
||||||
"react-markdown": "^8.0.3",
|
"react-markdown": "^8.0.6",
|
||||||
"remark-gfm": "^3.0.1"
|
"remark-gfm": "^3.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+772
-736
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@ import { VerInfo } from '../updater';
|
|||||||
|
|
||||||
interface PublicDeckyState {
|
interface PublicDeckyState {
|
||||||
plugins: Plugin[];
|
plugins: Plugin[];
|
||||||
|
pluginOrder: string[];
|
||||||
activePlugin: Plugin | null;
|
activePlugin: Plugin | null;
|
||||||
updates: PluginUpdateMapping | null;
|
updates: PluginUpdateMapping | null;
|
||||||
hasLoaderUpdate?: boolean;
|
hasLoaderUpdate?: boolean;
|
||||||
@@ -15,6 +16,7 @@ interface PublicDeckyState {
|
|||||||
|
|
||||||
export class DeckyState {
|
export class DeckyState {
|
||||||
private _plugins: Plugin[] = [];
|
private _plugins: Plugin[] = [];
|
||||||
|
private _pluginOrder: 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;
|
||||||
@@ -26,6 +28,7 @@ export class DeckyState {
|
|||||||
publicState(): PublicDeckyState {
|
publicState(): PublicDeckyState {
|
||||||
return {
|
return {
|
||||||
plugins: this._plugins,
|
plugins: this._plugins,
|
||||||
|
pluginOrder: this._pluginOrder,
|
||||||
activePlugin: this._activePlugin,
|
activePlugin: this._activePlugin,
|
||||||
updates: this._updates,
|
updates: this._updates,
|
||||||
hasLoaderUpdate: this._hasLoaderUpdate,
|
hasLoaderUpdate: this._hasLoaderUpdate,
|
||||||
@@ -44,6 +47,11 @@ export class DeckyState {
|
|||||||
this.notifyUpdate();
|
this.notifyUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPluginOrder(pluginOrder: string[]) {
|
||||||
|
this._pluginOrder = pluginOrder;
|
||||||
|
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();
|
||||||
@@ -78,6 +86,7 @@ interface DeckyStateContext extends PublicDeckyState {
|
|||||||
setVersionInfo(versionInfo: VerInfo): void;
|
setVersionInfo(versionInfo: VerInfo): void;
|
||||||
setIsLoaderUpdating(hasUpdate: boolean): void;
|
setIsLoaderUpdating(hasUpdate: boolean): void;
|
||||||
setActivePlugin(name: string): void;
|
setActivePlugin(name: string): void;
|
||||||
|
setPluginOrder(pluginOrder: string[]): void;
|
||||||
closeActivePlugin(): void;
|
closeActivePlugin(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,10 +115,18 @@ export const DeckyStateContextProvider: FC<Props> = ({ children, deckyState }) =
|
|||||||
const setVersionInfo = (versionInfo: VerInfo) => deckyState.setVersionInfo(versionInfo);
|
const setVersionInfo = (versionInfo: VerInfo) => deckyState.setVersionInfo(versionInfo);
|
||||||
const setActivePlugin = (name: string) => deckyState.setActivePlugin(name);
|
const setActivePlugin = (name: string) => deckyState.setActivePlugin(name);
|
||||||
const closeActivePlugin = () => deckyState.closeActivePlugin();
|
const closeActivePlugin = () => deckyState.closeActivePlugin();
|
||||||
|
const setPluginOrder = (pluginOrder: string[]) => deckyState.setPluginOrder(pluginOrder);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DeckyStateContext.Provider
|
<DeckyStateContext.Provider
|
||||||
value={{ ...publicDeckyState, setIsLoaderUpdating, setVersionInfo, setActivePlugin, closeActivePlugin }}
|
value={{
|
||||||
|
...publicDeckyState,
|
||||||
|
setIsLoaderUpdating,
|
||||||
|
setVersionInfo,
|
||||||
|
setActivePlugin,
|
||||||
|
closeActivePlugin,
|
||||||
|
setPluginOrder,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</DeckyStateContext.Provider>
|
</DeckyStateContext.Provider>
|
||||||
|
|||||||
@@ -7,17 +7,27 @@ import {
|
|||||||
scrollClasses,
|
scrollClasses,
|
||||||
staticClasses,
|
staticClasses,
|
||||||
} from 'decky-frontend-lib';
|
} from 'decky-frontend-lib';
|
||||||
import { VFC } from 'react';
|
import { VFC, useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { Plugin } from '../plugin';
|
||||||
import { useDeckyState } from './DeckyState';
|
import { useDeckyState } from './DeckyState';
|
||||||
import NotificationBadge from './NotificationBadge';
|
import NotificationBadge from './NotificationBadge';
|
||||||
import { useQuickAccessVisible } from './QuickAccessVisibleState';
|
import { useQuickAccessVisible } from './QuickAccessVisibleState';
|
||||||
import TitleView from './TitleView';
|
import TitleView from './TitleView';
|
||||||
|
|
||||||
const PluginView: VFC = () => {
|
const PluginView: VFC = () => {
|
||||||
const { plugins, updates, activePlugin, setActivePlugin, closeActivePlugin } = useDeckyState();
|
const { plugins, updates, activePlugin, pluginOrder, setActivePlugin, closeActivePlugin } = useDeckyState();
|
||||||
const visible = useQuickAccessVisible();
|
const visible = useQuickAccessVisible();
|
||||||
|
|
||||||
|
const [pluginList, setPluginList] = useState<Plugin[]>(
|
||||||
|
plugins.sort((a, b) => pluginOrder.indexOf(a.name) - pluginOrder.indexOf(b.name)),
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setPluginList(plugins.sort((a, b) => pluginOrder.indexOf(a.name) - pluginOrder.indexOf(b.name)));
|
||||||
|
console.log('updating PluginView after changes');
|
||||||
|
}, [plugins, pluginOrder]);
|
||||||
|
|
||||||
if (activePlugin) {
|
if (activePlugin) {
|
||||||
return (
|
return (
|
||||||
<Focusable onCancelButton={closeActivePlugin}>
|
<Focusable onCancelButton={closeActivePlugin}>
|
||||||
@@ -36,7 +46,7 @@ const PluginView: VFC = () => {
|
|||||||
<TitleView />
|
<TitleView />
|
||||||
<div className={joinClassNames(staticClasses.TabGroupPanel, scrollClasses.ScrollPanel, scrollClasses.ScrollY)}>
|
<div className={joinClassNames(staticClasses.TabGroupPanel, scrollClasses.ScrollPanel, scrollClasses.ScrollY)}>
|
||||||
<PanelSection>
|
<PanelSection>
|
||||||
{plugins
|
{pluginList
|
||||||
.filter((p) => p.content)
|
.filter((p) => p.content)
|
||||||
.map(({ name, icon }) => (
|
.map(({ name, icon }) => (
|
||||||
<PanelSectionRow key={name}>
|
<PanelSectionRow key={name}>
|
||||||
|
|||||||
@@ -2,24 +2,93 @@ import {
|
|||||||
DialogBody,
|
DialogBody,
|
||||||
DialogButton,
|
DialogButton,
|
||||||
DialogControlsSection,
|
DialogControlsSection,
|
||||||
Focusable,
|
GamepadEvent,
|
||||||
Menu,
|
Menu,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
|
ReorderableEntry,
|
||||||
|
ReorderableList,
|
||||||
showContextMenu,
|
showContextMenu,
|
||||||
} from 'decky-frontend-lib';
|
} from 'decky-frontend-lib';
|
||||||
import { useEffect } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { FaDownload, FaEllipsisH } from 'react-icons/fa';
|
import { FaDownload, FaEllipsisH } from 'react-icons/fa';
|
||||||
|
|
||||||
import { requestPluginInstall } from '../../../../store';
|
import { StorePluginVersion, requestPluginInstall } from '../../../../store';
|
||||||
|
import { useSetting } from '../../../../utils/hooks/useSetting';
|
||||||
import { useDeckyState } from '../../../DeckyState';
|
import { useDeckyState } from '../../../DeckyState';
|
||||||
|
|
||||||
|
function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
|
||||||
|
const data = props.entry.data;
|
||||||
|
|
||||||
|
const showCtxMenu = (e: MouseEvent | GamepadEvent) => {
|
||||||
|
showContextMenu(
|
||||||
|
<Menu label="Plugin Actions">
|
||||||
|
<MenuItem onSelected={() => window.DeckyPluginLoader.importPlugin(props.entry.label, data?.version)}>
|
||||||
|
Reload
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem onSelected={() => window.DeckyPluginLoader.uninstallPlugin(props.entry.label)}>Uninstall</MenuItem>
|
||||||
|
</Menu>,
|
||||||
|
e.currentTarget ?? window,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{data?.update && (
|
||||||
|
<DialogButton
|
||||||
|
style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
|
||||||
|
onClick={() => requestPluginInstall(props.entry.label, data?.update as StorePluginVersion)}
|
||||||
|
onOKButton={() => requestPluginInstall(props.entry.label, data?.update as StorePluginVersion)}
|
||||||
|
>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
|
Update to {data?.update?.name}
|
||||||
|
<FaDownload style={{ paddingLeft: '2rem' }} />
|
||||||
|
</div>
|
||||||
|
</DialogButton>
|
||||||
|
)}
|
||||||
|
<DialogButton
|
||||||
|
style={{ height: '40px', width: '40px', padding: '10px 12px', minWidth: '40px' }}
|
||||||
|
onClick={showCtxMenu}
|
||||||
|
onOKButton={showCtxMenu}
|
||||||
|
>
|
||||||
|
<FaEllipsisH />
|
||||||
|
</DialogButton>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginData = {
|
||||||
|
update?: StorePluginVersion;
|
||||||
|
version?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export default function PluginList() {
|
export default function PluginList() {
|
||||||
const { plugins, updates } = useDeckyState();
|
const { plugins, updates, pluginOrder, setPluginOrder } = useDeckyState();
|
||||||
|
const [_, setPluginOrderSetting] = useSetting<string[]>(
|
||||||
|
'pluginOrder',
|
||||||
|
plugins.map((plugin) => plugin.name),
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.DeckyPluginLoader.checkPluginUpdates();
|
window.DeckyPluginLoader.checkPluginUpdates();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const [pluginEntries, setPluginEntries] = useState<ReorderableEntry<PluginData>[]>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setPluginEntries(
|
||||||
|
plugins.map((plugin) => {
|
||||||
|
return {
|
||||||
|
label: plugin.name,
|
||||||
|
data: {
|
||||||
|
update: updates?.get(plugin.name),
|
||||||
|
version: plugin.version,
|
||||||
|
},
|
||||||
|
position: pluginOrder.indexOf(plugin.name),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}, [plugins, updates]);
|
||||||
|
|
||||||
if (plugins.length === 0) {
|
if (plugins.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -28,52 +97,17 @@ export default function PluginList() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onSave(entries: ReorderableEntry<PluginData>[]) {
|
||||||
|
const newOrder = entries.map((entry) => entry.label);
|
||||||
|
console.log(newOrder);
|
||||||
|
setPluginOrder(newOrder);
|
||||||
|
setPluginOrderSetting(newOrder);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogBody>
|
<DialogBody>
|
||||||
<DialogControlsSection>
|
<DialogControlsSection>
|
||||||
<ul style={{ listStyleType: 'none', padding: '0' }}>
|
<ReorderableList<PluginData> entries={pluginEntries} onSave={onSave} interactables={PluginInteractables} />
|
||||||
{plugins.map(({ name, version }) => {
|
|
||||||
const update = updates?.get(name);
|
|
||||||
return (
|
|
||||||
<li style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', paddingBottom: '10px' }}>
|
|
||||||
<span>
|
|
||||||
{name} <span style={{ opacity: '50%' }}>{'(' + version + ')'}</span>
|
|
||||||
</span>
|
|
||||||
<Focusable style={{ marginLeft: 'auto', boxShadow: 'none', display: 'flex', justifyContent: 'right' }}>
|
|
||||||
{update && (
|
|
||||||
<DialogButton
|
|
||||||
style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
|
|
||||||
onClick={() => requestPluginInstall(name, update)}
|
|
||||||
>
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
|
||||||
Update to {update.name}
|
|
||||||
<FaDownload style={{ paddingLeft: '2rem' }} />
|
|
||||||
</div>
|
|
||||||
</DialogButton>
|
|
||||||
)}
|
|
||||||
<DialogButton
|
|
||||||
style={{ height: '40px', width: '40px', padding: '10px 12px', minWidth: '40px' }}
|
|
||||||
onClick={(e: MouseEvent) =>
|
|
||||||
showContextMenu(
|
|
||||||
<Menu label="Plugin Actions">
|
|
||||||
<MenuItem onSelected={() => window.DeckyPluginLoader.importPlugin(name, version)}>
|
|
||||||
Reload
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem onSelected={() => window.DeckyPluginLoader.uninstallPlugin(name)}>
|
|
||||||
Uninstall
|
|
||||||
</MenuItem>
|
|
||||||
</Menu>,
|
|
||||||
e.currentTarget ?? window,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<FaEllipsisH />
|
|
||||||
</DialogButton>
|
|
||||||
</Focusable>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
</DialogControlsSection>
|
</DialogControlsSection>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ declare global {
|
|||||||
if (!window.DeckyPluginLoader.hasPlugin(plugin.name))
|
if (!window.DeckyPluginLoader.hasPlugin(plugin.name))
|
||||||
window.DeckyPluginLoader?.importPlugin(plugin.name, plugin.version);
|
window.DeckyPluginLoader?.importPlugin(plugin.name, plugin.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.DeckyPluginLoader.checkPluginUpdates();
|
window.DeckyPluginLoader.checkPluginUpdates();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,12 @@ class PluginLoader extends Logger {
|
|||||||
getSetting('developer.enabled', false).then((val) => {
|
getSetting('developer.enabled', false).then((val) => {
|
||||||
if (val) import('./developer').then((developer) => developer.startup());
|
if (val) import('./developer').then((developer) => developer.startup());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//* Grab and set plugin order
|
||||||
|
getSetting<string[]>('pluginOrder', []).then((pluginOrder) => {
|
||||||
|
console.log(pluginOrder);
|
||||||
|
this.deckyState.setPluginOrder(pluginOrder);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public deinit() {
|
public deinit() {
|
||||||
|
|||||||
Reference in New Issue
Block a user