From ab6ec981604a32611d972ede634abe7ccd19b0d2 Mon Sep 17 00:00:00 2001
From: AAGaming <aa@mail.catvibers.me>
Date: Tue, 2 Aug 2022 18:54:55 -0400
Subject: API for patching existing routes, lower power use

---
 frontend/src/router-hook.tsx | 50 ++++++++++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 13 deletions(-)

(limited to 'frontend/src/router-hook.tsx')

diff --git a/frontend/src/router-hook.tsx b/frontend/src/router-hook.tsx
index 4e23658e..ca2a7039 100644
--- a/frontend/src/router-hook.tsx
+++ b/frontend/src/router-hook.tsx
@@ -1,10 +1,11 @@
 import { afterPatch, findModuleChild, unpatch } from 'decky-frontend-lib';
 import { ReactElement, createElement, memo } from 'react';
-import type { Route } from 'react-router';
+import type { Route, RouteProps } from 'react-router';
 
 import {
   DeckyRouterState,
   DeckyRouterStateContextProvider,
+  RoutePatch,
   RouterEntry,
   useDeckyRouterState,
 } from './components/DeckyRouterState';
@@ -38,19 +39,16 @@ 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, Route>();
     const DeckyWrapper = ({ children }: { children: ReactElement }) => {
-      const { routes } = useDeckyRouterState();
+      const { routes, routePatches } = useDeckyRouterState();
 
-      let routerIndex = children.props.children[0].props.children.length;
-      if (
-        !children.props.children[0].props.children[routerIndex - 1]?.length ||
-        children.props.children[0].props.children[routerIndex - 1]?.length !== routes.size
-      ) {
-        if (
-          children.props.children[0].props.children[routerIndex - 1]?.length &&
-          children.props.children[0].props.children[routerIndex - 1].length !== routes.size
-        )
-          routerIndex--;
+      const routeList = children.props.children[0].props.children;
+
+      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(
@@ -59,8 +57,26 @@ class RouterHook extends Logger {
             </Route>,
           );
         });
-        children.props.children[0].props.children[routerIndex] = newRouterArray;
+        routeList[routerIndex] = newRouterArray;
       }
+      routeList.forEach((route: Route, index: number) => {
+        const replaced = toReplace.get(route?.props?.path as string);
+        if (replaced) {
+          routeList[index] = replaced;
+          toReplace.delete(route?.props?.path as string);
+        }
+        if (route?.props?.path && routePatches.has(route.props.path as string)) {
+          toReplace.set(
+            route?.props?.path as string,
+            // @ts-ignore
+            createElement(routeList[index].type, routeList[index].props, routeList[index].props.children),
+          );
+          routePatches.get(route.props.path as string)?.forEach((patch) => {
+            routeList[index].props = patch(routeList[index].props);
+          });
+        }
+      });
+      this.debug('Rerendered routes list');
       return children;
     };
 
@@ -97,6 +113,14 @@ class RouterHook extends Logger {
     this.routerState.addRoute(path, component, props);
   }
 
+  addPatch(path: string, patch: RoutePatch) {
+    return this.routerState.addPatch(path, patch);
+  }
+
+  removePatch(path: string, patch: RoutePatch) {
+    this.routerState.removePatch(path, patch);
+  }
+
   removeRoute(path: string) {
     this.routerState.removeRoute(path);
   }
-- 
cgit v1.2.3

