mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-07-11 23:41:59 +00:00
Refactor TabsHook (#458)
This commit is contained in:
@@ -43,7 +43,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"decky-frontend-lib": "3.20.7",
|
"decky-frontend-lib": "3.21.1",
|
||||||
"i18next": "^22.5.0",
|
"i18next": "^22.5.0",
|
||||||
"i18next-http-backend": "^2.2.1",
|
"i18next-http-backend": "^2.2.1",
|
||||||
"react-file-icon": "^1.3.0",
|
"react-file-icon": "^1.3.0",
|
||||||
|
|||||||
Generated
+4
-4
@@ -2,8 +2,8 @@ lockfileVersion: '6.0'
|
|||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
decky-frontend-lib:
|
decky-frontend-lib:
|
||||||
specifier: 3.20.7
|
specifier: 3.21.1
|
||||||
version: 3.20.7
|
version: 3.21.1
|
||||||
i18next:
|
i18next:
|
||||||
specifier: ^22.5.0
|
specifier: ^22.5.0
|
||||||
version: 22.5.0
|
version: 22.5.0
|
||||||
@@ -1393,8 +1393,8 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.2
|
ms: 2.1.2
|
||||||
|
|
||||||
/decky-frontend-lib@3.20.7:
|
/decky-frontend-lib@3.21.1:
|
||||||
resolution: {integrity: sha512-Zwwbo50cqpTbCfSCZaqITgTRvWs7pK9KO1A+Oo2sCC/DqOfyUtEH5niNPid4Qxu+yh4lsbEjTurJk1nCfd+nZw==}
|
resolution: {integrity: sha512-30605ET9qqZ6St6I9WmMmLGgSrTIdMwo7xy85+lRaF1miUd2icOGEJjwnbVcZDdkal+1fJ3tNEDXlchVfG4TrA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/decode-named-character-reference@1.0.2:
|
/decode-named-character-reference@1.0.2:
|
||||||
|
|||||||
+61
-74
@@ -1,5 +1,14 @@
|
|||||||
// TabsHook for versions after the Desktop merge
|
// 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 { QuickAccessVisibleStateProvider } from './components/QuickAccessVisibleState';
|
||||||
import Logger from './logger';
|
import Logger from './logger';
|
||||||
@@ -31,82 +40,60 @@ class TabsHook extends Logger {
|
|||||||
window.__TABS_HOOK_INSTANCE = this;
|
window.__TABS_HOOK_INSTANCE = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
async init() {
|
||||||
const tree = (document.getElementById('root') as any)._reactRootContainer._internalRoot.current;
|
this.qAMRoot = await this.getQAMRoot();
|
||||||
let qAMRoot: any;
|
|
||||||
const findQAMRoot = (currentNode: any, iters: number): any => {
|
let patchedInnerQAM: any;
|
||||||
if (iters >= 65) {
|
this.qamPatch = afterPatch(this.qAMRoot.return, 'type', (_: any, ret: any) => {
|
||||||
// currently 45
|
try {
|
||||||
return null;
|
if (this.qAMRoot?.child && !this.qAMRoot?.child?.type?.decky) {
|
||||||
}
|
afterPatch(this.qAMRoot.child, 'type', (_: any, ret: any) => {
|
||||||
if (
|
try {
|
||||||
typeof currentNode?.memoizedProps?.visible == 'boolean' &&
|
const qamTabsRenderer = findInReactTree(ret, (x) => x?.props?.onFocusNavDeactivated);
|
||||||
currentNode?.type?.toString()?.includes('QuickAccessMenuBrowserView')
|
if (patchedInnerQAM) {
|
||||||
) {
|
qamTabsRenderer.type = patchedInnerQAM;
|
||||||
this.log(`QAM root was found in ${iters} recursion cycles`);
|
} else {
|
||||||
return currentNode;
|
afterPatch(qamTabsRenderer, 'type', (innerArgs: any, ret: any) => {
|
||||||
}
|
const tabs = findInReactTree(ret, (x) => x?.props?.tabs);
|
||||||
if (currentNode.child) {
|
this.render(tabs.props.tabs, innerArgs[0].visible);
|
||||||
let node = findQAMRoot(currentNode.child, iters + 1);
|
return ret;
|
||||||
if (node !== null) return node;
|
});
|
||||||
}
|
patchedInnerQAM = qamTabsRenderer.type;
|
||||||
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;
|
} catch (e) {
|
||||||
});
|
this.error('Error patching QAM inner', e);
|
||||||
qAMRoot.child.type.decky = true;
|
}
|
||||||
qAMRoot.child.alternate.type = qAMRoot.child.type;
|
return ret;
|
||||||
}
|
});
|
||||||
} catch (e) {
|
this.qAMRoot.child.type.decky = true;
|
||||||
this.error('Error patching QAM', e);
|
this.qAMRoot.child.alternate.type = this.qAMRoot.child.type;
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
return ret;
|
this.error('Error patching QAM', e);
|
||||||
});
|
|
||||||
|
|
||||||
if (qAMRoot.return.alternate) {
|
|
||||||
qAMRoot.return.alternate.type = qAMRoot.return.type;
|
|
||||||
}
|
}
|
||||||
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() {
|
deinit() {
|
||||||
|
|||||||
Reference in New Issue
Block a user