diff options
| author | Weblate <noreply@weblate.org> | 2023-06-04 15:08:29 +0000 |
|---|---|---|
| committer | Weblate <noreply@weblate.org> | 2023-06-04 15:08:29 +0000 |
| commit | f87e794c3ff12ae18e0b4948bc5f854f590817b3 (patch) | |
| tree | 21dad29ad293c90afc6895349ee9151696e99e05 | |
| parent | 56719df8279b40fd61f597a6a4d40403cc911c3a (diff) | |
| parent | 8f17f2b0fe3528ec378ac4898dab3db05f3c4009 (diff) | |
| download | decky-loader-f87e794c3ff12ae18e0b4948bc5f854f590817b3.tar.gz decky-loader-f87e794c3ff12ae18e0b4948bc5f854f590817b3.zip | |
Merge remote-tracking branch 'origin/main'
| -rw-r--r-- | frontend/src/tabs-hook.tsx | 133 |
1 files changed, 73 insertions, 60 deletions
diff --git a/frontend/src/tabs-hook.tsx b/frontend/src/tabs-hook.tsx index 5d708fcb..08206c14 100644 --- a/frontend/src/tabs-hook.tsx +++ b/frontend/src/tabs-hook.tsx @@ -1,14 +1,5 @@ // TabsHook for versions after the Desktop merge -import { - Patch, - QuickAccessTab, - afterPatch, - findInReactTree, - findSP, - gamepadUIClasses, - getReactInstance, - sleep, -} from 'decky-frontend-lib'; +import { Patch, QuickAccessTab, afterPatch, findInReactTree, sleep } from 'decky-frontend-lib'; import { QuickAccessVisibleStateProvider } from './components/QuickAccessVisibleState'; import Logger from './logger'; @@ -40,60 +31,82 @@ class TabsHook extends Logger { window.__TABS_HOOK_INSTANCE = this; } - async init() { - this.qAMRoot = await this.getQAMRoot(); - - let patchedInnerQAM: any; - this.qamPatch = afterPatch(this.qAMRoot.return, 'type', (_: any, ret: any) => { - try { - if (this.qAMRoot?.child && !this.qAMRoot?.child?.type?.decky) { - afterPatch(this.qAMRoot.child, 'type', (_: any, ret: any) => { - try { - const qamTabsRenderer = findInReactTree(ret, (x) => x?.props?.onFocusNavDeactivated); - if (patchedInnerQAM) { - qamTabsRenderer.type = patchedInnerQAM; - } else { - afterPatch(qamTabsRenderer, 'type', (innerArgs: any, ret: any) => { - const tabs = findInReactTree(ret, (x) => x?.props?.tabs); - this.render(tabs.props.tabs, innerArgs[0].visible); - return ret; - }); - patchedInnerQAM = qamTabsRenderer.type; + init() { + const tree = (document.getElementById('root') as any)._reactRootContainer._internalRoot.current; + let qAMRoot: any; + const findQAMRoot = (currentNode: any, iters: number): any => { + if (iters >= 65) { + // currently 45 + return null; + } + if ( + typeof currentNode?.memoizedProps?.visible == 'boolean' && + currentNode?.type?.toString()?.includes('QuickAccessMenuBrowserView') + ) { + this.log(`QAM root was found in ${iters} recursion cycles`); + return currentNode; + } + if (currentNode.child) { + let node = findQAMRoot(currentNode.child, iters + 1); + if (node !== null) return node; + } + if (currentNode.sibling) { + let node = findQAMRoot(currentNode.sibling, iters + 1); + if (node !== null) return node; + } + return null; + }; + (async () => { + qAMRoot = findQAMRoot(tree, 0); + while (!qAMRoot) { + this.error( + 'Failed to find QAM root node, reattempting in 5 seconds. A developer may need to increase the recursion limit.', + ); + await sleep(5000); + qAMRoot = findQAMRoot(tree, 0); + } + this.qAMRoot = qAMRoot; + let patchedInnerQAM: any; + this.qamPatch = afterPatch(qAMRoot.return, 'type', (_: any, ret: any) => { + try { + if (!qAMRoot?.child) { + qAMRoot = findQAMRoot(tree, 0); + this.qAMRoot = qAMRoot; + } + if (qAMRoot?.child && !qAMRoot?.child?.type?.decky) { + afterPatch(qAMRoot.child, 'type', (_: any, ret: any) => { + try { + const qamTabsRenderer = findInReactTree(ret, (x) => x?.props?.onFocusNavDeactivated); + if (patchedInnerQAM) { + qamTabsRenderer.type = patchedInnerQAM; + } else { + afterPatch(qamTabsRenderer, 'type', (innerArgs: any, ret: any) => { + const tabs = findInReactTree(ret, (x) => x?.props?.tabs); + this.render(tabs.props.tabs, innerArgs[0].visible); + return ret; + }); + patchedInnerQAM = qamTabsRenderer.type; + } + } catch (e) { + this.error('Error patching QAM inner', e); } - } catch (e) { - this.error('Error patching QAM inner', e); - } - return ret; - }); - this.qAMRoot.child.type.decky = true; - this.qAMRoot.child.alternate.type = this.qAMRoot.child.type; + return ret; + }); + qAMRoot.child.type.decky = true; + qAMRoot.child.alternate.type = qAMRoot.child.type; + } + } catch (e) { + this.error('Error patching QAM', e); } - } catch (e) { - this.error('Error patching QAM', e); - } - return ret; - }); + return ret; + }); - if (this.qAMRoot.return.alternate) { - this.qAMRoot.return.alternate.type = this.qAMRoot.return.type; - } - this.log('Finished initial injection'); - } - - async getQAMRoot() { - while (!findSP()) { - await sleep(50); - } - - const parentNode = findSP().document.querySelector(`.${gamepadUIClasses.BasicUiRoot}`); - if (!parentNode) return null; - - return findInReactTree( - getReactInstance(parentNode), - (n) => - typeof n.memoizedProps?.visible !== 'undefined' && n.type?.toString()?.includes('QuickAccessMenuBrowserView'), - ); + if (qAMRoot.return.alternate) { + qAMRoot.return.alternate.type = qAMRoot.return.type; + } + this.log('Finished initial injection'); + })(); } deinit() { |
