From 84c3b039c385ad872bb0f22eba7a3d2cd4a5ea10 Mon Sep 17 00:00:00 2001 From: AAGaming Date: Mon, 24 Oct 2022 19:14:56 -0400 Subject: 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 --- frontend/src/router-hook.tsx | 89 +++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 22 deletions(-) (limited to 'frontend/src/router-hook.tsx') diff --git a/frontend/src/router-hook.tsx b/frontend/src/router-hook.tsx index 8414db2c..bf3ae0cb 100644 --- a/frontend/src/router-hook.tsx +++ b/frontend/src/router-hook.tsx @@ -1,7 +1,12 @@ import { Patch, afterPatch, findModuleChild } from 'decky-frontend-lib'; -import { ReactElement, ReactNode, cloneElement, createElement, memo } from 'react'; +import { FC, ReactElement, ReactNode, cloneElement, createElement, memo } from 'react'; import type { Route } from 'react-router'; +import { + DeckyGlobalComponentsState, + DeckyGlobalComponentsStateContextProvider, + useDeckyGlobalComponentsState, +} from './components/DeckyGlobalComponentsState'; import { DeckyRouterState, DeckyRouterStateContextProvider, @@ -22,8 +27,10 @@ class RouterHook extends Logger { private memoizedRouter: any; private gamepadWrapper: any; private routerState: DeckyRouterState = new DeckyRouterState(); + private globalComponentsState: DeckyGlobalComponentsState = new DeckyGlobalComponentsState(); private wrapperPatch: Patch; private routerPatch?: Patch; + public routes?: any[]; constructor() { super('RouterHook'); @@ -42,24 +49,28 @@ class RouterHook extends Logger { let Route: new () => Route; // Used to store the new replicated routes we create to allow routes to be unpatched. - let toReplace = new Map(); - const DeckyWrapper = ({ children }: { children: ReactElement }) => { - const { routes, routePatches } = useDeckyRouterState(); - - const routeList = children.props.children[0].props.children; - + const processList = ( + routeList: any[], + routes: Map | null, + routePatches: Map>, + save: boolean, + ) => { + this.debug('Route list: ', routeList); + if (save) this.routes = routeList; let routerIndex = routeList.length; - if (!routeList[routerIndex - 1]?.length || routeList[routerIndex - 1]?.length !== routes.size) { - if (routeList[routerIndex - 1]?.length && routeList[routerIndex - 1].length !== routes.size) routerIndex--; - const newRouterArray: ReactElement[] = []; - routes.forEach(({ component, props }, path) => { - newRouterArray.push( - - {createElement(component)} - , - ); - }); - routeList[routerIndex] = newRouterArray; + if (routes) { + if (!routeList[routerIndex - 1]?.length || routeList[routerIndex - 1]?.length !== routes.size) { + if (routeList[routerIndex - 1]?.length && routeList[routerIndex - 1].length !== routes.size) routerIndex--; + const newRouterArray: ReactElement[] = []; + routes.forEach(({ component, props }, path) => { + newRouterArray.push( + + {createElement(component)} + , + ); + }); + routeList[routerIndex] = newRouterArray; + } } routeList.forEach((route: Route, index: number) => { const replaced = toReplace.get(route?.props?.path as string); @@ -85,19 +96,40 @@ class RouterHook extends Logger { }); } }); + }; + let toReplace = new Map(); + const DeckyWrapper = ({ children }: { children: ReactElement }) => { + const { routes, routePatches } = useDeckyRouterState(); + const mainRouteList = children.props.children[0].props.children; + const ingameRouteList = children.props.children[1].props.children; // /appoverlay and /apprunning + processList(mainRouteList, routes, routePatches, true); + processList(ingameRouteList, null, routePatches, false); + this.debug('Rerendered routes list'); return children; }; + let renderedComponents: ReactElement[] = []; + + const DeckyGlobalComponentsWrapper = () => { + const { components } = useDeckyGlobalComponentsState(); + if (renderedComponents.length != components.size) { + this.debug('Rerendering global components'); + renderedComponents = Array.from(components.values()).map((GComponent) => ); + } + return <>{renderedComponents}; + }; + this.wrapperPatch = afterPatch(this.gamepadWrapper, 'render', (_: any, ret: any) => { - if (ret?.props?.children?.props?.children?.length == 5) { + if (ret?.props?.children?.props?.children?.length == 5 || ret?.props?.children?.props?.children?.length == 4) { + const idx = ret?.props?.children?.props?.children?.length == 4 ? 1 : 2; if ( - ret.props.children.props.children[2]?.props?.children?.[0]?.type?.type + ret.props.children.props.children[idx]?.props?.children?.[0]?.type?.type ?.toString() ?.includes('GamepadUI.Settings.Root()') ) { if (!this.router) { - this.router = ret.props.children.props.children[2]?.props?.children?.[0]?.type; + this.router = ret.props.children.props.children[idx]?.props?.children?.[0]?.type; this.routerPatch = afterPatch(this.router, 'type', (_: any, ret: any) => { if (!Route) Route = ret.props.children[0].props.children.find((x: any) => x.props.path == '/createaccount').type; @@ -111,7 +143,12 @@ class RouterHook extends Logger { this.memoizedRouter = memo(this.router.type); this.memoizedRouter.isDeckyRouter = true; } - ret.props.children.props.children[2].props.children[0].type = this.memoizedRouter; + ret.props.children.props.children.push( + + + , + ); + ret.props.children.props.children[idx].props.children[0].type = this.memoizedRouter; } } return ret; @@ -126,6 +163,14 @@ class RouterHook extends Logger { return this.routerState.addPatch(path, patch); } + addGlobalComponent(name: string, component: FC) { + this.globalComponentsState.addComponent(name, component); + } + + removeGlobalComponent(name: string) { + this.globalComponentsState.removeComponent(name); + } + removePatch(path: string, patch: RoutePatch) { this.routerState.removePatch(path, patch); } -- cgit v1.2.3