summaryrefslogtreecommitdiff
path: root/frontend/src/components/settings/pages
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/settings/pages')
-rw-r--r--frontend/src/components/settings/pages/plugin_list/PluginListLabel.tsx34
-rw-r--r--frontend/src/components/settings/pages/plugin_list/index.tsx74
2 files changed, 79 insertions, 29 deletions
diff --git a/frontend/src/components/settings/pages/plugin_list/PluginListLabel.tsx b/frontend/src/components/settings/pages/plugin_list/PluginListLabel.tsx
new file mode 100644
index 00000000..a49f808f
--- /dev/null
+++ b/frontend/src/components/settings/pages/plugin_list/PluginListLabel.tsx
@@ -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;
diff --git a/frontend/src/components/settings/pages/plugin_list/index.tsx b/frontend/src/components/settings/pages/plugin_list/index.tsx
index fab8ec2b..09d06d48 100644
--- a/frontend/src/components/settings/pages/plugin_list/index.tsx
+++ b/frontend/src/components/settings/pages/plugin_list/index.tsx
@@ -22,10 +22,7 @@ import {
} from '../../../../store';
import { useSetting } from '../../../../utils/hooks/useSetting';
import { useDeckyState } from '../../../DeckyState';
-
-function labelToName(pluginLabel: string, pluginVersion?: string): string {
- return pluginVersion ? pluginLabel.substring(0, pluginLabel.indexOf(` - ${pluginVersion}`)) : pluginLabel;
-}
+import PluginListLabel from './PluginListLabel';
async function reinstallPlugin(pluginName: string, currentVersion?: string) {
const serverData = await getPluginList();
@@ -36,10 +33,17 @@ async function reinstallPlugin(pluginName: string, currentVersion?: string) {
}
}
-function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
- const data = props.entry.data;
+type PluginTableData = PluginData & { name: string; hidden: boolean; onHide(): void; onShow(): void };
+
+function PluginInteractables(props: { entry: ReorderableEntry<PluginTableData> }) {
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) => {
showContextMenu(
@@ -47,7 +51,7 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
<MenuItem
onSelected={() => {
try {
- fetch(`http://127.0.0.1:1337/plugins/${pluginName}/reload`, {
+ fetch(`http://127.0.0.1:1337/plugins/${name}/reload`, {
method: 'POST',
credentials: 'include',
headers: {
@@ -58,7 +62,7 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
console.error('Error Reloading Plugin Backend', err);
}
- window.DeckyPluginLoader.importPlugin(pluginName, data?.version);
+ window.DeckyPluginLoader.importPlugin(name, version);
}}
>
{t('PluginListIndex.reload')}
@@ -66,15 +70,20 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
<MenuItem
onSelected={() =>
window.DeckyPluginLoader.uninstallPlugin(
- pluginName,
- t('PluginLoader.plugin_uninstall.title', { name: pluginName }),
+ name,
+ t('PluginLoader.plugin_uninstall.title', { name }),
t('PluginLoader.plugin_uninstall.button'),
- t('PluginLoader.plugin_uninstall.desc', { name: pluginName }),
+ t('PluginLoader.plugin_uninstall.desc', { name }),
)
}
>
{t('PluginListIndex.uninstall')}
</MenuItem>
+ {hidden ? (
+ <MenuItem onSelected={onShow}>{t('PluginListIndex.show')}</MenuItem>
+ ) : (
+ <MenuItem onSelected={onHide}>{t('PluginListIndex.hide')}</MenuItem>
+ )}
</Menu>,
e.currentTarget ?? window,
);
@@ -82,22 +91,22 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
return (
<>
- {data?.update ? (
+ {update ? (
<DialogButton
style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
- onClick={() => requestPluginInstall(pluginName, data?.update as StorePluginVersion, InstallType.UPDATE)}
- onOKButton={() => requestPluginInstall(pluginName, data?.update as StorePluginVersion, InstallType.UPDATE)}
+ onClick={() => requestPluginInstall(name, update, InstallType.UPDATE)}
+ onOKButton={() => requestPluginInstall(name, update, InstallType.UPDATE)}
>
<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' }} />
</div>
</DialogButton>
) : (
<DialogButton
style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
- onClick={() => reinstallPlugin(pluginName, data?.version)}
- onOKButton={() => reinstallPlugin(pluginName, data?.version)}
+ onClick={() => reinstallPlugin(name, version)}
+ onOKButton={() => reinstallPlugin(name, version)}
>
<div style={{ display: 'flex', minWidth: '180px', justifyContent: 'space-between', alignItems: 'center' }}>
{t('PluginListIndex.reinstall')}
@@ -130,7 +139,7 @@ type PluginData = {
};
export default function PluginList() {
- const { plugins, updates, pluginOrder, setPluginOrder } = useDeckyState();
+ const { plugins, updates, pluginOrder, setPluginOrder, hiddenPlugins } = useDeckyState();
const [_, setPluginOrderSetting] = useSetting<string[]>(
'pluginOrder',
plugins.map((plugin) => plugin.name),
@@ -141,22 +150,29 @@ export default function PluginList() {
window.DeckyPluginLoader.checkPluginUpdates();
}, []);
- const [pluginEntries, setPluginEntries] = useState<ReorderableEntry<PluginData>[]>([]);
+ const [pluginEntries, setPluginEntries] = useState<ReorderableEntry<PluginTableData>[]>([]);
+ const hiddenPluginsService = window.DeckyPluginLoader.hiddenPluginsService;
useEffect(() => {
setPluginEntries(
- plugins.map((plugin) => {
+ plugins.map(({ name, version }) => {
+ const hidden = hiddenPlugins.includes(name);
+
return {
- label: plugin.version ? `${plugin.name} - ${plugin.version}` : plugin.name,
+ label: <PluginListLabel name={name} hidden={hidden} version={version} />,
+ position: pluginOrder.indexOf(name),
data: {
- update: updates?.get(plugin.name),
- version: plugin.version,
+ name,
+ 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) {
return (
@@ -166,8 +182,8 @@ export default function PluginList() {
);
}
- function onSave(entries: ReorderableEntry<PluginData>[]) {
- const newOrder = entries.map((entry) => labelToName(entry.label, entry?.data?.version));
+ function onSave(entries: ReorderableEntry<PluginTableData>[]) {
+ const newOrder = entries.map((entry) => entry.data!.name);
console.log(newOrder);
setPluginOrder(newOrder);
setPluginOrderSetting(newOrder);
@@ -200,7 +216,7 @@ export default function PluginList() {
</DialogButton>
)}
<DialogControlsSection style={{ marginTop: 0 }}>
- <ReorderableList<PluginData> entries={pluginEntries} onSave={onSave} interactables={PluginInteractables} />
+ <ReorderableList<PluginTableData> entries={pluginEntries} onSave={onSave} interactables={PluginInteractables} />
</DialogControlsSection>
</DialogBody>
);