diff options
Diffstat (limited to 'frontend/src/tabs-hook.tsx')
| -rw-r--r-- | frontend/src/tabs-hook.tsx | 133 |
1 files changed, 60 insertions, 73 deletions
diff --git a/frontend/src/tabs-hook.tsx b/frontend/src/tabs-hook.tsx index 08206c14..5d708fcb 100644 --- a/frontend/src/tabs-hook.tsx +++ b/frontend/src/tabs-hook.tsx @@ -1,5 +1,14 @@ // TabsHook for versions after the Desktop merge -import { Patch, QuickAccessTab, afterPatch, findInReactTree, sleep } from 'decky-frontend-lib'; +import { + Patch, + QuickAccessTab, + afterPatch, + findInReactTree, + findSP, + gamepadUIClasses, + getReactInstance, + sleep, +} from 'decky-frontend-lib'; import { QuickAccessVisibleStateProvider } from './components/QuickAccessVisibleState'; import Logger from './logger'; @@ -31,82 +40,60 @@ class TabsHook extends Logger { window.__TABS_HOOK_INSTANCE = this; } - 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); + 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; } - 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 inner', e); + } + return ret; + }); + this.qAMRoot.child.type.decky = true; + this.qAMRoot.child.alternate.type = this.qAMRoot.child.type; } + } catch (e) { + this.error('Error patching QAM', e); + } - return ret; - }); + return ret; + }); - if (qAMRoot.return.alternate) { - qAMRoot.return.alternate.type = qAMRoot.return.type; - } - this.log('Finished initial injection'); - })(); + 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'), + ); } deinit() { |
