mirror of
https://github.com/SteamDeckHomebrew/decky-frontend-lib.git
synced 2026-05-20 10:00:08 +02:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4f2fb5fd2 | ||
|
|
0511f6a5c7 | ||
|
|
ff0afedc07 | ||
|
|
4dc40109ac | ||
|
|
29e6439115 | ||
|
|
a8eeb917e2 | ||
|
|
17b99dfed8 | ||
|
|
9ef419cee1 | ||
|
|
5aad952936 | ||
|
|
c2b0fad298 | ||
|
|
4d4cfedfe0 | ||
|
|
bb12921863 | ||
|
|
223739af25 | ||
|
|
95d977df45 |
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
- name: Setup | Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- name: Setup | Dependencies
|
||||
run: npm i -g pnpm && pnpm i --frozen-lockfile
|
||||
- name: Build
|
||||
|
||||
33
CHANGELOG.md
33
CHANGELOG.md
@@ -1,3 +1,36 @@
|
||||
# [3.25.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.24.5...v3.25.0) (2024-03-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **staticclasses:** unbreak on latest beta ([17b99df](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/17b99dfed8e4e146d0f4f5e78a950db5b10ae2b4))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **classMapper:** add class mapper ([a8eeb91](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/a8eeb917e22ef72905d448e159d70375ebf77ba6))
|
||||
|
||||
## [3.24.5](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.24.4...v3.24.5) (2024-02-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **finds:** make modal and scroll components work on latest betaa ([c2b0fad](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/c2b0fad298512aa8778c677275bd497bd8f7b00e))
|
||||
|
||||
## [3.24.4](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.24.3...v3.24.4) (2024-01-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **types:** fix incorrect `as` on many components leading to any types ([bb12921](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/bb129218634b77ddb1d73b0fe38a91898073707c))
|
||||
|
||||
## [3.24.3](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.24.2...v3.24.3) (2024-01-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **router:** wait 2s if internal navigators init fails ([95d977d](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/95d977df452d3b73b007c98854deab1842fa6fbf))
|
||||
|
||||
## [3.24.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.24.1...v3.24.2) (2024-01-20)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "decky-frontend-lib",
|
||||
"version": "3.24.2",
|
||||
"version": "3.25.0",
|
||||
"description": "A library for building decky plugins",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
||||
7586
pnpm-lock.yaml
generated
7586
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
34
src/class-mapper.ts
Normal file
34
src/class-mapper.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Module, findAllModules } from "./webpack";
|
||||
|
||||
export interface ClassModule {
|
||||
[name: string]: string
|
||||
};
|
||||
|
||||
export const classMap: ClassModule[] = findAllModules((m: Module) => {
|
||||
if (typeof m == "object" && !m.__esModule) {
|
||||
const keys = Object.keys(m);
|
||||
// special case some libraries
|
||||
if (keys.length == 1 && m.version) return false;
|
||||
// special case localization
|
||||
if (keys.length > 1000 && m.AboutSettings) return false;
|
||||
|
||||
return keys.length > 0 && keys.every(k => !Object.getOwnPropertyDescriptor(m, k)?.get && typeof m[k] == "string")
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
export function findClass(name: string): string | void {
|
||||
return classMap.find(m => m?.[name])?.[name];
|
||||
}
|
||||
|
||||
export function findClassModule(filter: (module: any) => boolean) : ClassModule | void {
|
||||
return classMap.find(m => filter(m));
|
||||
}
|
||||
|
||||
export function unminifyClass(minifiedClass: string): string | void {
|
||||
for (let m of classMap) {
|
||||
for (let className of Object.keys(m)) {
|
||||
if (m[className] == minifiedClass) return className;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,9 @@ export interface ButtonItemProps extends ItemProps {
|
||||
disabled?: boolean;
|
||||
}
|
||||
export const ButtonItem =
|
||||
CommonUIModule.ButtonField ||
|
||||
(Object.values(CommonUIModule).find(
|
||||
(CommonUIModule.ButtonField ||
|
||||
Object.values(CommonUIModule).find(
|
||||
(mod: any) =>
|
||||
mod?.render?.toString()?.includes('"highlightOnFocus","childrenContainerWidth"') ||
|
||||
mod?.render?.toString()?.includes('childrenContainerWidth:"min"'),
|
||||
) as FC<ButtonItemProps>);
|
||||
mod?.render?.toString()?.includes('childrenContainerWidth:"min"'),
|
||||
)) as FC<ButtonItemProps>;
|
||||
|
||||
@@ -155,15 +155,24 @@ export const ModalRoot = (Object.values(
|
||||
}
|
||||
})) as FC<ModalRootProps>;
|
||||
|
||||
interface SimpleModalProps{
|
||||
active?: boolean,
|
||||
children: ReactNode
|
||||
interface SimpleModalProps {
|
||||
active?: boolean;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
const ModalModule = findModule((mod) => {
|
||||
if (typeof mod !== 'object' || !mod.__esModule) return undefined;
|
||||
if (mod.SimpleModal && mod.ModalPosition) return mod;
|
||||
})
|
||||
const ModalModule = findModule((mod: any) => {
|
||||
if (typeof mod !== 'object') return false;
|
||||
for (let prop in mod) {
|
||||
if (Object.keys(mod).length > 4 && mod[prop]?.toString().includes('.ModalPosition,fallback:')) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
export const SimpleModal = ModalModule.SimpleModal as FC<SimpleModalProps>
|
||||
export const ModalPosition = ModalModule.ModalPosition as FC<SimpleModalProps>
|
||||
const ModalModuleProps = ModalModule ? Object.values(ModalModule) : [];
|
||||
|
||||
export const SimpleModal = ModalModuleProps.find(prop => {
|
||||
const string = prop?.toString()
|
||||
return string?.includes(".ShowPortalModal()") && string?.includes(".OnElementReadyCallbacks.Register(")
|
||||
}) as FC<SimpleModalProps>;
|
||||
|
||||
export const ModalPosition = ModalModuleProps.find(prop => prop?.toString().includes(".ModalPosition,fallback:")) as FC<SimpleModalProps>;
|
||||
|
||||
@@ -29,5 +29,5 @@ export interface PanelSectionRowProps {
|
||||
}
|
||||
// New as of Feb 22 2023 Beta || Old
|
||||
export const PanelSectionRow =
|
||||
mod.PanelSectionRow ||
|
||||
(Object.values(mod).filter((exp: any) => !exp?.toString()?.includes('.PanelSection'))[0] as FC<PanelSectionRowProps>);
|
||||
(mod.PanelSectionRow ||
|
||||
Object.values(mod).filter((exp: any) => !exp?.toString()?.includes('.PanelSection'))[0]) as FC<PanelSectionRowProps>;
|
||||
|
||||
@@ -148,7 +148,7 @@ try {
|
||||
initInternalNavigators();
|
||||
while (!InternalNavigators?.AppProperties) {
|
||||
console.log('[DFL:Router]: Trying to init internal navigators again');
|
||||
await sleep(100);
|
||||
await sleep(2000);
|
||||
initInternalNavigators();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import { FC, ReactNode } from "react";
|
||||
import { findModuleChild, findModule } from "../webpack";
|
||||
import { FC, ReactNode } from 'react';
|
||||
|
||||
import { findModule, findModuleChild } from '../webpack';
|
||||
|
||||
const ScrollingModule = findModule((mod) => {
|
||||
if (typeof mod !== 'object' || !mod.__esModule) return undefined;
|
||||
if (mod.ScrollPanel) return mod;
|
||||
if (typeof mod !== 'object') return false;
|
||||
for (let prop in mod) {
|
||||
if (mod[prop]?.render?.toString?.().includes("{case\"x\":")) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
export const ScrollPanel: FC<{ children?: ReactNode; }> = ScrollingModule.ScrollPanel;
|
||||
const ScrollingModuleProps = ScrollingModule ? Object.values(ScrollingModule) : [];
|
||||
|
||||
export const ScrollPanelGroup: FC<{ children?: ReactNode; }> = findModuleChild((mod) => {
|
||||
if (typeof mod !== 'object' || !mod.__esModule) return undefined;
|
||||
return mod.ScrollPanelGroup;
|
||||
})
|
||||
export const ScrollPanel = ScrollingModuleProps.find((prop: any) => prop?.render?.toString?.().includes("{case\"x\":")) as FC<{ children?: ReactNode }>;
|
||||
|
||||
export const ScrollPanelGroup: FC<{ children?: ReactNode }> = findModuleChild((mod) => {
|
||||
if (typeof mod !== 'object') return undefined;
|
||||
for (let prop in mod) {
|
||||
if (mod[prop]?.render?.toString().includes(".FocusVisibleChild()),[])")) return mod[prop];
|
||||
}
|
||||
});
|
||||
@@ -112,12 +112,12 @@ try {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tabs component as used in the library and media tabs. See {@link TabsProps}
|
||||
* Tabs component as used in the library and media tabs. See {@link TabsProps}.
|
||||
* Unlike other components in `decky-frontend-lib`, this requires Decky Loader to be running.
|
||||
*/
|
||||
export const Tabs =
|
||||
oldTabs ||
|
||||
(((props: TabsProps) => {
|
||||
(oldTabs ||
|
||||
((props: TabsProps) => {
|
||||
const found = tabsComponent;
|
||||
const [tc, setTC] = useState<FC<TabsProps>>(found);
|
||||
useEffect(() => {
|
||||
@@ -131,4 +131,4 @@ export const Tabs =
|
||||
}, []);
|
||||
console.log('tc', tc);
|
||||
return tc ? createElement(tc, props) : <SteamSpinner />;
|
||||
}) as FC<TabsProps>);
|
||||
})) as FC<TabsProps>;
|
||||
|
||||
@@ -694,55 +694,56 @@ type BasicAppDetailsSectionStylerClasses = Record<
|
||||
>;
|
||||
|
||||
export const quickAccessMenuClasses: QuickAccessMenuClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.Title?.includes('quickaccessmenu'),
|
||||
(mod) => typeof mod === 'object' && mod?.Title && mod?.QuickAccessMenu && mod?.BatteryDetailsLabels,
|
||||
);
|
||||
/**
|
||||
* @depreciated please use quickAccessMenuClasses instead
|
||||
*/
|
||||
export const staticClasses = quickAccessMenuClasses;
|
||||
export const scrollPanelClasses: ScrollPanelClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.ScrollPanel?.includes('scrollpanel'),
|
||||
(mod) => typeof mod === 'object' && mod?.ScrollPanel,
|
||||
);
|
||||
/**
|
||||
* @depreciated please use scrollPanelClasses instead
|
||||
*/
|
||||
export const scrollClasses = scrollPanelClasses;
|
||||
// TODO refactor to use class mapper
|
||||
export const gamepadDialogClasses: GamepadDialogClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.GamepadDialogContent?.includes('gamepaddialog'),
|
||||
(mod) => typeof mod === 'object' && mod?.GamepadDialogContent,
|
||||
);
|
||||
export const quickAccessControlsClasses: QuickAccessControlsClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && typeof mod?.PanelSection === 'string' && mod?.PanelSection?.includes('quickaccesscontrols'),
|
||||
(mod) => typeof mod === 'object' && typeof mod?.PanelSection === 'string' && mod?.PanelSection,
|
||||
);
|
||||
export const updaterFieldClasses: UpdaterFieldClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.OOBEUpdateStatusContainer?.includes('updaterfield'),
|
||||
(mod) => typeof mod === 'object' && mod?.OOBEUpdateStatusContainer,
|
||||
);
|
||||
export const playSectionClasses: PlaySectionClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.Container?.includes('appdetailsplaysection'),
|
||||
(mod) => typeof mod === 'object' && mod?.Container,
|
||||
);
|
||||
export const gamepadSliderClasses: GamepadSliderClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.SliderControlPanelGroup?.includes('gamepadslider'),
|
||||
(mod) => typeof mod === 'object' && mod?.SliderControlPanelGroup,
|
||||
);
|
||||
export const appDetailsHeaderClasses: AppDetailsHeaderClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.TopCapsule?.includes('sharedappdetailsheader'),
|
||||
(mod) => typeof mod === 'object' && mod?.TopCapsule,
|
||||
);
|
||||
export const appDetailsClasses: AppDetailsClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.HeaderLoaded?.includes('appdetails_'),
|
||||
(mod) => typeof mod === 'object' && mod?.HeaderLoaded,
|
||||
);
|
||||
export const gamepadUIClasses: GamepadUIClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.BasicUiRoot?.includes('gamepadui_'),
|
||||
(mod) => typeof mod === 'object' && mod?.BasicUiRoot,
|
||||
);
|
||||
export const gamepadTabbedPageClasses: GamepadTabbedPageClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.GamepadTabbedPage?.includes('gamepadtabbedpage_')
|
||||
(mod) => typeof mod === 'object' && mod?.GamepadTabbedPage
|
||||
);
|
||||
export const gamepadContextMenuClasses: GamepadContextMenuClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.BasicContextMenuModal?.includes('gamepadcontextmenu')
|
||||
(mod) => typeof mod === 'object' && mod?.BasicContextMenuModal
|
||||
);
|
||||
export const achievementClasses: AchievementClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.AchievementListItemBase?.includes('achievementslist')
|
||||
(mod) => typeof mod === 'object' && mod?.AchievementListItemBase
|
||||
);
|
||||
export const mainMenuAppRunningClasses: MainMenuAppRunningClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.MainMenuAppRunning?.includes('mainmenuapprunning')
|
||||
(mod) => typeof mod === 'object' && mod?.MainMenuAppRunning
|
||||
);
|
||||
export const basicAppDetailsSectionStylerClasses: BasicAppDetailsSectionStylerClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.AppDetailsRoot?.includes('basicappdetailssectionstyler_')
|
||||
(mod) => typeof mod === 'object' && mod?.AppDetailsRoot
|
||||
);
|
||||
|
||||
@@ -6,3 +6,4 @@ export * from './deck-hooks';
|
||||
export * from './plugin';
|
||||
export * from './webpack';
|
||||
export * from './utils';
|
||||
export * from './class-mapper';
|
||||
|
||||
Reference in New Issue
Block a user