mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-06-17 08:47:49 +00:00
Refactor TabsHook (#458)
This commit is contained in:
@@ -43,7 +43,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"decky-frontend-lib": "3.20.7",
|
||||
"decky-frontend-lib": "3.21.1",
|
||||
"i18next": "^22.5.0",
|
||||
"i18next-http-backend": "^2.2.1",
|
||||
"react-file-icon": "^1.3.0",
|
||||
|
||||
Generated
+4
-4
@@ -2,8 +2,8 @@ lockfileVersion: '6.0'
|
||||
|
||||
dependencies:
|
||||
decky-frontend-lib:
|
||||
specifier: 3.20.7
|
||||
version: 3.20.7
|
||||
specifier: 3.21.1
|
||||
version: 3.21.1
|
||||
i18next:
|
||||
specifier: ^22.5.0
|
||||
version: 22.5.0
|
||||
@@ -1393,8 +1393,8 @@ packages:
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
|
||||
/decky-frontend-lib@3.20.7:
|
||||
resolution: {integrity: sha512-Zwwbo50cqpTbCfSCZaqITgTRvWs7pK9KO1A+Oo2sCC/DqOfyUtEH5niNPid4Qxu+yh4lsbEjTurJk1nCfd+nZw==}
|
||||
/decky-frontend-lib@3.21.1:
|
||||
resolution: {integrity: sha512-30605ET9qqZ6St6I9WmMmLGgSrTIdMwo7xy85+lRaF1miUd2icOGEJjwnbVcZDdkal+1fJ3tNEDXlchVfG4TrA==}
|
||||
dev: false
|
||||
|
||||
/decode-named-character-reference@1.0.2:
|
||||
|
||||
+61
-74
@@ -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;
|
||||
}
|
||||
|
||||
return ret;
|
||||
});
|
||||
|
||||
if (qAMRoot.return.alternate) {
|
||||
qAMRoot.return.alternate.type = qAMRoot.return.type;
|
||||
} catch (e) {
|
||||
this.error('Error patching QAM', e);
|
||||
}
|
||||
this.log('Finished initial injection');
|
||||
})();
|
||||
|
||||
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'),
|
||||
);
|
||||
}
|
||||
|
||||
deinit() {
|
||||
|
||||
Reference in New Issue
Block a user