mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-07-11 13:41:59 +00:00
All props of route, expose routerHook
This commit is contained in:
Generated
+52
-21
@@ -9,7 +9,7 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "GPLV2",
|
"license": "GPLV2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"decky-frontend-lib": "^0.0.3",
|
"decky-frontend-lib": "^0.0.4",
|
||||||
"react-icons": "^4.3.1"
|
"react-icons": "^4.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
"@rollup/plugin-replace": "^4.0.0",
|
"@rollup/plugin-replace": "^4.0.0",
|
||||||
"@rollup/plugin-typescript": "^8.3.2",
|
"@rollup/plugin-typescript": "^8.3.2",
|
||||||
"@types/react": "16.14.0",
|
"@types/react": "16.14.0",
|
||||||
|
"@types/react-router": "5.1.18",
|
||||||
"@types/webpack": "^5.28.0",
|
"@types/webpack": "^5.28.0",
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.1",
|
||||||
"import-sort-style-module": "^6.0.0",
|
"import-sort-style-module": "^6.0.0",
|
||||||
@@ -26,7 +27,9 @@
|
|||||||
"prettier-plugin-import-sort": "^0.0.7",
|
"prettier-plugin-import-sort": "^0.0.7",
|
||||||
"react": "16.14.0",
|
"react": "16.14.0",
|
||||||
"react-dom": "16.14.0",
|
"react-dom": "16.14.0",
|
||||||
"rollup": "^2.70.2"
|
"rollup": "^2.70.2",
|
||||||
|
"tslib": "^2.4.0",
|
||||||
|
"typescript": "^4.7.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
@@ -509,6 +512,12 @@
|
|||||||
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
|
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/history": {
|
||||||
|
"version": "4.7.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
|
||||||
|
"integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/json-schema": {
|
"node_modules/@types/json-schema": {
|
||||||
"version": "7.0.11",
|
"version": "7.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||||
@@ -537,6 +546,16 @@
|
|||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-router": {
|
||||||
|
"version": "5.1.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.18.tgz",
|
||||||
|
"integrity": "sha512-YYknwy0D0iOwKQgz9v8nOzt2J6l4gouBmDnWqUUznltOTaon+r8US8ky8HvN0tXvc38U9m6z/t2RsVsnd1zM0g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/history": "^4.7.11",
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/resolve": {
|
"node_modules/@types/resolve": {
|
||||||
"version": "1.17.1",
|
"version": "1.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
||||||
@@ -998,9 +1017,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/decky-frontend-lib": {
|
"node_modules/decky-frontend-lib": {
|
||||||
"version": "0.0.3",
|
"version": "0.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/decky-frontend-lib/-/decky-frontend-lib-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/decky-frontend-lib/-/decky-frontend-lib-0.0.4.tgz",
|
||||||
"integrity": "sha512-kOiXyUcxN4wtCsYZ/aMnNdvGL8lqM04Q9JmbzE9ykdbKq1AStn3HxE6dzOL4DukHahM/dyifLt7tTN93bDE0SA=="
|
"integrity": "sha512-FSOsvhd1TR/hgLpO98IjAm9id4SZrTwUtQcUIeoyDlJCOMH7qg18bTB+yvGBkP05nykEGuxKS5I/o4GC++F1kg=="
|
||||||
},
|
},
|
||||||
"node_modules/deepmerge": {
|
"node_modules/deepmerge": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.2",
|
||||||
@@ -2044,15 +2063,13 @@
|
|||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
|
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "4.6.4",
|
"version": "4.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz",
|
||||||
"integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
|
"integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -2532,6 +2549,12 @@
|
|||||||
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
|
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/history": {
|
||||||
|
"version": "4.7.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
|
||||||
|
"integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/json-schema": {
|
"@types/json-schema": {
|
||||||
"version": "7.0.11",
|
"version": "7.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||||
@@ -2560,6 +2583,16 @@
|
|||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-router": {
|
||||||
|
"version": "5.1.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.18.tgz",
|
||||||
|
"integrity": "sha512-YYknwy0D0iOwKQgz9v8nOzt2J6l4gouBmDnWqUUznltOTaon+r8US8ky8HvN0tXvc38U9m6z/t2RsVsnd1zM0g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/history": "^4.7.11",
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/resolve": {
|
"@types/resolve": {
|
||||||
"version": "1.17.1",
|
"version": "1.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
||||||
@@ -2946,9 +2979,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"decky-frontend-lib": {
|
"decky-frontend-lib": {
|
||||||
"version": "0.0.3",
|
"version": "0.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/decky-frontend-lib/-/decky-frontend-lib-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/decky-frontend-lib/-/decky-frontend-lib-0.0.4.tgz",
|
||||||
"integrity": "sha512-kOiXyUcxN4wtCsYZ/aMnNdvGL8lqM04Q9JmbzE9ykdbKq1AStn3HxE6dzOL4DukHahM/dyifLt7tTN93bDE0SA=="
|
"integrity": "sha512-FSOsvhd1TR/hgLpO98IjAm9id4SZrTwUtQcUIeoyDlJCOMH7qg18bTB+yvGBkP05nykEGuxKS5I/o4GC++F1kg=="
|
||||||
},
|
},
|
||||||
"deepmerge": {
|
"deepmerge": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.2",
|
||||||
@@ -3756,15 +3789,13 @@
|
|||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
|
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.6.4",
|
"version": "4.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz",
|
||||||
"integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
|
"integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"uri-js": {
|
"uri-js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"@rollup/plugin-replace": "^4.0.0",
|
"@rollup/plugin-replace": "^4.0.0",
|
||||||
"@rollup/plugin-typescript": "^8.3.2",
|
"@rollup/plugin-typescript": "^8.3.2",
|
||||||
"@types/react": "16.14.0",
|
"@types/react": "16.14.0",
|
||||||
|
"@types/react-router": "5.1.18",
|
||||||
"@types/webpack": "^5.28.0",
|
"@types/webpack": "^5.28.0",
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.1",
|
||||||
"import-sort-style-module": "^6.0.0",
|
"import-sort-style-module": "^6.0.0",
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"decky-frontend-lib": "^0.0.3",
|
"decky-frontend-lib": "^0.0.4",
|
||||||
"react-icons": "^4.3.1"
|
"react-icons": "^4.3.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
import { ComponentType, FC, createContext, useContext, useEffect, useState } from 'react';
|
import { ComponentType, FC, createContext, useContext, useEffect, useState } from 'react';
|
||||||
|
import { RouteProps } from 'react-router';
|
||||||
|
|
||||||
|
export interface RouterEntry {
|
||||||
|
props: Omit<RouteProps, 'path' | 'children'>;
|
||||||
|
component: ComponentType;
|
||||||
|
}
|
||||||
|
|
||||||
interface PublicDeckyRouterState {
|
interface PublicDeckyRouterState {
|
||||||
routes: Map<string, ComponentType>;
|
routes: Map<string, RouterEntry>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DeckyRouterState {
|
export class DeckyRouterState {
|
||||||
private _routes: Map<string, ComponentType> = new Map<string, ComponentType>();
|
private _routes = new Map<string, RouterEntry>();
|
||||||
|
|
||||||
public eventBus = new EventTarget();
|
public eventBus = new EventTarget();
|
||||||
|
|
||||||
@@ -13,8 +19,8 @@ export class DeckyRouterState {
|
|||||||
return { routes: this._routes };
|
return { routes: this._routes };
|
||||||
}
|
}
|
||||||
|
|
||||||
addRoute(path: string, render: ComponentType) {
|
addRoute(path: string, component: RouterEntry['component'], props: RouterEntry['props'] = {}) {
|
||||||
this._routes.set(path, render);
|
this._routes.set(path, { props, component });
|
||||||
this.notifyUpdate();
|
this.notifyUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +35,7 @@ export class DeckyRouterState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface DeckyRouterStateContext extends PublicDeckyRouterState {
|
interface DeckyRouterStateContext extends PublicDeckyRouterState {
|
||||||
addRoute(path: string, render: ComponentType): void;
|
addRoute(path: string, component: RouterEntry['component'], props: RouterEntry['props']): void;
|
||||||
removeRoute(path: string): void;
|
removeRoute(path: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +62,8 @@ export const DeckyRouterStateContextProvider: FC<Props> = ({ children, deckyRout
|
|||||||
return () => deckyRouterState.eventBus.removeEventListener('update', onUpdate);
|
return () => deckyRouterState.eventBus.removeEventListener('update', onUpdate);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const addRoute = (path: string, render: ComponentType) => deckyRouterState.addRoute(path, render);
|
const addRoute = (path: string, component: RouterEntry['component'], props: RouterEntry['props'] = {}) =>
|
||||||
|
deckyRouterState.addRoute(path, component, props);
|
||||||
const removeRoute = (path: string) => deckyRouterState.removeRoute(path);
|
const removeRoute = (path: string) => deckyRouterState.removeRoute(path);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class PluginLoader extends Logger {
|
|||||||
private async importReactPlugin(name: string) {
|
private async importReactPlugin(name: string) {
|
||||||
let res = await fetch(`http://127.0.0.1:1337/plugins/${name}/frontend_bundle`);
|
let res = await fetch(`http://127.0.0.1:1337/plugins/${name}/frontend_bundle`);
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
let content = await eval(await res.text())(PluginLoader.createPluginAPI(name));
|
let content = await eval(await res.text())(this.createPluginAPI(name));
|
||||||
this.plugins.push({
|
this.plugins.push({
|
||||||
name: name,
|
name: name,
|
||||||
icon: content.icon,
|
icon: content.icon,
|
||||||
@@ -82,7 +82,7 @@ class PluginLoader extends Logger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static createPluginAPI(pluginName: string) {
|
createPluginAPI(pluginName: string) {
|
||||||
return {
|
return {
|
||||||
routerHook: this.routerHook,
|
routerHook: this.routerHook,
|
||||||
async callServerMethod(methodName: string, args = {}) {
|
async callServerMethod(methodName: string, args = {}) {
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
import { afterPatch, findModuleChild, unpatch } from 'decky-frontend-lib';
|
import { afterPatch, findModuleChild, unpatch } from 'decky-frontend-lib';
|
||||||
import { FC, ReactElement, createElement } from 'react';
|
import { ReactElement, createElement, memo } from 'react';
|
||||||
|
import type { Route } from 'react-router';
|
||||||
|
|
||||||
import { DeckyRouterState, DeckyRouterStateContextProvider, useDeckyRouterState } from './components/DeckyRouterState';
|
import {
|
||||||
|
DeckyRouterState,
|
||||||
|
DeckyRouterStateContextProvider,
|
||||||
|
RouterEntry,
|
||||||
|
useDeckyRouterState,
|
||||||
|
} from './components/DeckyRouterState';
|
||||||
import Logger from './logger';
|
import Logger from './logger';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@@ -10,11 +16,6 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RouteProps {
|
|
||||||
path: string;
|
|
||||||
children: ReactElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
class RouterHook extends Logger {
|
class RouterHook extends Logger {
|
||||||
private router: any;
|
private router: any;
|
||||||
private memoizedRouter: any;
|
private memoizedRouter: any;
|
||||||
@@ -36,18 +37,22 @@ class RouterHook extends Logger {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let Route: FC<RouteProps>;
|
let Route: new () => Route;
|
||||||
const DeckyWrapper = ({ children }: { children: ReactElement }) => {
|
const DeckyWrapper = ({ children }: { children: ReactElement }) => {
|
||||||
const { routes } = useDeckyRouterState();
|
const { routes } = useDeckyRouterState();
|
||||||
|
|
||||||
const routerIndex = children.props.children[0].props.children.length - 1;
|
const routerIndex = children.props.children[0].props.children.length - 1;
|
||||||
if (
|
if (
|
||||||
!children.props.children[0].props.children[routerIndex].length ||
|
!children.props.children[0].props.children[routerIndex].length ||
|
||||||
children.props.children[0].props.children !== routes.size
|
children.props.children[0].props.children !== routes.size
|
||||||
) {
|
) {
|
||||||
const newRouterArray: ReactElement[] = [];
|
const newRouterArray: ReactElement[] = [];
|
||||||
routes.forEach((Render, path) => {
|
routes.forEach(({ component, props }, path) => {
|
||||||
newRouterArray.push(<Route path={path}>{createElement(Render)}</Route>);
|
newRouterArray.push(
|
||||||
|
<Route path={path} {...props}>
|
||||||
|
{createElement(component)}
|
||||||
|
</Route>,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
children.props.children[0].props.children[routerIndex] = newRouterArray;
|
children.props.children[0].props.children[routerIndex] = newRouterArray;
|
||||||
}
|
}
|
||||||
@@ -73,7 +78,7 @@ class RouterHook extends Logger {
|
|||||||
);
|
);
|
||||||
return returnVal;
|
return returnVal;
|
||||||
});
|
});
|
||||||
this.memoizedRouter = window.SP_REACT.memo(this.router.type);
|
this.memoizedRouter = memo(this.router.type);
|
||||||
this.memoizedRouter.isDeckyRouter = true;
|
this.memoizedRouter.isDeckyRouter = true;
|
||||||
}
|
}
|
||||||
ret.props.children.props.children[2].props.children[0].type = this.memoizedRouter;
|
ret.props.children.props.children[2].props.children[0].type = this.memoizedRouter;
|
||||||
@@ -83,6 +88,10 @@ class RouterHook extends Logger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addRoute(path: string, component: RouterEntry['component'], props: RouterEntry['props'] = {}) {
|
||||||
|
this.routerState.addRoute(path, component, props);
|
||||||
|
}
|
||||||
|
|
||||||
deinit() {
|
deinit() {
|
||||||
unpatch(this.gamepadWrapper, 'render');
|
unpatch(this.gamepadWrapper, 'render');
|
||||||
this.router && unpatch(this.router, 'type');
|
this.router && unpatch(this.router, 'type');
|
||||||
|
|||||||
Reference in New Issue
Block a user