From 0f36e87ccea0d9bf2a3db8ee858f27d9d1b2d796 Mon Sep 17 00:00:00 2001 From: Travis Lane <63308171+Tormak9970@users.noreply.github.com> Date: Mon, 3 Apr 2023 17:21:31 -0400 Subject: 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 --- .../settings/pages/plugin_list/index.tsx | 128 +++++++++++++-------- 1 file changed, 81 insertions(+), 47 deletions(-) (limited to 'frontend/src/components/settings') diff --git a/frontend/src/components/settings/pages/plugin_list/index.tsx b/frontend/src/components/settings/pages/plugin_list/index.tsx index 48894031..d9a85e9f 100644 --- a/frontend/src/components/settings/pages/plugin_list/index.tsx +++ b/frontend/src/components/settings/pages/plugin_list/index.tsx @@ -2,24 +2,93 @@ import { DialogBody, DialogButton, DialogControlsSection, - Focusable, + GamepadEvent, Menu, MenuItem, + ReorderableEntry, + ReorderableList, showContextMenu, } from 'decky-frontend-lib'; -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; 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'; +function PluginInteractables(props: { entry: ReorderableEntry }) { + const data = props.entry.data; + + const showCtxMenu = (e: MouseEvent | GamepadEvent) => { + showContextMenu( + + window.DeckyPluginLoader.importPlugin(props.entry.label, data?.version)}> + Reload + + window.DeckyPluginLoader.uninstallPlugin(props.entry.label)}>Uninstall + , + e.currentTarget ?? window, + ); + }; + + return ( + <> + {data?.update && ( + requestPluginInstall(props.entry.label, data?.update as StorePluginVersion)} + onOKButton={() => requestPluginInstall(props.entry.label, data?.update as StorePluginVersion)} + > +
+ Update to {data?.update?.name} + +
+
+ )} + + + + + ); +} + +type PluginData = { + update?: StorePluginVersion; + version?: string; +}; + export default function PluginList() { - const { plugins, updates } = useDeckyState(); + const { plugins, updates, pluginOrder, setPluginOrder } = useDeckyState(); + const [_, setPluginOrderSetting] = useSetting( + 'pluginOrder', + plugins.map((plugin) => plugin.name), + ); useEffect(() => { window.DeckyPluginLoader.checkPluginUpdates(); }, []); + const [pluginEntries, setPluginEntries] = useState[]>([]); + + 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) { return (
@@ -28,52 +97,17 @@ export default function PluginList() { ); } + function onSave(entries: ReorderableEntry[]) { + const newOrder = entries.map((entry) => entry.label); + console.log(newOrder); + setPluginOrder(newOrder); + setPluginOrderSetting(newOrder); + } + return ( -
    - {plugins.map(({ name, version }) => { - const update = updates?.get(name); - return ( -
  • - - {name} {'(' + version + ')'} - - - {update && ( - requestPluginInstall(name, update)} - > -
    - Update to {update.name} - -
    -
    - )} - - showContextMenu( - - window.DeckyPluginLoader.importPlugin(name, version)}> - Reload - - window.DeckyPluginLoader.uninstallPlugin(name)}> - Uninstall - - , - e.currentTarget ?? window, - ) - } - > - - -
    -
  • - ); - })} -
+ entries={pluginEntries} onSave={onSave} interactables={PluginInteractables} />
); -- cgit v1.2.3