summaryrefslogtreecommitdiff
path: root/frontend/src/tabs-hook.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/tabs-hook.tsx')
-rw-r--r--frontend/src/tabs-hook.tsx101
1 files changed, 26 insertions, 75 deletions
diff --git a/frontend/src/tabs-hook.tsx b/frontend/src/tabs-hook.tsx
index 16643165..dbf6ca35 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 { ErrorBoundary, Patch, QuickAccessTab, afterPatch, findInReactTree, getReactRoot, sleep } from '@decky/ui';
+import { ErrorBoundary, Patch, QuickAccessTab, afterPatch, createReactTreePatcher, findInReactTree, findModuleByExport, getReactRoot, setReactPatcherLoggingEnabled, sleep } from '@decky/ui';
import { QuickAccessVisibleStateProvider } from './components/QuickAccessVisibleState';
import Logger from './logger';
@@ -22,6 +22,7 @@ class TabsHook extends Logger {
tabs: Tab[] = [];
private qAMRoot?: any;
private qamPatch?: Patch;
+ private cachedTabs: any;
constructor() {
super('TabsHook');
@@ -32,87 +33,37 @@ class TabsHook extends Logger {
}
init() {
- const tree = getReactRoot(document.getElementById('root') as any);
- let qAMRoot: any;
- const findQAMRoot = (currentNode: any, iters: number): any => {
- if (iters >= 80) {
- // currently 67
- return null;
- }
- if (
- (typeof currentNode?.memoizedProps?.visible == 'boolean' ||
- typeof currentNode?.memoizedProps?.active == '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);
- }
- return ret;
- });
- qAMRoot.child.type.decky = true;
- qAMRoot.child.alternate.type = qAMRoot.child.type;
- }
- } catch (e) {
- this.error('Error patching QAM', e);
- }
+ // TODO patch the "embedded" renderer in this module too (seems to be for VR? unsure)
+ const qamModule = findModuleByExport(e => e?.type?.toString()?.includes("QuickAccessMenuBrowserView"));
+ const qamRenderer = Object.values(qamModule).find((e: any) => e?.type?.toString()?.includes("QuickAccessMenuBrowserView"))
- return ret;
- });
+ const patchHandler = createReactTreePatcher([
+ tree => findInReactTree(tree, node => node?.props?.onFocusNavDeactivated)
+ ], (args, ret) => {
+ this.log("qam render", args, ret);
+ const tabs = findInReactTree(ret, (x) => x?.props?.tabs);
+ this.render(tabs.props.tabs, args[0].visible);
+ return ret;
+ }, "TabsHook");
- if (qAMRoot.return.alternate) {
- qAMRoot.return.alternate.type = qAMRoot.return.type;
+ this.qamPatch = afterPatch(qamRenderer, "type", patchHandler);
+
+ // Patch already rendered qam
+ const root = getReactRoot(document.getElementById('root') as any);
+ const qamNode = root && findInReactTree(root, (n: any) => n.elementType == qamRenderer); // need elementType, because type is actually mobx wrapper
+ if (qamNode) {
+ this.debug("qamNode", qamNode);
+ // Only affects this fiber node so we don't need to unpatch here
+ qamNode.type = qamNode.elementType.type;
+ if (qamNode?.alternate) {
+ qamNode.alternate.type = qamNode.type;
}
- this.log('Finished initial injection');
- })();
+ }
}
deinit() {
this.qamPatch?.unpatch();
- this.qAMRoot.return.alternate.type = this.qAMRoot.return.type;
+ // this.qAMRoot.return.alternate.type = this.qAMRoot.return.type;
}
add(tab: Tab) {