From 29d651bed66a1859dcfd0ac74406a358ba65867e Mon Sep 17 00:00:00 2001 From: AAGaming Date: Thu, 9 Nov 2023 15:35:32 -0500 Subject: [PATCH 01/10] fix: get rid of title view jank on latest beta --- frontend/src/components/PluginView.tsx | 21 +++++++-------------- frontend/src/components/TitleView.tsx | 2 ++ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/PluginView.tsx b/frontend/src/components/PluginView.tsx index b53035f78..a31053fe3 100644 --- a/frontend/src/components/PluginView.tsx +++ b/frontend/src/components/PluginView.tsx @@ -1,12 +1,4 @@ -import { - ButtonItem, - Focusable, - PanelSection, - PanelSectionRow, - joinClassNames, - scrollClasses, - staticClasses, -} from 'decky-frontend-lib'; +import { ButtonItem, Focusable, PanelSection, PanelSectionRow } from 'decky-frontend-lib'; import { VFC, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { FaEyeSlash } from 'react-icons/fa'; @@ -36,10 +28,7 @@ const PluginView: VFC = () => { return ( -
+
{(visible || activePlugin.alwaysRender) && activePlugin.content}
@@ -48,7 +37,11 @@ const PluginView: VFC = () => { return ( <> -
+
{pluginList .filter((p) => p.content) diff --git a/frontend/src/components/TitleView.tsx b/frontend/src/components/TitleView.tsx index 111f8c807..357656fab 100644 --- a/frontend/src/components/TitleView.tsx +++ b/frontend/src/components/TitleView.tsx @@ -10,6 +10,8 @@ const titleStyles: CSSProperties = { display: 'flex', paddingTop: '3px', paddingRight: '16px', + position: 'sticky', + top: '0px', }; const TitleView: VFC = () => { From 8f26fdec2d7e280c11f9ef33cd706d7feb172ace Mon Sep 17 00:00:00 2001 From: Party Wumpus <48649272+PartyWumpus@users.noreply.github.com> Date: Fri, 10 Nov 2023 17:19:01 +0000 Subject: [PATCH 02/10] Count the number of installs for each plugin (#557) --- backend/src/browser.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/backend/src/browser.py b/backend/src/browser.py index da8569bee..966206671 100644 --- a/backend/src/browser.py +++ b/backend/src/browser.py @@ -186,6 +186,18 @@ async def _install(self, artifact: str, name: str, version: str, hash: str): else: logger.fatal(f"Could not fetch from URL. {await res.text()}") + storeUrl = "" + match self.settings.getSetting("store", 0): + case 0: storeUrl = "https://plugins.deckbrew.xyz/plugins" # default + case 1: storeUrl = "https://testing.deckbrew.xyz/plugins" # testing + case 2: storeUrl = self.settings.getSetting("store-url", "https://plugins.deckbrew.xyz/plugins") # custom + case _: storeUrl = "https://plugins.deckbrew.xyz/plugins" + logger.info(f"Incrementing installs for {name} from URL {storeUrl} (version {version})") + async with ClientSession() as client: + res = await client.post(storeUrl+f"/{name}/versions/{version}/increment?isUpdate={isInstalled}", ssl=get_ssl_context()) + if res.status != 200: + logger.error(f"Server did not accept install count increment request. code: {res.status}") + # Check to make sure we got the file if res_zip is None: logger.fatal(f"Could not fetch {artifact}") From 479a16c6557fc9656e1ff601e6ed7e677846d428 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 21:01:48 +0000 Subject: [PATCH 03/10] Bump aiohttp from 3.8.4 to 3.8.5 in /backend (#558) --- backend/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/requirements.txt b/backend/requirements.txt index 326a924cf..58493e572 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.8.4 +aiohttp==3.8.5 aiohttp-jinja2==1.5.1 aiohttp_cors==0.7.0 watchdog==2.1.7 From 75ad98a7b2ce53bf2916a6bfb760599e7b50fc9d Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 11 Nov 2023 21:50:23 +0100 Subject: [PATCH 04/10] Check if Linux service is running before trying to start or stop it (#540) this prevents needless prompts opening up --- backend/src/localplatformlinux.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/src/localplatformlinux.py b/backend/src/localplatformlinux.py index bde2caac1..846fa0745 100644 --- a/backend/src/localplatformlinux.py +++ b/backend/src/localplatformlinux.py @@ -125,11 +125,19 @@ async def service_restart(service_name : str) -> bool: return res.returncode == 0 async def service_stop(service_name : str) -> bool: + if not await service_active(service_name): + # Service isn't running. pretend we stopped it + return True + cmd = ["systemctl", "stop", service_name] res = run(cmd, stdout=PIPE, stderr=STDOUT) return res.returncode == 0 async def service_start(service_name : str) -> bool: + if await service_active(service_name): + # Service is running. pretend we started it + return True + cmd = ["systemctl", "start", service_name] res = run(cmd, stdout=PIPE, stderr=STDOUT) return res.returncode == 0 From 7c3ae9b62b0991cf9efcfa3d806e06c2fd664816 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 11 Nov 2023 21:56:32 +0100 Subject: [PATCH 05/10] replace chmod implementation with os.chmod (#541) --- backend/src/localplatformlinux.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/backend/src/localplatformlinux.py b/backend/src/localplatformlinux.py index 846fa0745..1f857f27d 100644 --- a/backend/src/localplatformlinux.py +++ b/backend/src/localplatformlinux.py @@ -58,8 +58,22 @@ def chown(path : str, user : UserType = UserType.HOST_USER, recursive : bool = def chmod(path : str, permissions : int, recursive : bool = True) -> bool: if _get_effective_user_id() != 0: return True - result = call(["chmod", "-R", str(permissions), path] if recursive else ["chmod", str(permissions), path]) - return result == 0 + + try: + octal_permissions = int(str(permissions), 8) + + if recursive: + for root, dirs, files in os.walk(path): + for d in dirs: + os.chmod(os.path.join(root, d), octal_permissions) + for d in files: + os.chmod(os.path.join(root, d), octal_permissions) + + os.chmod(path, octal_permissions) + except: + return False + + return True def folder_owner(path : str) -> UserType|None: user_owner = _get_user_owner(path) From 91186da97940a24c80edcd41991727d43da19456 Mon Sep 17 00:00:00 2001 From: Party Wumpus <48649272+PartyWumpus@users.noreply.github.com> Date: Fri, 24 Nov 2023 15:08:29 -0800 Subject: [PATCH 06/10] bump dfl --- frontend/package.json | 2 +- frontend/pnpm-lock.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 7017622b9..fc45005d1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -44,7 +44,7 @@ } }, "dependencies": { - "decky-frontend-lib": "3.21.1", + "decky-frontend-lib": "3.23.1", "filesize": "^10.0.7", "i18next": "^23.2.1", "i18next-http-backend": "^2.2.1", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index db150c517..f007e269b 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: decky-frontend-lib: - specifier: 3.21.1 - version: 3.21.1 + specifier: 3.23.1 + version: 3.23.1 filesize: specifier: ^10.0.7 version: 10.0.7 @@ -1482,8 +1482,8 @@ packages: dependencies: ms: 2.1.2 - /decky-frontend-lib@3.21.1: - resolution: {integrity: sha512-30605ET9qqZ6St6I9WmMmLGgSrTIdMwo7xy85+lRaF1miUd2icOGEJjwnbVcZDdkal+1fJ3tNEDXlchVfG4TrA==} + /decky-frontend-lib@3.23.1: + resolution: {integrity: sha512-6JKtSCjk5liJ+xBqOPZvPSp1HdkaQ+j/I19bGSk+cWuxSrodyduduXKJE4p4GJ/+KgFdn0yg/8tRi+DSqmBvdw==} dev: false /decode-named-character-reference@1.0.2: @@ -1852,8 +1852,8 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true @@ -3477,7 +3477,7 @@ packages: engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /rsvp@3.2.1: From 80a00a0d35655791a4e2bc697ad0748fe2c2f9ad Mon Sep 17 00:00:00 2001 From: AAGaming Date: Tue, 12 Dec 2023 22:21:25 -0500 Subject: [PATCH 07/10] fix: Adjust tabs and toaster hooks to work on react 18, also half-fix Valve Internal --- frontend/package.json | 2 +- frontend/pnpm-lock.yaml | 8 +++--- frontend/src/developer.tsx | 48 ++++++++++++++++++++-------------- frontend/src/tabs-hook.old.tsx | 4 +-- frontend/src/tabs-hook.tsx | 8 +++--- frontend/src/toaster.tsx | 17 +++++++++--- 6 files changed, 52 insertions(+), 35 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index fc45005d1..846bff50e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -44,7 +44,7 @@ } }, "dependencies": { - "decky-frontend-lib": "3.23.1", + "decky-frontend-lib": "3.24.1", "filesize": "^10.0.7", "i18next": "^23.2.1", "i18next-http-backend": "^2.2.1", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index f007e269b..f7dbe376a 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: decky-frontend-lib: - specifier: 3.23.1 - version: 3.23.1 + specifier: 3.24.1 + version: 3.24.1 filesize: specifier: ^10.0.7 version: 10.0.7 @@ -1482,8 +1482,8 @@ packages: dependencies: ms: 2.1.2 - /decky-frontend-lib@3.23.1: - resolution: {integrity: sha512-6JKtSCjk5liJ+xBqOPZvPSp1HdkaQ+j/I19bGSk+cWuxSrodyduduXKJE4p4GJ/+KgFdn0yg/8tRi+DSqmBvdw==} + /decky-frontend-lib@3.24.1: + resolution: {integrity: sha512-VGxLTPetxx/pQVC+t8odTHrwQAh7uy4bO2Od2gGWSTfmUUoxtAcEtiXGyE9mKsoD6t7QNHrGvgXn78sf2i/IeQ==} dev: false /decode-named-character-reference@1.0.2: diff --git a/frontend/src/developer.tsx b/frontend/src/developer.tsx index 43f550d76..50b3e4e49 100644 --- a/frontend/src/developer.tsx +++ b/frontend/src/developer.tsx @@ -9,32 +9,40 @@ const logger = new Logger('DeveloperMode'); let removeSettingsObserver: () => void = () => {}; -export async function setShowValveInternal(show: boolean) { - let settingsMod: any; - while (!settingsMod) { - settingsMod = findModuleChild((m) => { - if (typeof m !== 'object') return undefined; - for (let prop in m) { - if (typeof m[prop]?.settings?.bIsValveEmail !== 'undefined') return m[prop]; - } - }); - if (!settingsMod) { - logger.debug('[ValveInternal] waiting for settingsMod'); - await sleep(1000); - } +declare global { + interface Window { + settingsStore: any; } +} +export async function setShowValveInternal(show: boolean) { if (show) { - removeSettingsObserver = settingsMod[ - Object.getOwnPropertySymbols(settingsMod).find((x) => x.toString() == 'Symbol(mobx administration)') as any - ].observe((e: any) => { - e.newValue.bIsValveEmail = true; - }); - settingsMod.m_Settings.bIsValveEmail = true; + const mobx = + window.settingsStore[ + Object.getOwnPropertySymbols(window.settingsStore).find( + (x) => x.toString() == 'Symbol(mobx administration)', + ) as any + ]; + + if (mobx.observe_) { + // New style, currently broken + logger.log('Valve internal not yet supported on this build.'); + // removeSettingsObserver = mobx.observe_(mobx, [(e: any) => { + // console.log("got e", e) + // e.newValue.bIsValveEmail = true; + // }]); + } else if (mobx.observe) { + // Old style + removeSettingsObserver = mobx.observe((e: any) => { + e.newValue.bIsValveEmail = true; + }); + } + + window.settingsStore.m_Settings.bIsValveEmail = true; logger.log('Enabled Valve Internal menu'); } else { removeSettingsObserver(); - settingsMod.m_Settings.bIsValveEmail = false; + window.settingsStore.m_Settings.bIsValveEmail = false; logger.log('Disabled Valve Internal menu'); } } diff --git a/frontend/src/tabs-hook.old.tsx b/frontend/src/tabs-hook.old.tsx index 5b5115969..982f6f092 100644 --- a/frontend/src/tabs-hook.old.tsx +++ b/frontend/src/tabs-hook.old.tsx @@ -1,5 +1,5 @@ // TabsHook for versions before the Desktop merge -import { Patch, afterPatch, sleep } from 'decky-frontend-lib'; +import { Patch, afterPatch, getReactRoot, sleep } from 'decky-frontend-lib'; import { memo } from 'react'; import NewTabsHook from './tabs-hook'; @@ -35,7 +35,7 @@ class TabsHook extends NewTabsHook { init() { const self = this; - const tree = (document.getElementById('root') as any)._reactRootContainer._internalRoot.current; + const tree = getReactRoot(document.getElementById('root') as any); let scrollRoot: any; async function findScrollRoot(currentNode: any, iters: number): Promise { if (iters >= 30) { diff --git a/frontend/src/tabs-hook.tsx b/frontend/src/tabs-hook.tsx index 724377018..56ff8f10b 100644 --- a/frontend/src/tabs-hook.tsx +++ b/frontend/src/tabs-hook.tsx @@ -1,5 +1,5 @@ // TabsHook for versions after the Desktop merge -import { Patch, QuickAccessTab, afterPatch, findInReactTree, sleep } from 'decky-frontend-lib'; +import { Patch, QuickAccessTab, afterPatch, findInReactTree, getReactRoot, sleep } from 'decky-frontend-lib'; import { QuickAccessVisibleStateProvider } from './components/QuickAccessVisibleState'; import Logger from './logger'; @@ -32,11 +32,11 @@ class TabsHook extends Logger { } init() { - const tree = (document.getElementById('root') as any)._reactRootContainer._internalRoot.current; + const tree = getReactRoot(document.getElementById('root') as any); let qAMRoot: any; const findQAMRoot = (currentNode: any, iters: number): any => { - if (iters >= 65) { - // currently 45 + if (iters >= 80) { + // currently 67 return null; } if ( diff --git a/frontend/src/toaster.tsx b/frontend/src/toaster.tsx index 7ef4a4473..0db8889ab 100644 --- a/frontend/src/toaster.tsx +++ b/frontend/src/toaster.tsx @@ -1,4 +1,13 @@ -import { Module, Patch, ToastData, afterPatch, findInReactTree, findModuleChild, sleep } from 'decky-frontend-lib'; +import { + Module, + Patch, + ToastData, + afterPatch, + findInReactTree, + findModuleChild, + getReactRoot, + sleep, +} from 'decky-frontend-lib'; import { ReactNode } from 'react'; import Toast from './components/Toast'; @@ -38,10 +47,10 @@ class Toaster extends Logger { // // )); let instance: any; - const tree = (document.getElementById('root') as any)._reactRootContainer._internalRoot.current; + const tree = getReactRoot(document.getElementById('root') as any); const findToasterRoot = (currentNode: any, iters: number): any => { - if (iters >= 65) { - // currently 65 + if (iters >= 80) { + // currently 66 return null; } if ( From e21a5d5890739fc88d19504c5b31f09d3d786722 Mon Sep 17 00:00:00 2001 From: AAGaming Date: Tue, 12 Dec 2023 22:23:07 -0500 Subject: [PATCH 08/10] fix: idiotic formatting error i should have noticed --- frontend/src/developer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/developer.tsx b/frontend/src/developer.tsx index 50b3e4e49..ca9fb4094 100644 --- a/frontend/src/developer.tsx +++ b/frontend/src/developer.tsx @@ -1,4 +1,4 @@ -import { findModuleChild, sleep } from 'decky-frontend-lib'; +import { sleep } from 'decky-frontend-lib'; import { FaReact } from 'react-icons/fa'; import Logger from './logger'; From 3489fd7d692503b8e2b5e255ab75cbbf9e371536 Mon Sep 17 00:00:00 2001 From: AAGaming Date: Wed, 13 Dec 2023 22:06:22 -0500 Subject: [PATCH 09/10] fix(developer): add back valve internal on beta look i was tired when writing yesterday's fix okay --- frontend/src/developer.tsx | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/frontend/src/developer.tsx b/frontend/src/developer.tsx index ca9fb4094..e753086d3 100644 --- a/frontend/src/developer.tsx +++ b/frontend/src/developer.tsx @@ -24,19 +24,9 @@ export async function setShowValveInternal(show: boolean) { ) as any ]; - if (mobx.observe_) { - // New style, currently broken - logger.log('Valve internal not yet supported on this build.'); - // removeSettingsObserver = mobx.observe_(mobx, [(e: any) => { - // console.log("got e", e) - // e.newValue.bIsValveEmail = true; - // }]); - } else if (mobx.observe) { - // Old style - removeSettingsObserver = mobx.observe((e: any) => { - e.newValue.bIsValveEmail = true; - }); - } + removeSettingsObserver = (mobx.observe_ || mobx.observe).call(mobx, (e: any) => { + e.newValue.bIsValveEmail = true; + }); window.settingsStore.m_Settings.bIsValveEmail = true; logger.log('Enabled Valve Internal menu'); From 39f4f2870b4c0924421130a3f532c07320938e97 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 16 Dec 2023 03:07:54 +0100 Subject: [PATCH 10/10] Call plugin unload function after stopping event loop (#539) This can prevent race conditions where unload is clearing data but main is still working with it --- backend/src/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugin.py b/backend/src/plugin.py index b57bc5f7f..ed401b45a 100644 --- a/backend/src/plugin.py +++ b/backend/src/plugin.py @@ -118,11 +118,11 @@ async def _on_new_message(self, message : str) -> str|None: if "stop" in data: self.log.info("Calling Loader unload function.") - await self._unload() get_event_loop().stop() while get_event_loop().is_running(): await sleep(0) get_event_loop().close() + await self._unload() raise Exception("Closing message listener") # TODO there is definitely a better way to type this