mirror of
https://github.com/SteamDeckHomebrew/decky-frontend-lib.git
synced 2026-05-23 03:18:48 +02:00
Compare commits
1 Commits
v3.18.10
...
aa/menu-ho
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6e399fa46 |
42
CHANGELOG.md
42
CHANGELOG.md
@@ -1,45 +1,3 @@
|
|||||||
## [3.18.10](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.9...v3.18.10) (2023-01-17)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **SuspensefulImage:** fix changing src ([9723854](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/9723854ddca53d7708e1effbddec9e5ead22d5de))
|
|
||||||
|
|
||||||
## [3.18.9](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.8...v3.18.9) (2023-01-16)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **Navigation:** fix on stable ([4affd4a](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/4affd4aaec088f01d0f30af48cb4daa34acf26b1))
|
|
||||||
|
|
||||||
## [3.18.8](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.7...v3.18.8) (2023-01-16)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **Navigation:** fix timing issue in decky-loader ([58b69f0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/58b69f0d6c43356c4f0ed183802d5bf7fb80e978))
|
|
||||||
|
|
||||||
## [3.18.7](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.6...v3.18.7) (2023-01-16)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* un-break navigation on stable ([2e66e5a](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/2e66e5a555f44009d24e332eca82453ba930baf7))
|
|
||||||
|
|
||||||
## [3.18.6](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.5...v3.18.6) (2023-01-13)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **Router:** fix Navigation for the millionth time ([aac2d52](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/aac2d520a68b1074ba1ae988d6c92f7881a296d7))
|
|
||||||
|
|
||||||
## [3.18.5](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.4...v3.18.5) (2022-12-21)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* fixed prop interfaces ([#70](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/70)) ([0b50f2c](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/0b50f2cf0baa76fc00aa0a41a8435d7a512bff19))
|
|
||||||
|
|
||||||
## [3.18.4](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.3...v3.18.4) (2022-12-16)
|
## [3.18.4](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.3...v3.18.4) (2022-12-16)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "decky-frontend-lib",
|
"name": "decky-frontend-lib",
|
||||||
"version": "3.18.10",
|
"version": "3.18.4",
|
||||||
"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",
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ export const SuspensefulImage: FC<SuspensefulImageProps> = (props) => {
|
|||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
|
||||||
setError(false);
|
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.src = props.src || '';
|
img.src = props.src || '';
|
||||||
img.addEventListener('load', () => {
|
img.addEventListener('load', () => {
|
||||||
@@ -23,7 +21,7 @@ export const SuspensefulImage: FC<SuspensefulImageProps> = (props) => {
|
|||||||
img.addEventListener('error', () => {
|
img.addEventListener('error', () => {
|
||||||
setError(true);
|
setError(true);
|
||||||
});
|
});
|
||||||
}, [props.src]);
|
}, []);
|
||||||
|
|
||||||
return loading ? (
|
return loading ? (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { CSSProperties, FC } from 'react';
|
import { CSSProperties, FC, ReactNode } from 'react';
|
||||||
|
|
||||||
import { findModuleChild } from '../webpack';
|
import { findModuleChild } from '../webpack';
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ export interface MarqueeProps {
|
|||||||
resetOnPause?: boolean;
|
resetOnPause?: boolean;
|
||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
className?: string;
|
className?: string;
|
||||||
children: React.ReactNode;
|
children: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Marquee: FC<MarqueeProps> = findModuleChild((m) => {
|
export const Marquee: FC<MarqueeProps> = findModuleChild((m) => {
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { FC, ReactNode } from 'react';
|
import { FC } from 'react';
|
||||||
|
|
||||||
import { findModuleChild } from '../webpack';
|
import { findModuleChild } from '../webpack';
|
||||||
|
|
||||||
export interface PanelSectionProps {
|
export interface PanelSectionProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
spinner?: boolean;
|
spinner?: boolean;
|
||||||
children?: ReactNode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const [panelSection, mod] = findModuleChild((mod: any) => {
|
const [panelSection, mod] = findModuleChild((mod: any) => {
|
||||||
@@ -19,10 +18,6 @@ const [panelSection, mod] = findModuleChild((mod: any) => {
|
|||||||
|
|
||||||
export const PanelSection = panelSection as FC<PanelSectionProps>;
|
export const PanelSection = panelSection as FC<PanelSectionProps>;
|
||||||
|
|
||||||
export interface PanelSectionRowProps {
|
|
||||||
children?: ReactNode
|
|
||||||
}
|
|
||||||
|
|
||||||
export const PanelSectionRow = Object.values(mod).filter(
|
export const PanelSectionRow = Object.values(mod).filter(
|
||||||
(exp: any) => !exp?.toString()?.includes('.PanelSection'),
|
(exp: any) => !exp?.toString()?.includes('.PanelSection'),
|
||||||
)[0] as FC<PanelSectionRowProps>;
|
)[0] as FC;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { sleep } from '../utils';
|
|
||||||
import { Module, findModuleChild } from '../webpack';
|
import { Module, findModuleChild } from '../webpack';
|
||||||
|
|
||||||
export enum SideMenu {
|
export enum SideMenu {
|
||||||
@@ -126,65 +125,32 @@ export interface Navigation {
|
|||||||
CloseSideMenus(): void;
|
CloseSideMenus(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export let Navigation = {} as Navigation;
|
export const Navigation = {
|
||||||
|
Navigate: Router.Navigate.bind(Router),
|
||||||
try {
|
NavigateBack: Router.WindowStore?.GamepadUIMainWindowInstance?.NavigateBack.bind(
|
||||||
(async () => {
|
Router.WindowStore.GamepadUIMainWindowInstance,
|
||||||
let InternalNavigators: any = {};
|
),
|
||||||
if (!Router.NavigateToAppProperties || (Router as unknown as any).deckyShim) {
|
NavigateToAppProperties: Router.NavigateToAppProperties.bind(Router),
|
||||||
function initInternalNavigators() {
|
NavigateToExternalWeb: Router.NavigateToExternalWeb.bind(Router),
|
||||||
try {
|
NavigateToInvites: Router.NavigateToInvites.bind(Router),
|
||||||
InternalNavigators = findModuleChild((m: any) => {
|
NavigateToChat: Router.NavigateToChat.bind(Router),
|
||||||
if (typeof m !== 'object') return undefined;
|
NavigateToLibraryTab: Router.NavigateToLibraryTab.bind(Router),
|
||||||
for (let prop in m) {
|
NavigateToLayoutPreview: Router.NavigateToLayoutPreview.bind(Router),
|
||||||
if (m[prop]?.GetNavigator) {
|
NavigateToSteamWeb: Router.WindowStore?.GamepadUIMainWindowInstance?.NavigateToSteamWeb.bind(
|
||||||
return m[prop];
|
Router.WindowStore.GamepadUIMainWindowInstance,
|
||||||
}
|
),
|
||||||
}
|
NavigateToWebRoute: Router.WindowStore?.GamepadUIMainWindowInstance?.NavigateToWebRoute.bind(
|
||||||
})?.GetNavigator();
|
Router.WindowStore.GamepadUIMainWindowInstance,
|
||||||
} catch (e) {
|
),
|
||||||
console.error('[DFL:Router]: Failed to init internal navigators, trying again');
|
OpenSideMenu: Router.WindowStore?.GamepadUIMainWindowInstance?.MenuStore.OpenSideMenu.bind(
|
||||||
}
|
Router.WindowStore.GamepadUIMainWindowInstance.MenuStore,
|
||||||
}
|
),
|
||||||
initInternalNavigators();
|
OpenQuickAccessMenu: Router.WindowStore?.GamepadUIMainWindowInstance?.MenuStore.OpenQuickAccessMenu.bind(
|
||||||
while (!InternalNavigators?.AppProperties) {
|
Router.WindowStore.GamepadUIMainWindowInstance.MenuStore,
|
||||||
console.log('[DFL:Router]: Trying to init internal navigators again');
|
),
|
||||||
await sleep(100);
|
OpenMainMenu: Router.WindowStore?.GamepadUIMainWindowInstance?.MenuStore.OpenMainMenu.bind(
|
||||||
initInternalNavigators();
|
Router.WindowStore.GamepadUIMainWindowInstance.MenuStore,
|
||||||
}
|
),
|
||||||
}
|
CloseSideMenus: Router.CloseSideMenus.bind(Router),
|
||||||
const newNavigation = {
|
OpenPowerMenu: Router.OpenPowerMenu.bind(Router),
|
||||||
Navigate: Router.Navigate.bind(Router),
|
} as Navigation;
|
||||||
NavigateBack: Router.WindowStore?.GamepadUIMainWindowInstance?.NavigateBack.bind(
|
|
||||||
Router.WindowStore.GamepadUIMainWindowInstance,
|
|
||||||
),
|
|
||||||
NavigateToAppProperties: InternalNavigators?.AppProperties || Router.NavigateToAppProperties.bind(Router),
|
|
||||||
NavigateToExternalWeb: Router.NavigateToExternalWeb.bind(Router),
|
|
||||||
NavigateToInvites: InternalNavigators?.Invites || Router.NavigateToInvites.bind(Router),
|
|
||||||
NavigateToChat: Router.NavigateToChat.bind(Router),
|
|
||||||
NavigateToLibraryTab: InternalNavigators?.LibraryTab || Router.NavigateToLibraryTab.bind(Router),
|
|
||||||
NavigateToLayoutPreview: Router.NavigateToLayoutPreview.bind(Router),
|
|
||||||
NavigateToSteamWeb: Router.WindowStore?.GamepadUIMainWindowInstance?.NavigateToSteamWeb.bind(
|
|
||||||
Router.WindowStore.GamepadUIMainWindowInstance,
|
|
||||||
),
|
|
||||||
NavigateToWebRoute: Router.WindowStore?.GamepadUIMainWindowInstance?.NavigateToWebRoute.bind(
|
|
||||||
Router.WindowStore.GamepadUIMainWindowInstance,
|
|
||||||
),
|
|
||||||
OpenSideMenu: Router.WindowStore?.GamepadUIMainWindowInstance?.MenuStore.OpenSideMenu.bind(
|
|
||||||
Router.WindowStore.GamepadUIMainWindowInstance.MenuStore,
|
|
||||||
),
|
|
||||||
OpenQuickAccessMenu: Router.WindowStore?.GamepadUIMainWindowInstance?.MenuStore.OpenQuickAccessMenu.bind(
|
|
||||||
Router.WindowStore.GamepadUIMainWindowInstance.MenuStore,
|
|
||||||
),
|
|
||||||
OpenMainMenu: Router.WindowStore?.GamepadUIMainWindowInstance?.MenuStore.OpenMainMenu.bind(
|
|
||||||
Router.WindowStore.GamepadUIMainWindowInstance.MenuStore,
|
|
||||||
),
|
|
||||||
CloseSideMenus: Router.CloseSideMenus.bind(Router),
|
|
||||||
OpenPowerMenu: Router.OpenPowerMenu.bind(Router),
|
|
||||||
} as Navigation;
|
|
||||||
|
|
||||||
Object.assign(Navigation, newNavigation);
|
|
||||||
})();
|
|
||||||
} catch (e) {
|
|
||||||
console.error('[DFL:Router]: Error initializing Navigation interface', e);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -21,6 +21,52 @@ interface ServerResponseError {
|
|||||||
|
|
||||||
export type ServerResponse<TRes> = ServerResponseSuccess<TRes> | ServerResponseError;
|
export type ServerResponse<TRes> = ServerResponseSuccess<TRes> | ServerResponseError;
|
||||||
|
|
||||||
|
export interface MainMenuItem {
|
||||||
|
/** Called when clicking this menu item, useful if you do not want to navigate to a route.
|
||||||
|
* For navigating to a route, use route instead. */
|
||||||
|
action?: () => void;
|
||||||
|
/** The route this menu item navigates to @example "/steamweb" */
|
||||||
|
route?: string;
|
||||||
|
/** Props for the route this item navigates to. Currently only used for /steamweb to determine what webpack to navigate to @example {url: 'https://store.steampowered.com/'} */
|
||||||
|
routeState?: any;
|
||||||
|
/** Label for this menu item, @example "Store" */
|
||||||
|
label: ReactNode;
|
||||||
|
/** Runs when this item is selected. Defaults to setting the focused app to null.
|
||||||
|
* If you override this you must also call the original to retain proper behaivour */
|
||||||
|
onFocus?: () => void;
|
||||||
|
/** Icon of this menu item, you probably want a react SVG node */
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CustomMainMenuItem extends MainMenuItem {
|
||||||
|
index: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MainMenuItemReactNode {
|
||||||
|
props: MainMenuItem;
|
||||||
|
type: ComponentType;
|
||||||
|
key: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OverlayReactNode {
|
||||||
|
props: MainMenuItem;
|
||||||
|
type: ComponentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ItemPatch = (item: MainMenuItemReactNode) => MainMenuItemReactNode;
|
||||||
|
export type OverlayPatch = (overlay: OverlayReactNode) => OverlayReactNode;
|
||||||
|
|
||||||
|
export interface MenuHook {
|
||||||
|
addItem(item: CustomMainMenuItem): CustomMainMenuItem;
|
||||||
|
addPatch(path: string, patch: ItemPatch): ItemPatch;
|
||||||
|
addOverlayPatch(patch: OverlayPatch): OverlayPatch;
|
||||||
|
addOverlayComponent(component: ReactNode): ReactNode;
|
||||||
|
removePatch(path: string, patch: ItemPatch): void;
|
||||||
|
removeOverlayPatch(patch: OverlayPatch): void;
|
||||||
|
removeOverlayComponent(component: ReactNode): void;
|
||||||
|
removeItem(item: CustomMainMenuItem): void;
|
||||||
|
}
|
||||||
|
|
||||||
export type RoutePatch = (route: RouteProps) => RouteProps;
|
export type RoutePatch = (route: RouteProps) => RouteProps;
|
||||||
|
|
||||||
export interface RouterHook {
|
export interface RouterHook {
|
||||||
@@ -59,6 +105,7 @@ export interface FilePickerRes {
|
|||||||
|
|
||||||
export interface ServerAPI {
|
export interface ServerAPI {
|
||||||
routerHook: RouterHook;
|
routerHook: RouterHook;
|
||||||
|
menuHook: MenuHook;
|
||||||
toaster: Toaster;
|
toaster: Toaster;
|
||||||
openFilePicker(startPath: string, includeFiles?: boolean, regex?: RegExp): Promise<FilePickerRes>;
|
openFilePicker(startPath: string, includeFiles?: boolean, regex?: RegExp): Promise<FilePickerRes>;
|
||||||
callPluginMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
|
callPluginMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
|
||||||
|
|||||||
Reference in New Issue
Block a user