diff options
| author | AAGaming <aa@mail.catvibers.me> | 2022-06-20 23:37:52 -0400 |
|---|---|---|
| committer | AAGaming <aa@mail.catvibers.me> | 2022-06-20 23:37:52 -0400 |
| commit | e7c44ee202fcb9ebe5e737eb23485a38b7ea6657 (patch) | |
| tree | e125988f23bc35219b0abcfa1c0f3a1a0abf570c | |
| parent | 39f6a7688de64b41090ec2030e46470b49c6866f (diff) | |
| download | decky-loader-e7c44ee202fcb9ebe5e737eb23485a38b7ea6657.tar.gz decky-loader-e7c44ee202fcb9ebe5e737eb23485a38b7ea6657.zip | |
Replace tabs hook, fix panels, bump lib
| -rwxr-xr-x | contrib/deck.sh | 4 | ||||
| -rw-r--r-- | frontend/package.json | 2 | ||||
| -rw-r--r-- | frontend/src/plugin-loader.tsx | 4 | ||||
| -rw-r--r-- | frontend/src/tabs-hook.ts | 85 |
4 files changed, 80 insertions, 15 deletions
diff --git a/contrib/deck.sh b/contrib/deck.sh index d46a7929..1bb1690f 100755 --- a/contrib/deck.sh +++ b/contrib/deck.sh @@ -167,8 +167,8 @@ pnpmtransbundle() { pnpm i &> '/dev/null' pnpm run build &> '/dev/null' elif [[ "$2" == "template" ]]; then - pnpm i - pnpm run build + pnpm i &> '/dev/null' + pnpm run build &> '/dev/null' fi } diff --git a/frontend/package.json b/frontend/package.json index ece97471..d4a5c12b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -37,7 +37,7 @@ } }, "dependencies": { - "decky-frontend-lib": "^0.10.2", + "decky-frontend-lib": "^0.11.0", "react-icons": "^4.4.0" } } diff --git a/frontend/src/plugin-loader.tsx b/frontend/src/plugin-loader.tsx index 442db3e4..5f284503 100644 --- a/frontend/src/plugin-loader.tsx +++ b/frontend/src/plugin-loader.tsx @@ -117,10 +117,10 @@ class PluginLoader extends Logger { private async importReactPlugin(name: string) { let res = await fetch(`http://127.0.0.1:1337/plugins/${name}/frontend_bundle`); if (res.ok) { - let { name: _, content } = await eval(await res.text())(this.createPluginAPI(name)); + let plugin = await eval(await res.text())(this.createPluginAPI(name)); this.plugins.push({ name: name, - ...content, + ...plugin, }); } else throw new Error(`${name} frontend_bundle not OK`); } diff --git a/frontend/src/tabs-hook.ts b/frontend/src/tabs-hook.ts index dd013844..de03310e 100644 --- a/frontend/src/tabs-hook.ts +++ b/frontend/src/tabs-hook.ts @@ -1,3 +1,6 @@ +import { afterPatch, sleep, unpatch } from 'decky-frontend-lib'; +import { memo } from 'react'; + import Logger from './logger'; declare global { @@ -11,7 +14,7 @@ declare global { const isTabsArray = (tabs: any) => { const length = tabs.length; - return length === 7 && tabs[length - 1]?.key === 6 && tabs[length - 1]?.tab; + return length >= 7 && tabs[length - 1]?.tab; }; interface Tab { @@ -24,24 +27,86 @@ 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; constructor() { super('TabsHook'); this.log('Initialized'); + window.__TABS_HOOK_INSTANCE?.deinit?.(); window.__TABS_HOOK_INSTANCE = this; const self = this; - - const filter = Array.prototype.__filter ?? Array.prototype.filter; - Array.prototype.__filter = filter; - Array.prototype.filter = function (...args: any[]) { - if (isTabsArray(this)) { - self.render(this); + const tree = (document.getElementById('root') as any)._reactRootContainer._internalRoot.current; + let scrollRoot: any; + let currentNode = tree; + (async () => { + let iters = 0; + while (!scrollRoot) { + iters++; + currentNode = currentNode?.child; + if (iters >= 30 || !currentNode) { + iters = 0; + currentNode = tree; + await sleep(5000); + } + if (currentNode?.type?.prototype?.RemoveSmartScrollContainer) scrollRoot = currentNode; } - // @ts-ignore - return filter.call(this, ...args); - }; + let newQA: any; + let newQATabRenderer: any; + 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 = (...args: any) => { + const oFilter = Array.prototype.filter; + Array.prototype.filter = function (...args: any[]) { + if (isTabsArray(this)) { + self.render(this); + } + // @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(...args); + 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; + } + return ret; + }); + this.cNode = scrollRoot; + this.cNode.stateNode.forceUpdate(); + })(); + } + + deinit() { + unpatch(this.cNode.stateNode, 'render'); + if (this.qAPTree) this.qAPTree.type = this.quickAccess; + if (this.rendererTree) this.rendererTree.type = this.tabRenderer; + if (this.cNode) this.cNode.stateNode.forceUpdate(); } add(tab: Tab) { |
