mirror of
https://github.com/SteamDeckHomebrew/decky-frontend-lib.git
synced 2026-05-24 03:48:48 +02:00
Compare commits
1 Commits
v0.2.0
...
aa/patcher
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b94a595659 |
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["@commitlint/config-conventional"]
|
|
||||||
}
|
|
||||||
29
.github/workflows/release.yaml
vendored
29
.github/workflows/release.yaml
vendored
@@ -1,29 +0,0 @@
|
|||||||
name: Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
name: Release
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- name: Setup | Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup | Node.js
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
- name: Setup | Dependencies
|
|
||||||
run: npm ci
|
|
||||||
- name: Test
|
|
||||||
run: npm test
|
|
||||||
- name: Release
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
||||||
run: npm exec semantic-release
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -35,6 +35,3 @@ Thumbs.db
|
|||||||
dist/
|
dist/
|
||||||
|
|
||||||
research/
|
research/
|
||||||
|
|
||||||
# PNPM lockfile
|
|
||||||
pnpm-lock.yaml
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
. "$(dirname -- "$0")/_/husky.sh"
|
|
||||||
|
|
||||||
npx --no -- commitlint --edit "${1}"
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"branches": ["main", "dev"],
|
|
||||||
"plugins": [
|
|
||||||
"@semantic-release/commit-analyzer",
|
|
||||||
"@semantic-release/release-notes-generator",
|
|
||||||
"@semantic-release/changelog",
|
|
||||||
"@semantic-release/npm",
|
|
||||||
"@semantic-release/github",
|
|
||||||
[
|
|
||||||
"@semantic-release/git",
|
|
||||||
{
|
|
||||||
"assets": ["CHANGELOG.md", "package.json"],
|
|
||||||
"message": "chore(release): ${nextRelease.version} [CI SKIP]"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,13 +0,0 @@
|
|||||||
# [0.2.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.1.0...v0.2.0) (2022-06-04)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **router:** expose GetQuickAccessTab and rename QuickAccessTabs to QuickAccessTab ([bf0c2b1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/bf0c2b17bfc4e67a8aa90cfee6a91bd1482720d4))
|
|
||||||
|
|
||||||
# [0.1.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.0.6...v0.1.0) (2022-06-04)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **router:** types for steam router ([62bf0ea](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/62bf0eaffa83d85245a038ffe3819315bd02f045))
|
|
||||||
5
globals.d.ts
vendored
5
globals.d.ts
vendored
@@ -1,5 +0,0 @@
|
|||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
SP_REACT: typeof React;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
12424
package-lock.json
generated
12424
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "decky-frontend-lib",
|
"name": "decky-frontend-lib",
|
||||||
"version": "0.2.0",
|
"version": "0.0.2",
|
||||||
"description": "A library for building decky plugins",
|
"description": "A library for building decky plugins",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
@@ -9,9 +9,7 @@
|
|||||||
"build": "shx rm -rf dist && tsc -b",
|
"build": "shx rm -rf dist && tsc -b",
|
||||||
"dev": "tsc -b -w",
|
"dev": "tsc -b -w",
|
||||||
"prepack": "npm run build",
|
"prepack": "npm run build",
|
||||||
"test": "echo 'No tests for now!'",
|
"test": "jest"
|
||||||
"postinstall": "husky install",
|
|
||||||
"commit": "git-cz"
|
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"/lib",
|
"/lib",
|
||||||
@@ -34,26 +32,12 @@
|
|||||||
"url": "https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues"
|
"url": "https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/SteamDeckHomebrew/decky-frontend-lib#readme",
|
"homepage": "https://github.com/SteamDeckHomebrew/decky-frontend-lib#readme",
|
||||||
"config": {
|
|
||||||
"commitizen": {
|
|
||||||
"path": "@commitlint/cz-commitlint"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.0.2",
|
|
||||||
"@commitlint/config-conventional": "^17.0.2",
|
|
||||||
"@commitlint/cz-commitlint": "^17.0.0",
|
|
||||||
"@semantic-release/changelog": "^6.0.1",
|
|
||||||
"@semantic-release/git": "^10.0.1",
|
|
||||||
"@types/jest": "^27.4.1",
|
"@types/jest": "^27.4.1",
|
||||||
"@types/react": "16.14.0",
|
"@types/react": "16.14.0",
|
||||||
"@types/react-router": "5.1.18",
|
|
||||||
"commitizen": "^4.2.4",
|
|
||||||
"husky": "^8.0.1",
|
|
||||||
"import-sort-style-module": "^6.0.0",
|
"import-sort-style-module": "^6.0.0",
|
||||||
"jest": "^27.5.1",
|
"jest": "^27.5.1",
|
||||||
"prettier-plugin-import-sort": "^0.0.7",
|
"prettier-plugin-import-sort": "^0.0.7",
|
||||||
"semantic-release": "^19.0.2",
|
|
||||||
"shx": "^0.3.4",
|
"shx": "^0.3.4",
|
||||||
"ts-jest": "^27.1.4",
|
"ts-jest": "^27.1.4",
|
||||||
"typescript": "^4.6.3"
|
"typescript": "^4.6.3"
|
||||||
|
|||||||
2899
pnpm-lock.yaml
generated
Normal file
2899
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,27 +3,14 @@ import { FC } from 'react';
|
|||||||
import { CommonUIModule } from '../webpack';
|
import { CommonUIModule } from '../webpack';
|
||||||
|
|
||||||
interface ButtonProps {
|
interface ButtonProps {
|
||||||
className?: string;
|
label?: string;
|
||||||
noFocusRing?: boolean;
|
description?: string;
|
||||||
disabled?: boolean;
|
layout?: 'below';
|
||||||
onClick?(e: MouseEvent): void;
|
onClick?(e: MouseEvent): void;
|
||||||
onPointerDown?(e: PointerEvent): void;
|
disabled?: boolean;
|
||||||
onPointerUp?(e: PointerEvent): void;
|
bottomSeparator?: boolean;
|
||||||
onPointerCancel?(e: PointerEvent): void;
|
|
||||||
onMouseDown?(e: PointerEvent): void;
|
|
||||||
onMouseUp?(e: MouseEvent): void;
|
|
||||||
onTouchStart?(e: TouchEvent): void;
|
|
||||||
onTouchEnd?(e: TouchEvent): void;
|
|
||||||
onTouchCancel?(e: TouchEvent): void;
|
|
||||||
onSubmit?(e: SubmitEvent): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DialogButton = Object.values(CommonUIModule).find(
|
export const Button = Object.values(CommonUIModule).find((mod: any) =>
|
||||||
(mod: any) =>
|
mod?.render?.toString()?.includes('childrenContainerWidth:"min"'),
|
||||||
mod?.render?.toString()?.includes('Object.assign({type:"button"') &&
|
) as FC<ButtonProps>;
|
||||||
mod?.render?.toString()?.includes('DialogButton'),
|
|
||||||
) as any;
|
|
||||||
|
|
||||||
// Button isn't exported, so call DialogButton to grab it
|
|
||||||
|
|
||||||
export const Button = DialogButton!.render({}).type as FC<ButtonProps>; // its actually a forwarded ref but that doesn't really matter in usage
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
|
|
||||||
import { CommonUIModule } from '../webpack';
|
|
||||||
|
|
||||||
interface ButtonItemProps {
|
|
||||||
label?: string;
|
|
||||||
description?: string;
|
|
||||||
layout?: 'below';
|
|
||||||
icon?: JSX.Element;
|
|
||||||
onClick?(e: MouseEvent): void;
|
|
||||||
disabled?: boolean;
|
|
||||||
bottomSeparator?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ButtonItem = Object.values(CommonUIModule).find((mod: any) =>
|
|
||||||
mod?.render?.toString()?.includes('childrenContainerWidth:"min"'),
|
|
||||||
) as FC<ButtonItemProps>;
|
|
||||||
11
src/deck-components/Menu.tsx
Executable file → Normal file
11
src/deck-components/Menu.tsx
Executable file → Normal file
@@ -1,16 +1,7 @@
|
|||||||
import { FC, ReactNode } from 'react';
|
import { FC } from 'react';
|
||||||
|
|
||||||
import { findModuleChild } from '../webpack';
|
import { findModuleChild } from '../webpack';
|
||||||
|
|
||||||
export const showContextMenu: (children: ReactNode, parent?: EventTarget) => void = findModuleChild((m) => {
|
|
||||||
if (typeof m !== 'object') return undefined;
|
|
||||||
for (let prop in m) {
|
|
||||||
if (typeof m[prop] === 'function' && m[prop].toString().includes('stopPropagation))')) {
|
|
||||||
return m[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
interface MenuProps {
|
interface MenuProps {
|
||||||
label: string;
|
label: string;
|
||||||
onCancel?(): void;
|
onCancel?(): void;
|
||||||
|
|||||||
24
src/deck-components/Modal.tsx
Executable file → Normal file
24
src/deck-components/Modal.tsx
Executable file → Normal file
@@ -1,28 +1,12 @@
|
|||||||
import { FC, ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
import { findModuleChild } from '../webpack';
|
import { findModuleChild } from '../webpack';
|
||||||
|
|
||||||
// TODO: there is another argument, figure out what it does
|
export const showModal: (children: ReactNode, parent: EventTarget) => void = findModuleChild((m) => {
|
||||||
export const showModal: (children: ReactNode, parent?: EventTarget) => void = findModuleChild((m) => {
|
|
||||||
if (typeof m !== 'object') return undefined;
|
if (typeof m !== 'object') return undefined;
|
||||||
for (let prop in m) {
|
for (let prop in m) {
|
||||||
if (typeof m[prop] === 'function' && m[prop].toString().includes('bHideMainWindowForPopouts:!0')) {
|
if (typeof m[prop] === 'function' && m[prop].toString().includes('stopPropagation))')) {
|
||||||
return m[prop];
|
return m[prop];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
interface ModalRootProps {
|
|
||||||
onMiddleButton?(): void,
|
|
||||||
onCancel?(): void;
|
|
||||||
onOK?(): void;
|
|
||||||
bAllowFullSize?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ModalRoot = findModuleChild(m => {
|
|
||||||
if (typeof m !== "object") return undefined;
|
|
||||||
for (let prop in m) {
|
|
||||||
if (!m[prop]?.prototype?.OK && m[prop]?.prototype?.Cancel && m[prop]?.prototype?.render) {
|
|
||||||
return m[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) as FC<ModalRootProps>;
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
|
|
||||||
import { findModuleChild } from '../webpack';
|
|
||||||
|
|
||||||
interface PanelSectionProps {
|
|
||||||
title?: string;
|
|
||||||
spinner?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [panelSection, mod] = findModuleChild((mod: any) => {
|
|
||||||
for (let prop in mod) {
|
|
||||||
if (mod[prop]?.toString()?.includes('.PanelSection')) {
|
|
||||||
return [mod[prop], mod];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
export const PanelSection = panelSection as FC<PanelSectionProps>;
|
|
||||||
|
|
||||||
export const PanelSectionRow = Object.values(mod).filter(
|
|
||||||
(exp: any) => !exp?.toString()?.includes('.PanelSection'),
|
|
||||||
)[0] as FC;
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
import { Module, findModuleChild } from '../webpack';
|
|
||||||
|
|
||||||
export enum SideMenu {
|
|
||||||
None,
|
|
||||||
Main,
|
|
||||||
QuickAccess,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum QuickAccessTab {
|
|
||||||
Notifications,
|
|
||||||
RemotePlayTogetherControls,
|
|
||||||
VoiceChat,
|
|
||||||
Friends,
|
|
||||||
Settings,
|
|
||||||
Perf,
|
|
||||||
Help,
|
|
||||||
Decky,
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Router {
|
|
||||||
CloseSideMenus(): void;
|
|
||||||
OpenQuickAccessMenu(quickAccessTab: QuickAccessTab): void;
|
|
||||||
GetQuickAccessTab(): QuickAccessTab;
|
|
||||||
NavigateToExternalWeb(url: string): void;
|
|
||||||
ToggleSideMenu(sideMenu: SideMenu): void;
|
|
||||||
CloseSideMenus(): void;
|
|
||||||
OpenSideMenu(sideMenu: SideMenu): void;
|
|
||||||
OpenPowerMenu(unknown?: any): void;
|
|
||||||
get RunningApps(): any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Router = findModuleChild((m: Module) => {
|
|
||||||
if (typeof m !== 'object') return undefined;
|
|
||||||
for (let prop in m) {
|
|
||||||
if (m[prop]?.Navigate && m[prop]?.NavigationManager) return m[prop];
|
|
||||||
}
|
|
||||||
}) as Router;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
|
|
||||||
import { IconsModule } from '../webpack';
|
|
||||||
|
|
||||||
// TODO type this and other icons?
|
|
||||||
export const Spinner = Object.values(IconsModule).find((mod: any) =>
|
|
||||||
mod?.toString && /Spinner\)}\),.\.createElement\(\"path\",{d:\"M18 /.test(mod.toString())
|
|
||||||
) as FC<{}>;
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { findModuleChild } from '../webpack';
|
|
||||||
|
|
||||||
export const SteamSpinner = findModuleChild((m) => {
|
|
||||||
if (typeof m !== "object") return undefined;
|
|
||||||
for (let prop in m) {
|
|
||||||
if (m[prop]?.toString()?.includes("Steam Spinner") && m[prop].toString().includes("PreloadThrobber")) return m[prop]
|
|
||||||
}
|
|
||||||
}) as FC<{}>;
|
|
||||||
5
src/deck-components/index.ts
Executable file → Normal file
5
src/deck-components/index.ts
Executable file → Normal file
@@ -1,11 +1,6 @@
|
|||||||
export * from './Button';
|
export * from './Button';
|
||||||
export * from './ButtonItem';
|
|
||||||
export * from './Menu';
|
export * from './Menu';
|
||||||
export * from './Modal';
|
export * from './Modal';
|
||||||
export * from './Panel';
|
|
||||||
export * from './Router';
|
|
||||||
export * from './Slider';
|
export * from './Slider';
|
||||||
export * from './Spinner';
|
|
||||||
export * from './static-classes';
|
export * from './static-classes';
|
||||||
export * from './SteamSpinner';
|
|
||||||
export * from './Toggle';
|
export * from './Toggle';
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import type { ComponentType } from 'react';
|
|
||||||
import { RouteProps } from 'react-router';
|
|
||||||
|
|
||||||
export interface Plugin {
|
export interface Plugin {
|
||||||
title: JSX.Element;
|
title: JSX.Element;
|
||||||
icon: JSX.Element;
|
icon: JSX.Element;
|
||||||
@@ -20,13 +17,7 @@ interface ServerResponseError {
|
|||||||
|
|
||||||
type ServerResponse<TRes> = ServerResponseSuccess<TRes> | ServerResponseError;
|
type ServerResponse<TRes> = ServerResponseSuccess<TRes> | ServerResponseError;
|
||||||
|
|
||||||
interface RouterHook {
|
|
||||||
addRoute(path: string, component: ComponentType, props?: Omit<RouteProps, 'path' | 'children'>): void;
|
|
||||||
removeRoute(path: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ServerAPI {
|
export interface ServerAPI {
|
||||||
routerHook: RouterHook;
|
|
||||||
callPluginMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
|
callPluginMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
|
||||||
callServerMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
|
callServerMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
|
||||||
fetchNoCors<TRes = {}>(url: string, request: RequestInfo): Promise<ServerResponse<TRes>>;
|
fetchNoCors<TRes = {}>(url: string, request: RequestInfo): Promise<ServerResponse<TRes>>;
|
||||||
|
|||||||
44
src/utils.ts
44
src/utils.ts
@@ -1,41 +1,35 @@
|
|||||||
import * as React from "react";
|
export function sleep(ms: number): Promise<void> {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
// this shouldn't need to be redeclared but it does for some reason
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
SP_REACT: typeof React;
|
SP_REACT: any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fakeRenderComponent(fun: Function): any {
|
export function fakeRenderComponent(fun: Function): any {
|
||||||
const hooks = (window.SP_REACT as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current;
|
const hooks = window.SP_REACT.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current;
|
||||||
|
|
||||||
// TODO: add more hooks
|
// TODO: add more hooks
|
||||||
|
|
||||||
let oldHooks = {
|
let oldHooks = {
|
||||||
useContext: hooks.useContext,
|
useContext: hooks.useContext,
|
||||||
useCallback: hooks.useCallback,
|
useCallback: hooks.useCallback,
|
||||||
useLayoutEffect: hooks.useLayoutEffect,
|
|
||||||
useEffect: hooks.useEffect,
|
useEffect: hooks.useEffect,
|
||||||
useMemo: hooks.useMemo,
|
|
||||||
useRef: hooks.useRef,
|
|
||||||
useState: hooks.useState,
|
useState: hooks.useState,
|
||||||
}
|
}
|
||||||
|
|
||||||
hooks.useCallback = (cb: Function) => cb;
|
hooks.useCallback = (cb: Function) => cb;
|
||||||
hooks.useContext = (cb: any) => cb._currentValue;
|
hooks.useContext = (cb: Function) => cb;
|
||||||
hooks.useLayoutEffect = (_: Function) => {}//cb();
|
hooks.useEffect = (cb: Function) => cb();
|
||||||
hooks.useMemo = (cb: Function, _: any[]) => cb;
|
|
||||||
hooks.useEffect = (_: Function) => {}//cb();
|
|
||||||
hooks.useRef = (val: any) => ({current: val || {}});
|
|
||||||
hooks.useState = (v: any) => {
|
hooks.useState = (v: any) => {
|
||||||
let val = v;
|
let val = v;
|
||||||
|
|
||||||
return [val, (n: any) => val = n];
|
return [val, (n: any) => val = n];
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = fun(hooks);
|
const res = fun();
|
||||||
|
|
||||||
Object.assign(hooks, oldHooks);
|
Object.assign(hooks, oldHooks);
|
||||||
|
|
||||||
@@ -56,8 +50,8 @@ export function beforePatch(obj: any, name: string, fnc: Function): void {
|
|||||||
export function afterPatch(obj: any, name: string, fnc: Function): void {
|
export function afterPatch(obj: any, name: string, fnc: Function): void {
|
||||||
const orig = obj[name];
|
const orig = obj[name];
|
||||||
obj[name] = function (...args: any[]) {
|
obj[name] = function (...args: any[]) {
|
||||||
let ret = orig.call(this, ...args);
|
let ret = orig.apply(...args);
|
||||||
ret = fnc.call(this, args, ret);
|
ret = fnc(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
Object.assign(obj[name], orig);
|
Object.assign(obj[name], orig);
|
||||||
@@ -65,23 +59,7 @@ export function afterPatch(obj: any, name: string, fnc: Function): void {
|
|||||||
obj[name].__deckyOrig = orig;
|
obj[name].__deckyOrig = orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function replacePatch(obj: any, name: string, fnc: Function): void {
|
|
||||||
const orig = obj[name];
|
|
||||||
obj[name] = function (...args: any[]) {
|
|
||||||
const ret = fnc.call(this, args);
|
|
||||||
if (ret == 'CALL_ORIGINAL') return orig.call(this, ...args);
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
Object.assign(obj[name], orig);
|
|
||||||
obj[name].toString = () => orig.toString();
|
|
||||||
obj[name].__deckyOrig = orig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO allow one method to be patched and unpatched multiple times independently using IDs in a Map or something
|
// TODO allow one method to be patched and unpatched multiple times independently using IDs in a Map or something
|
||||||
export function unpatch(obj: any, name: any): void {
|
export function unpatch(obj: any, name: any): void {
|
||||||
obj[name] = obj[name].__deckyOrig;
|
obj[name] = obj[name].__deckyOrig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getReactInstance(o: HTMLElement | Element | Node) {
|
|
||||||
return o[Object.keys(o).find(k => k.startsWith('__reactInternalInstance')) as string]
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ declare global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
export type Module = any;
|
type Module = any;
|
||||||
type FilterFn = (module: any) => boolean;
|
type FilterFn = (module: any) => boolean;
|
||||||
type FindFn = (module: any) => any;
|
type FindFn = (module: any) => any;
|
||||||
|
|
||||||
@@ -58,18 +58,7 @@ export const CommonUIModule = allModules.find((m: Module) => {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
export const IconsModule = findModule((m: Module) => {
|
export const Router = findModuleChild((m: Module) => {
|
||||||
if (typeof m !== 'object') return false;
|
if (typeof m !== "object") return undefined;
|
||||||
for (let prop in m) {
|
for (let prop in m) { if (m[prop]?.Navigate && m[prop]?.NavigationManager) return m[prop]}
|
||||||
if (m[prop]?.toString && /Spinner\)}\),.\.createElement\(\"path\",{d:\"M18 /.test(m[prop].toString())) return true;
|
})
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ReactRouter = allModules.find((m: Module) => {
|
|
||||||
if (typeof m !== 'object') return undefined;
|
|
||||||
for (let prop in m) {
|
|
||||||
if (m[prop]?.computeRootMatch) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
@@ -3,8 +3,7 @@
|
|||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"jsx": "react",
|
"jsx": "react-jsx",
|
||||||
"jsxFactory": "window.SP_REACT.createElement",
|
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
@@ -18,6 +17,6 @@
|
|||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"skipLibCheck": true
|
"skipLibCheck": true
|
||||||
},
|
},
|
||||||
"include": ["src", "globals.d.ts"],
|
"include": ["src"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user