diff options
| author | AAGaming <aa@mail.catvibers.me> | 2022-10-24 19:14:56 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-24 16:14:56 -0700 |
| commit | 84c3b039c385ad872bb0f22eba7a3d2cd4a5ea10 (patch) | |
| tree | 20b13066c6256cc6ca1beac085094c7964226a37 /frontend/src/tabs-hook.tsx | |
| parent | 2e6b3834da357c7e81821ce60bad36f54dd9fa6e (diff) | |
| download | decky-loader-84c3b039c385ad872bb0f22eba7a3d2cd4a5ea10.tar.gz decky-loader-84c3b039c385ad872bb0f22eba7a3d2cd4a5ea10.zip | |
preview 10/21/2022 fixes (#234)
* initial fixes: everything working except toasts and patch notes
* tabshook changes, disable toaster for now
* prettier
* oops
* implement custom toaster because I am tired of Valve's shit
also fix QAM not injecting sometimes
* remove extra logging
* add findSP, fix patch notes, fix vscode screwup
* fix patch notes
* show error when plugin frontends fail to load
* add get_tab_lambda
* add css and has_element helpers to Tab
* small modals fixup
* Don't forceUpdate QuickAccess on stable
* add routes prop used to get tabs component
* add more dev utils to DFL global
Diffstat (limited to 'frontend/src/tabs-hook.tsx')
| -rw-r--r-- | frontend/src/tabs-hook.tsx | 143 |
1 files changed, 57 insertions, 86 deletions
diff --git a/frontend/src/tabs-hook.tsx b/frontend/src/tabs-hook.tsx index c5072e27..5929b8a0 100644 --- a/frontend/src/tabs-hook.tsx +++ b/frontend/src/tabs-hook.tsx @@ -1,5 +1,4 @@ -import { Patch, QuickAccessTab, afterPatch, sleep } from 'decky-frontend-lib'; -import { memo } from 'react'; +import { QuickAccessTab, quickAccessMenuClasses, sleep } from 'decky-frontend-lib'; import { QuickAccessVisibleStateProvider } from './components/QuickAccessVisibleState'; import Logger from './logger'; @@ -28,15 +27,7 @@ interface Tab { class TabsHook extends Logger { // private keys = 7; tabs: Tab[] = []; - private quickAccess: any; - private tabRenderer: any; - private memoizedQuickAccess: any; - private cNode: any; - - private qAPTree: any; - private rendererTree: any; - - private cNodePatch?: Patch; + private oFilter: (...args: any[]) => any; constructor() { super('TabsHook'); @@ -46,84 +37,63 @@ class TabsHook extends Logger { window.__TABS_HOOK_INSTANCE = this; const self = this; - const tree = (document.getElementById('root') as any)._reactRootContainer._internalRoot.current; - let scrollRoot: any; - async function findScrollRoot(currentNode: any, iters: number): Promise<any> { - if (iters >= 30) { - self.error( - 'Scroll root was not found before hitting the recursion limit, a developer will need to increase the limit.', - ); - return null; - } - currentNode = currentNode?.child; - if (currentNode?.type?.prototype?.RemoveSmartScrollContainer) { - self.log(`Scroll root was found in ${iters} recursion cycles`); - return currentNode; - } - if (!currentNode) return null; - if (currentNode.sibling) { - let node = await findScrollRoot(currentNode.sibling, iters + 1); - if (node !== null) return node; - } - return await findScrollRoot(currentNode, iters + 1); - } - (async () => { - scrollRoot = await findScrollRoot(tree, 0); - while (!scrollRoot) { - this.log('Failed to find scroll root node, reattempting in 5 seconds'); - await sleep(5000); - scrollRoot = await findScrollRoot(tree, 0); + const oFilter = (this.oFilter = Array.prototype.filter); + Array.prototype.filter = function patchedFilter(...args: any[]) { + if (isTabsArray(this)) { + self.render(this); } - let newQA: any; - let newQATabRenderer: any; - this.cNodePatch = afterPatch(scrollRoot.stateNode, 'render', (_: any, ret: any) => { - if (!this.quickAccess && ret.props.children.props.children[4]) { - this.quickAccess = ret?.props?.children?.props?.children[4].type; - newQA = (...args: any) => { - const ret = this.quickAccess.type(...args); - if (ret) { - if (!newQATabRenderer) { - this.tabRenderer = ret.props.children[1].children.type; - newQATabRenderer = (...qamArgs: any[]) => { - const oFilter = Array.prototype.filter; - Array.prototype.filter = function (...args: any[]) { - if (isTabsArray(this)) { - self.render(this, qamArgs[0].visible); - } - // @ts-ignore - return oFilter.call(this, ...args); - }; - // TODO remove array hack entirely and use this instead const tabs = ret.props.children.props.children[0].props.children[1].props.children[0].props.children[0].props.tabs - const ret = this.tabRenderer(...qamArgs); - Array.prototype.filter = oFilter; - return ret; - }; - } - this.rendererTree = ret.props.children[1].children; - ret.props.children[1].children.type = newQATabRenderer; - } - return ret; - }; - this.memoizedQuickAccess = memo(newQA); - this.memoizedQuickAccess.isDeckyQuickAccess = true; - } - if (ret.props.children.props.children[4]) { - this.qAPTree = ret.props.children.props.children[4]; - ret.props.children.props.children[4].type = this.memoizedQuickAccess; + // @ts-ignore + return oFilter.call(this, ...args); + }; + + if (document.title != 'SP') + try { + const tree = (document.getElementById('root') as any)._reactRootContainer._internalRoot.current; + let qAMRoot: any; + async function findQAMRoot(currentNode: any, iters: number): Promise<any> { + if (iters >= 60) { + // currently 44 + return null; + } + currentNode = currentNode?.child; + if ( + currentNode?.memoizedProps?.className && + currentNode?.memoizedProps?.className.startsWith(quickAccessMenuClasses.ViewPlaceholder) + ) { + self.log(`QAM root was found in ${iters} recursion cycles`); + return currentNode; + } + if (!currentNode) return null; + if (currentNode.sibling) { + let node = await findQAMRoot(currentNode.sibling, iters + 1); + if (node !== null) return node; + } + return await findQAMRoot(currentNode, iters + 1); } - return ret; - }); - this.cNode = scrollRoot; - this.cNode.stateNode.forceUpdate(); - this.log('Finished initial injection'); - })(); + (async () => { + qAMRoot = await 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 = await findQAMRoot(tree, 0); + } + + while (!qAMRoot?.stateNode?.forceUpdate) { + qAMRoot = qAMRoot.return; + } + qAMRoot.stateNode.shouldComponentUpdate = () => true; + qAMRoot.stateNode.forceUpdate(); + delete qAMRoot.stateNode.shouldComponentUpdate; + })(); + } catch (e) { + this.log('Failed to rerender QAM', e); + } } deinit() { - this.cNodePatch?.unpatch(); - if (this.qAPTree) this.qAPTree.type = this.quickAccess; - if (this.rendererTree) this.rendererTree.type = this.tabRenderer; - if (this.cNode) this.cNode.stateNode.forceUpdate(); + Array.prototype.filter = this.oFilter; } add(tab: Tab) { @@ -136,13 +106,14 @@ class TabsHook extends Logger { this.tabs = this.tabs.filter((tab) => tab.id !== id); } - render(existingTabs: any[], visible: boolean) { + render(existingTabs: any[]) { for (const { title, icon, content, id } of this.tabs) { existingTabs.push({ key: id, title, tab: icon, - panel: <QuickAccessVisibleStateProvider visible={visible}>{content}</QuickAccessVisibleStateProvider>, + decky: true, + panel: <QuickAccessVisibleStateProvider>{content}</QuickAccessVisibleStateProvider>, }); } } |
