mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-10-03 10:29:35 +00:00
Add sort plugins setting (#859)
This commit is contained in:
@@ -217,6 +217,9 @@
|
||||
"developer_mode": {
|
||||
"label": "Developer mode"
|
||||
},
|
||||
"sort_plugins": {
|
||||
"label": "Sort plugins alphabetically"
|
||||
},
|
||||
"notifications": {
|
||||
"decky_updates_label": "Decky update available",
|
||||
"header": "Notifications",
|
||||
|
||||
@@ -10,6 +10,7 @@ interface PublicDeckyState {
|
||||
disabledPlugins: DisabledPlugin[];
|
||||
installedPlugins: (Plugin | DisabledPlugin)[];
|
||||
pluginOrder: string[];
|
||||
sortPlugins: boolean;
|
||||
frozenPlugins: string[];
|
||||
hiddenPlugins: string[];
|
||||
activePlugin: Plugin | null;
|
||||
@@ -31,6 +32,7 @@ export class DeckyState {
|
||||
private _disabledPlugins: DisabledPlugin[] = [];
|
||||
private _installedPlugins: (Plugin | DisabledPlugin)[] = [];
|
||||
private _pluginOrder: string[] = [];
|
||||
private _sortPlugins: boolean = false;
|
||||
private _frozenPlugins: string[] = [];
|
||||
private _hiddenPlugins: string[] = [];
|
||||
private _activePlugin: Plugin | null = null;
|
||||
@@ -49,6 +51,7 @@ export class DeckyState {
|
||||
disabledPlugins: this._disabledPlugins,
|
||||
installedPlugins: this._installedPlugins,
|
||||
pluginOrder: this._pluginOrder,
|
||||
sortPlugins: this._sortPlugins,
|
||||
frozenPlugins: this._frozenPlugins,
|
||||
hiddenPlugins: this._hiddenPlugins,
|
||||
activePlugin: this._activePlugin,
|
||||
@@ -83,6 +86,11 @@ export class DeckyState {
|
||||
this.notifyUpdate();
|
||||
}
|
||||
|
||||
setSortPlugins(sortPlugins: boolean) {
|
||||
this._sortPlugins = sortPlugins;
|
||||
this.notifyUpdate();
|
||||
}
|
||||
|
||||
setFrozenPlugins(frozenPlugins: string[]) {
|
||||
this._frozenPlugins = frozenPlugins;
|
||||
this.notifyUpdate();
|
||||
@@ -139,6 +147,7 @@ interface DeckyStateContext extends PublicDeckyState {
|
||||
setActivePlugin(name: string): void;
|
||||
setPluginOrder(pluginOrder: string[]): void;
|
||||
setDisabledPlugins(disabled: DisabledPlugin[]): void;
|
||||
setSortPlugins(sortPlugins: boolean): void;
|
||||
closeActivePlugin(): void;
|
||||
}
|
||||
|
||||
@@ -178,6 +187,7 @@ export const DeckyStateContextProvider: FC<Props> = ({ children, deckyState }) =
|
||||
const closeActivePlugin = deckyState.closeActivePlugin.bind(deckyState);
|
||||
const setPluginOrder = deckyState.setPluginOrder.bind(deckyState);
|
||||
const setDisabledPlugins = deckyState.setDisabledPlugins.bind(deckyState);
|
||||
const setSortPlugins = deckyState.setSortPlugins.bind(deckyState);
|
||||
|
||||
return (
|
||||
<DeckyStateContext.Provider
|
||||
@@ -189,6 +199,7 @@ export const DeckyStateContextProvider: FC<Props> = ({ children, deckyState }) =
|
||||
closeActivePlugin,
|
||||
setPluginOrder,
|
||||
setDisabledPlugins,
|
||||
setSortPlugins,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -16,6 +16,7 @@ const PluginView: FC = () => {
|
||||
updates,
|
||||
activePlugin,
|
||||
pluginOrder,
|
||||
sortPlugins,
|
||||
setActivePlugin,
|
||||
closeActivePlugin,
|
||||
} = useDeckyState();
|
||||
@@ -26,10 +27,14 @@ const PluginView: FC = () => {
|
||||
console.log('updating PluginView after changes');
|
||||
|
||||
return [...plugins]
|
||||
.sort((a, b) => pluginOrder.indexOf(a.name) - pluginOrder.indexOf(b.name))
|
||||
.sort((a, b) =>
|
||||
sortPlugins
|
||||
? a.name.localeCompare(b.name, undefined, { sensitivity: 'base' })
|
||||
: pluginOrder.indexOf(a.name) - pluginOrder.indexOf(b.name),
|
||||
)
|
||||
.filter((p) => p.content)
|
||||
.filter(({ name }) => !hiddenPlugins.includes(name));
|
||||
}, [plugins, pluginOrder, hiddenPlugins]);
|
||||
}, [plugins, pluginOrder, sortPlugins, hiddenPlugins]);
|
||||
|
||||
const numberOfHidden = hiddenPlugins.filter((name) => !!plugins.find((p) => p.name === name)).length;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { DialogBody, DialogControlsSection, DialogControlsSectionHeader, Field, Toggle } from '@decky/ui';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useSetting } from '../../../../utils/hooks/useSetting';
|
||||
import { useDeckyState } from '../../../DeckyState';
|
||||
import BranchSelect from './BranchSelect';
|
||||
import NotificationSettings from './NotificationSettings';
|
||||
@@ -14,7 +15,8 @@ export default function GeneralSettings({
|
||||
isDeveloper: boolean;
|
||||
setIsDeveloper: (val: boolean) => void;
|
||||
}) {
|
||||
const { versionInfo } = useDeckyState();
|
||||
const { versionInfo, sortPlugins, setSortPlugins } = useDeckyState();
|
||||
const [_, setSortPluginsSetting] = useSetting<boolean>('sortPlugins', false);
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@@ -42,6 +44,15 @@ export default function GeneralSettings({
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
<Field label={t('SettingsGeneralIndex.sort_plugins.label')}>
|
||||
<Toggle
|
||||
value={sortPlugins}
|
||||
onChange={(toggleValue) => {
|
||||
setSortPlugins(toggleValue);
|
||||
setSortPluginsSetting(toggleValue);
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
</DialogControlsSection>
|
||||
<DialogControlsSection>
|
||||
<DialogControlsSectionHeader>{t('SettingsGeneralIndex.about.header')}</DialogControlsSectionHeader>
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
ReorderableList,
|
||||
showContextMenu,
|
||||
} from '@decky/ui';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaDownload, FaEllipsisH, FaRecycle } from 'react-icons/fa';
|
||||
|
||||
@@ -171,9 +171,16 @@ type PluginData = {
|
||||
};
|
||||
|
||||
export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) {
|
||||
const { installedPlugins, disabledPlugins, updates, pluginOrder, setPluginOrder, frozenPlugins, hiddenPlugins } =
|
||||
useDeckyState();
|
||||
|
||||
const {
|
||||
installedPlugins,
|
||||
disabledPlugins,
|
||||
updates,
|
||||
pluginOrder,
|
||||
setPluginOrder,
|
||||
frozenPlugins,
|
||||
hiddenPlugins,
|
||||
sortPlugins,
|
||||
} = useDeckyState();
|
||||
const [_, setPluginOrderSetting] = useSetting<string[]>(
|
||||
'pluginOrder',
|
||||
installedPlugins.map((plugin) => plugin.name),
|
||||
@@ -188,6 +195,12 @@ export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) {
|
||||
const hiddenPluginsService = DeckyPluginLoader.hiddenPluginsService;
|
||||
const frozenPluginsService = DeckyPluginLoader.frozenPluginsService;
|
||||
|
||||
const sortedPlugins = useMemo(() => {
|
||||
return sortPlugins
|
||||
? [...installedPlugins].sort((a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: 'base' }))
|
||||
: installedPlugins;
|
||||
}, [installedPlugins, sortPlugins]);
|
||||
|
||||
useEffect(() => {
|
||||
setPluginEntries(
|
||||
installedPlugins.map(({ name, version }) => {
|
||||
@@ -204,7 +217,7 @@ export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) {
|
||||
disabled={disabledPlugins.find((p) => p.name == name) !== undefined}
|
||||
/>
|
||||
),
|
||||
position: pluginOrder.indexOf(name),
|
||||
position: sortPlugins ? sortedPlugins.findIndex((p) => p.name === name) : pluginOrder.indexOf(name),
|
||||
data: {
|
||||
name,
|
||||
disabled: disabledPlugins.some((disabledPlugin) => disabledPlugin.name === name),
|
||||
@@ -221,7 +234,7 @@ export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) {
|
||||
};
|
||||
}),
|
||||
);
|
||||
}, [installedPlugins, updates, hiddenPlugins, disabledPlugins]);
|
||||
}, [installedPlugins, updates, hiddenPlugins, disabledPlugins, sortPlugins, sortedPlugins]);
|
||||
|
||||
if (installedPlugins.length === 0) {
|
||||
return (
|
||||
@@ -232,6 +245,9 @@ export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) {
|
||||
}
|
||||
|
||||
function onSave(entries: ReorderableEntry<PluginTableData>[]) {
|
||||
if (sortPlugins) {
|
||||
return;
|
||||
}
|
||||
const newOrder = entries.map((entry) => entry.data!.name);
|
||||
console.log(newOrder);
|
||||
setPluginOrder(newOrder);
|
||||
@@ -265,7 +281,12 @@ export default function PluginList({ isDeveloper }: { isDeveloper: boolean }) {
|
||||
</DialogButton>
|
||||
)}
|
||||
<DialogControlsSection style={{ marginTop: 0 }}>
|
||||
<ReorderableList<PluginTableData> entries={pluginEntries} onSave={onSave} interactables={PluginInteractables} />
|
||||
<ReorderableList<PluginTableData>
|
||||
entries={pluginEntries}
|
||||
onSave={onSave}
|
||||
interactables={PluginInteractables}
|
||||
disableReordering={sortPlugins}
|
||||
/>
|
||||
</DialogControlsSection>
|
||||
</DialogBody>
|
||||
);
|
||||
|
||||
@@ -360,6 +360,12 @@ class PluginLoader extends Logger {
|
||||
this.deckyState.setPluginOrder(pluginOrder);
|
||||
});
|
||||
|
||||
// Grab and set sort plugins setting
|
||||
getSetting<boolean>('sortPlugins', false).then((sortPlugins) => {
|
||||
this.debug('sortPlugins: ', sortPlugins);
|
||||
this.deckyState.setSortPlugins(sortPlugins);
|
||||
});
|
||||
|
||||
this.frozenPluginsService.init();
|
||||
this.hiddenPluginsService.init();
|
||||
this.notificationService.init();
|
||||
|
||||
Reference in New Issue
Block a user