diff --git a/frontend/package.json b/frontend/package.json index 842ec869..20c906f7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -47,7 +47,7 @@ } }, "dependencies": { - "@decky/ui": "^4.8.3", + "@decky/ui": "^4.9.0", "compare-versions": "^6.1.1", "filesize": "^10.1.2", "i18next": "^23.11.5", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 73e1c7bd..16a1fab7 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@decky/ui': - specifier: ^4.8.3 - version: 4.8.3 + specifier: ^4.9.0 + version: 4.9.0 compare-versions: specifier: ^6.1.1 version: 6.1.1 @@ -218,8 +218,8 @@ packages: '@decky/api@1.1.1': resolution: {integrity: sha512-R5fkBRHBt5QIQY7Q0AlbVIhlIZ/nTzwBOoi8Rt4Go2fjFnoMKPInCJl6cPjXzimGwl2pyqKJgY6VnH6ar0XrHQ==} - '@decky/ui@4.8.3': - resolution: {integrity: sha512-Y1KciazgvKqMEVBGrWFCTGOqgVi5sHbcQNoCZRMbPpcI0U3j7udl6mkfe/NBa16oRDZ03ljS41SmrAgKAAt/pA==} + '@decky/ui@4.9.0': + resolution: {integrity: sha512-5iN8UciEpL4WHPdUr4Nzl4/y3CBnLfUN+/1q+WeMUNOzPJICLiwlltfBbyZyMM/ST3nPrDYCLbZCYD9jKWFLXQ==} '@esbuild/aix-ppc64@0.20.2': resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} @@ -2295,7 +2295,7 @@ snapshots: '@decky/api@1.1.1': {} - '@decky/ui@4.8.3': {} + '@decky/ui@4.9.0': {} '@esbuild/aix-ppc64@0.20.2': optional: true diff --git a/frontend/src/components/PluginView.tsx b/frontend/src/components/PluginView.tsx index 1d39972e..ea35bb5f 100644 --- a/frontend/src/components/PluginView.tsx +++ b/frontend/src/components/PluginView.tsx @@ -25,7 +25,12 @@ const PluginView: FC = () => { if (activePlugin) { return ( - +
{(visible || activePlugin.alwaysRender) && activePlugin.content} diff --git a/frontend/src/components/TitleView.tsx b/frontend/src/components/TitleView.tsx index 0cb82b7f..a9408fef 100644 --- a/frontend/src/components/TitleView.tsx +++ b/frontend/src/components/TitleView.tsx @@ -58,7 +58,7 @@ const TitleView: FC = () => { > - {activePlugin?.titleView ||
{activePlugin.name}
} + {activePlugin.titleView ||
{activePlugin.name}
} ); }; diff --git a/frontend/src/components/settings/pages/plugin_list/PluginListLabel.tsx b/frontend/src/components/settings/pages/plugin_list/PluginListLabel.tsx index fec03e56..ee98eb6a 100644 --- a/frontend/src/components/settings/pages/plugin_list/PluginListLabel.tsx +++ b/frontend/src/components/settings/pages/plugin_list/PluginListLabel.tsx @@ -2,18 +2,27 @@ import { FC } from 'react'; import { useTranslation } from 'react-i18next'; import { FaEyeSlash, FaLock } from 'react-icons/fa'; +import { StorePluginVersion } from '../../../../store'; +import NotificationBadge from '../../../NotificationBadge'; + interface PluginListLabelProps { frozen: boolean; hidden: boolean; name: string; version?: string; + update: StorePluginVersion | undefined; } -const PluginListLabel: FC = ({ name, frozen, hidden, version }) => { +const PluginListLabel: FC = ({ name, frozen, hidden, version, update }) => { const { t } = useTranslation(); return (
-
+
{name} {version && ( <> @@ -28,6 +37,7 @@ const PluginListLabel: FC = ({ name, frozen, hidden, versi )} +
{hidden && (
('loader/reload_plugin'); +const squareButtonStyle: CSSProperties = { + height: '40px', + width: '40px', + minWidth: '40px', + padding: '0', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', +}; + function PluginInteractables(props: { entry: ReorderableEntry }) { const { t } = useTranslation(); @@ -54,7 +70,8 @@ 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, onOpen } = + props.entry.data; const showCtxMenu = (e: MouseEvent | GamepadEvent) => { showContextMenu( @@ -70,6 +87,7 @@ function PluginInteractables(props: { entry: ReorderableEntry } > {t('PluginListIndex.reload')} + reinstallPlugin(name, version)}>{t('PluginListIndex.reinstall')} DeckyPluginLoader.uninstallPlugin( @@ -82,6 +100,9 @@ function PluginInteractables(props: { entry: ReorderableEntry } > {t('PluginListIndex.uninstall')} + + + {hidden ? ( {t('PluginListIndex.show')} ) : ( @@ -98,46 +119,34 @@ function PluginInteractables(props: { entry: ReorderableEntry } }; return ( - <> +
{update ? ( requestPluginInstall(name, update, InstallType.UPDATE)} onOKButton={() => requestPluginInstall(name, update, InstallType.UPDATE)} > -
- {t('PluginListIndex.update_to', { name: update.name })} - -
+ {t('PluginListIndex.update_to', { name: update.name })}
- ) : ( - reinstallPlugin(name, version)} - onOKButton={() => reinstallPlugin(name, version)} - > -
- {t('PluginListIndex.reinstall')} - -
-
- )} - + ) : null} + + + + - +
); } @@ -147,7 +156,8 @@ type PluginData = { }; export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) { - const { plugins, updates, pluginOrder, setPluginOrder, frozenPlugins, hiddenPlugins } = useDeckyState(); + const { plugins, updates, pluginOrder, setPluginOrder, frozenPlugins, hiddenPlugins, setActivePlugin } = + useDeckyState(); const [_, setPluginOrderSetting] = useSetting( 'pluginOrder', plugins.map((plugin) => plugin.name), @@ -158,18 +168,19 @@ export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) { DeckyPluginLoader.checkPluginUpdates(); }, []); - const [pluginEntries, setPluginEntries] = useState[]>([]); - const hiddenPluginsService = DeckyPluginLoader.hiddenPluginsService; - const frozenPluginsService = DeckyPluginLoader.frozenPluginsService; - - useEffect(() => { - setPluginEntries( + const pluginEntries = useMemo( + () => plugins.map(({ name, version }) => { + const hiddenPluginsService = DeckyPluginLoader.hiddenPluginsService; + const frozenPluginsService = DeckyPluginLoader.frozenPluginsService; + const frozen = frozenPlugins.includes(name); const hidden = hiddenPlugins.includes(name); + const update = updates?.get(name); + return { - label: