summaryrefslogtreecommitdiff
path: root/frontend/src
diff options
context:
space:
mode:
authorMIkhail Kozlov <mishakozlov74@gmail.com>2023-05-30 23:53:48 -0700
committerGitHub <noreply@github.com>2023-05-30 23:53:48 -0700
commitb27b625921212648748f056cd704dda0267106c5 (patch)
treeec48d864b90c54d8d02f9e46d705d60b2071d1db /frontend/src
parentc5229c6a62d423661d2f6c97fe4cfbed1a7ff019 (diff)
downloaddecky-loader-b27b625921212648748f056cd704dda0267106c5.tar.gz
decky-loader-b27b625921212648748f056cd704dda0267106c5.zip
Refactor TabsHook (#458)
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/tabs-hook.tsx133
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() {