From 9f586a1b97cf9069fbfbeee17e3909baf9e95f66 Mon Sep 17 00:00:00 2001
From: jbofill <74568881+jessebofill@users.noreply.github.com>
Date: Tue, 30 Dec 2025 12:29:08 -0700
Subject: Feat: Disable plugins (#850)

* implement base frontend changes necessary for plugin disabling

* implement frontend diisable functions/ modal

* plugin disable boilerplate / untested

* Feat disable plugins (#810)

* implement base frontend changes necessary for plugin disabling

* implement frontend diisable functions/ modal

---------

Co-authored-by: Jesse Bofill <jesse_bofill@yahoo.com>

* fix mistakes

* add frontend

* working plugin disable, not tested extensively

* fix uninstalled hidden plugins remaining in list

* hide plugin irrelevant plugin setting menu option when disabled

* fix hidden plugin issues

* reset disabled plugin on uninstall

* fix plugin load on reenable

* move disable settings uninstall cleanup

* add engilsh tranlsations for enable/ disable elements

* fix bug where wrong loadType can get passed to importPlugin

* show correct number of hidden plugins if plugin is both hidden and disabled

* fix: get fresh list of plugin updates when changed in settings plugin list

* fix: fix invalid semver plugin version from preventing latest updates

* retain x position when changing focus in list items  that have multiple horizontal focusables

* correction to pluging version checking validation

* make sure disabled plugins get checked for updates

* show number of disabled plugins at bottom of plugin view

* add notice to update modals that disabled plugins will be enabled upon installation

* run formatter

* Update backend/decky_loader/locales/en-US.json

Co-authored-by: EMERALD <hudson.samuels@gmail.com>

* chore: correct filename typo

* chore: change disabled icon

* chore: revert accidental defsettings changes

* format

* add timeout to frontend importPlugin

if a request hangs this prevent it from blocking other plugin loads.
backend diaptch_plugin which calls this for individual plugin load (as opposed to batch) is set to 15s.
other callers of importPlugin are not using timeout, same as before.

* fix plugin update checking loop

---------

Co-authored-by: marios <marios8543@gmail.com>
Co-authored-by: EMERALD <hudson.samuels@gmail.com>
---
 frontend/src/components/store/PluginCard.tsx | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

(limited to 'frontend/src/components/store/PluginCard.tsx')

diff --git a/frontend/src/components/store/PluginCard.tsx b/frontend/src/components/store/PluginCard.tsx
index f64abd09..a47207c9 100644
--- a/frontend/src/components/store/PluginCard.tsx
+++ b/frontend/src/components/store/PluginCard.tsx
@@ -1,15 +1,23 @@
-import { ButtonItem, Dropdown, Focusable, PanelSectionRow, SingleDropdownOption, SuspensefulImage } from '@decky/ui';
+import {
+  ButtonItem,
+  Dropdown,
+  Focusable,
+  NavEntryPositionPreferences,
+  PanelSectionRow,
+  SingleDropdownOption,
+  SuspensefulImage,
+} from '@decky/ui';
 import { CSSProperties, FC, useState } from 'react';
 import { useTranslation } from 'react-i18next';
 import { FaArrowDown, FaArrowUp, FaCheck, FaDownload, FaRecycle } from 'react-icons/fa';
 
-import { InstallType, Plugin } from '../../plugin';
+import { DisabledPlugin, InstallType, Plugin } from '../../plugin';
 import { StorePlugin, requestPluginInstall } from '../../store';
 import ExternalLink from '../ExternalLink';
 
 interface PluginCardProps {
   storePlugin: StorePlugin;
-  installedPlugin: Plugin | undefined;
+  installedPlugin: Plugin | DisabledPlugin | undefined;
 }
 
 const PluginCard: FC<PluginCardProps> = ({ storePlugin, installedPlugin }) => {
@@ -139,7 +147,10 @@ const PluginCard: FC<PluginCardProps> = ({ storePlugin, installedPlugin }) => {
         </div>
         <div className="deckyStoreCardButtonRow">
           <PanelSectionRow>
-            <Focusable style={{ display: 'flex', gap: '5px', padding: 0 }}>
+            <Focusable
+              style={{ display: 'flex', gap: '5px', padding: 0 }}
+              navEntryPreferPosition={NavEntryPositionPreferences.MAINTAIN_X}
+            >
               <div
                 className="deckyStoreCardInstallContainer"
                 style={
-- 
cgit v1.2.3

