summaryrefslogtreecommitdiff
path: root/frontend/src/router-hook.tsx
diff options
context:
space:
mode:
authorAAGaming <aa@mail.catvibers.me>2022-10-24 19:14:56 -0400
committerGitHub <noreply@github.com>2022-10-24 16:14:56 -0700
commit84c3b039c385ad872bb0f22eba7a3d2cd4a5ea10 (patch)
tree20b13066c6256cc6ca1beac085094c7964226a37 /frontend/src/router-hook.tsx
parent2e6b3834da357c7e81821ce60bad36f54dd9fa6e (diff)
downloaddecky-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/router-hook.tsx')
-rw-r--r--frontend/src/router-hook.tsx89
1 files changed, 67 insertions, 22 deletions
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,8 +1,13 @@
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,
RoutePatch,
@@ -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<string, ReactNode>();
- const DeckyWrapper = ({ children }: { children: ReactElement }) => {
- const { routes, routePatches } = useDeckyRouterState();
-
- const routeList = children.props.children[0].props.children;
-
+ const processList = (
+ routeList: any[],
+ routes: Map<string, RouterEntry> | null,
+ routePatches: Map<string, Set<RoutePatch>>,
+ 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(
- <Route path={path} {...props}>
- {createElement(component)}
- </Route>,
- );
- });
- 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(
+ <Route path={path} {...props}>
+ {createElement(component)}
+ </Route>,
+ );
+ });
+ 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<string, ReactNode>();
+ 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) => <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(
+ <DeckyGlobalComponentsStateContextProvider deckyGlobalComponentsState={this.globalComponentsState}>
+ <DeckyGlobalComponentsWrapper />
+ </DeckyGlobalComponentsStateContextProvider>,
+ );
+ 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);
}