mirror of
https://github.com/SteamDeckHomebrew/decky-frontend-lib.git
synced 2026-05-20 18:10:08 +02:00
Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e48c7bbadd | ||
|
|
727fcc8186 | ||
|
|
dc196d53f5 | ||
|
|
f0379e5d19 | ||
|
|
fd94842647 | ||
|
|
ef6be8c6ec | ||
|
|
767dc2fcee | ||
|
|
52305987c5 | ||
|
|
6f14da152a | ||
|
|
bb291b211c | ||
|
|
88f245d476 | ||
|
|
5bc78df918 | ||
|
|
c586afb97d | ||
|
|
d9150c2556 | ||
|
|
cd0635e94f | ||
|
|
443c7850d7 | ||
|
|
d24136ecb6 | ||
|
|
55507446cc | ||
|
|
925ea8c3ce | ||
|
|
14c5210931 | ||
|
|
cc29ddaf57 | ||
|
|
1e8979b641 | ||
|
|
7ba1229a4e | ||
|
|
4c2a715324 | ||
|
|
678ba216f1 | ||
|
|
07d15f5dca | ||
|
|
c84a091469 | ||
|
|
47fd13692f | ||
|
|
2ec9519b7d | ||
|
|
24606190e0 | ||
|
|
ed98d14b37 | ||
|
|
b882612dfa | ||
|
|
32291620b4 | ||
|
|
9b368c5f11 | ||
|
|
e167ef5a13 | ||
|
|
2f3df00967 | ||
|
|
215156d316 | ||
|
|
47d75db690 | ||
|
|
82768e0415 | ||
|
|
e44187fe4b | ||
|
|
72af32436e | ||
|
|
e1f64a38de | ||
|
|
82ed48761d | ||
|
|
a81c342d2a | ||
|
|
68d630262d | ||
|
|
0bb8c67cfa | ||
|
|
edd29e6c5a | ||
|
|
0ed054fae9 | ||
|
|
0d912eac88 | ||
|
|
789e16380f | ||
|
|
88b50bbc1e | ||
|
|
75f35882f2 | ||
|
|
9c72a55aff | ||
|
|
92ffc76075 | ||
|
|
ce3860f73b | ||
|
|
d8b10a2133 | ||
|
|
1581304dcb | ||
|
|
60ddf474e0 | ||
|
|
52ae328e2e | ||
|
|
aa0fad2ecf | ||
|
|
dab9071d1e | ||
|
|
189a90ba31 | ||
|
|
8509ae8f9a | ||
|
|
a6ebfdcd7d | ||
|
|
5f7655baaf | ||
|
|
bca2dcc9bd | ||
|
|
546a4da043 |
4
.github/workflows/release.yaml
vendored
4
.github/workflows/release.yaml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
@@ -20,9 +21,12 @@ jobs:
|
||||
node-version: 16
|
||||
- name: Setup | Dependencies
|
||||
run: npm i -g pnpm && pnpm i --frozen-lockfile
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
- name: Test
|
||||
run: pnpm run test
|
||||
- name: Release
|
||||
if: github.event_name != 'pull_request'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
162
CHANGELOG.md
162
CHANGELOG.md
@@ -1,3 +1,165 @@
|
||||
## [3.18.4](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.3...v3.18.4) (2022-12-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **modals:** fix ModalRoot again ([fd94842](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/fd94842647e51dd9a104e170e0c5ee2bebce12d6))
|
||||
|
||||
## [3.18.3](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.2...v3.18.3) (2022-12-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Router:** update Router interface to SteamOS3.4 and add Navigation ([#52](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/52)) ([f0379e5](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/f0379e5d19279863b571e66918bc9107efedb612))
|
||||
|
||||
## [3.18.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.1...v3.18.2) (2022-12-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **useQuickAccessVisible:** remove invalid prop access ([#66](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/66)) ([767dc2f](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/767dc2fcee97d8b6c2d331ae29704d9b469de51a))
|
||||
|
||||
## [3.18.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.18.0...v3.18.1) (2022-12-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **findSP:** fallback to last active context ([#53](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/53)) ([6f14da1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/6f14da152acc4757b814844f1b77bf83dd98d77e))
|
||||
|
||||
# [3.18.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.17.0...v3.18.0) (2022-12-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **DialogCheckbox:** Add DialogCheckbox component ([#58](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/58)) ([88f245d](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/88f245d476a6477e9fc0cd35e9b675961ecbc26c))
|
||||
|
||||
# [3.17.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.16.2...v3.17.0) (2022-12-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **ControlsList:** Add ControlsList component ([#61](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/61)) ([c586afb](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/c586afb97d59928ecb703b5a254ed1b9405e2c7e))
|
||||
|
||||
## [3.16.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.16.1...v3.16.2) (2022-12-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Marquee:** replace default export with named export ([cd0635e](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/cd0635e94f98499f9f5fc24a7fd4b93efe7dfc38))
|
||||
|
||||
## [3.16.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.16.0...v3.16.1) (2022-12-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **FooterLegend:** change description types to ReactNode ([#62](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/62)) ([d24136e](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/d24136ecb6b0c5239b68723e8f92a4822aa7b590))
|
||||
|
||||
# [3.16.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.15.0...v3.16.0) (2022-12-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Marquee:** Add Marquee component ([#63](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/63)) ([925ea8c](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/925ea8c3ceaaf6ff2f79b8808908a9b144a4fcff))
|
||||
|
||||
# [3.15.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.14.0...v3.15.0) (2022-12-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Focusable:** add noFocusRing prop type ([#65](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/65)) ([cc29dda](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/cc29ddaf578e21ab2abe1cd266f1d15debee0637))
|
||||
|
||||
# [3.14.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.13.0...v3.14.0) (2022-12-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **toast:** add showToast/playSound to ToastData ([#64](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/64)) ([7ba1229](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/7ba1229a4e24fea587b96dc8b078200faf45ddee))
|
||||
|
||||
# [3.13.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.12.0...v3.13.0) (2022-11-29)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Menu:** add more missing props ([#60](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/60)) [CI SKIP] ([678ba21](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/678ba216f1e194986b0c391398e6f73536cd0102))
|
||||
|
||||
# [3.12.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.11.1...v3.12.0) (2022-11-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **MenuItem:** add missing props ([#59](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/59)) ([c84a091](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/c84a09146935f0942265b7a1e4aadc40e8cf22dc))
|
||||
|
||||
## [3.11.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.11.0...v3.11.1) (2022-11-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Footer:** add types for ActionDescriptionMap ([2ec9519](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/2ec9519b7d6d1cc0d232853ce05a773953b37c5a))
|
||||
|
||||
# [3.11.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.10.0...v3.11.0) (2022-11-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **classes:** add "appDetailsClasses" ([#55](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/55)) ([ed98d14](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/ed98d14b37cf09500afd88e7c8e9c03749119b38))
|
||||
|
||||
# [3.10.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.9.0...v3.10.0) (2022-11-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **classes:** add appDetailsHeaderClasses ([#54](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/54)) ([3229162](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/32291620b403f8b65cf378343454a3f2668fb6ee))
|
||||
|
||||
# [3.9.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.8.0...v3.9.0) (2022-11-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Dialog:** add "focusable" button prop ([#51](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/51)) ([e167ef5](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/e167ef5a138a3edc004db2365334f8455c177132))
|
||||
|
||||
# [3.8.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.7.14...v3.8.0) (2022-11-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **routerhook:** add global components support ([215156d](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/215156d31688faac9028627379e5a3ac4d64ec46))
|
||||
|
||||
## [3.7.14](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.7.13...v3.7.14) (2022-11-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Menu:** fix on Steam beta ([82768e0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/82768e0415d084deb2af39beb3f9273a83e819de))
|
||||
* **Modal:** fix on Steam beta ([e44187f](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/e44187fe4b9d3e3c9e94490669591599dc5246ba))
|
||||
|
||||
## [3.7.13](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.7.12...v3.7.13) (2022-11-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **useQuickAccessVisible:** make it work in beta ([#49](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/49)) ([e1f64a3](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/e1f64a38de85073e5cea74ecea4b9cde9a783ecc))
|
||||
|
||||
## [3.7.12](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.7.11...v3.7.12) (2022-10-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Item:** change title and description types to ReactNode ([0ed054f](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/0ed054fae972ffd36299b142bd693f80388480a6))
|
||||
|
||||
## [3.7.11](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.7.10...v3.7.11) (2022-10-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **package.json:** train wtf ([789e163](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/789e16380fd01a6b46188c7a1174a55c18c8dead))
|
||||
|
||||
## [3.7.10](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.7.9...v3.7.10) (2022-10-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **tabs:** shut up typescript ([75f3588](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/75f35882f27252e1255208953a6e801c68d5dcec))
|
||||
|
||||
## [3.7.9](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.7.8...v3.7.9) (2022-10-28)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "decky-frontend-lib",
|
||||
"version": "3.7.9",
|
||||
"version": "3.18.4",
|
||||
"description": "A library for building decky plugins",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
@@ -10,7 +10,6 @@
|
||||
"build": "shx rm -rf dist && tsc -b",
|
||||
"dev": "tsc -b -w",
|
||||
"docs": "typedoc --tsconfig ./tsconfig.json src/**/*",
|
||||
"prepack": "npm run build",
|
||||
"test": "echo 'No tests for now!'",
|
||||
"prepare": "husky install",
|
||||
"commit": "git-cz"
|
||||
@@ -54,6 +53,7 @@
|
||||
"husky": "^8.0.1",
|
||||
"import-sort-style-module": "^6.0.0",
|
||||
"jest": "^27.5.1",
|
||||
"minimist": "^1.2.6",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-import-sort": "^0.0.7",
|
||||
"semantic-release": "^19.0.3",
|
||||
@@ -78,8 +78,5 @@
|
||||
"style": "module",
|
||||
"parser": "typescript"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.6"
|
||||
}
|
||||
}
|
||||
|
||||
5
pnpm-lock.yaml
generated
5
pnpm-lock.yaml
generated
@@ -25,9 +25,6 @@ specifiers:
|
||||
typedoc-plugin-missing-exports: ^1.0.0
|
||||
typescript: ^4.6.3
|
||||
|
||||
dependencies:
|
||||
minimist: 1.2.6
|
||||
|
||||
devDependencies:
|
||||
'@commitlint/cli': 17.0.2
|
||||
'@commitlint/config-conventional': 17.0.2
|
||||
@@ -41,6 +38,7 @@ devDependencies:
|
||||
husky: 8.0.1
|
||||
import-sort-style-module: 6.0.0
|
||||
jest: 27.5.1
|
||||
minimist: 1.2.6
|
||||
prettier: 2.7.1
|
||||
prettier-plugin-import-sort: 0.0.7_prettier@2.7.1
|
||||
semantic-release: 19.0.3
|
||||
@@ -3735,6 +3733,7 @@ packages:
|
||||
|
||||
/minimist/1.2.6:
|
||||
resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==}
|
||||
dev: true
|
||||
|
||||
/modify-values/1.0.1:
|
||||
resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from './usequickaccessvisible';
|
||||
export * from './useQuickAccessVisible';
|
||||
|
||||
@@ -4,6 +4,17 @@ declare global {
|
||||
var FocusNavController: any;
|
||||
}
|
||||
|
||||
function getQuickAccessWindow(): Window | null {
|
||||
try {
|
||||
const context = FocusNavController?.m_ActiveContext || FocusNavController?.m_LastActiveContext;
|
||||
const navTrees = context?.m_rgGamepadNavigationTrees || FocusNavController?.m_rgGamepadNavigationTrees;
|
||||
return navTrees?.find((tree: any) => tree?.id === "QuickAccess-NA")?.m_Root?.m_element?.ownerDocument.defaultView ?? null;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns state indicating the visibility of quick access menu.
|
||||
*
|
||||
@@ -42,12 +53,10 @@ declare global {
|
||||
* };
|
||||
*/
|
||||
export function useQuickAccessVisible(): boolean {
|
||||
// Assuming that the component is rendered in QAM already, so true by default...
|
||||
const [isVisible, setIsVisible] = useState(true);
|
||||
const [isVisible, setIsVisible] = useState(getQuickAccessWindow()?.document.hasFocus() ?? true);
|
||||
|
||||
useEffect(() => {
|
||||
const quickAccessWindow: Window | null =
|
||||
FocusNavController?.GetGamepadNavTreeByID('QuickAccess-NA')?.m_Root?.m_element?.ownerDocument.defaultView ?? null;
|
||||
const quickAccessWindow = getQuickAccessWindow();
|
||||
if (quickAccessWindow === null) {
|
||||
console.error('Could not get window of QuickAccess menu!');
|
||||
return;
|
||||
17
src/deck-components/ControlsList.tsx
Normal file
17
src/deck-components/ControlsList.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { findModuleChild } from '../webpack';
|
||||
import { FC } from 'react';
|
||||
|
||||
export interface ControlsListProps {
|
||||
alignItems?: 'left' | 'right' | 'center';
|
||||
spacing?: 'standard' | 'extra';
|
||||
}
|
||||
|
||||
export const ControlsList: FC<ControlsListProps> = findModuleChild((m) => {
|
||||
if (typeof m !== 'object') return;
|
||||
for (const prop in m) {
|
||||
if (m[prop]?.toString && m[prop].toString().includes('().ControlsListChild') && m[prop].toString().includes('().ControlsListOuterPanel')) {
|
||||
return m[prop];
|
||||
}
|
||||
}
|
||||
return;
|
||||
});
|
||||
@@ -9,8 +9,35 @@ export interface DialogCommonProps extends RefAttributes<HTMLDivElement> {
|
||||
}
|
||||
|
||||
export interface DialogButtonProps extends DialogCommonProps, FooterLegendProps {
|
||||
/**
|
||||
* Enables/disables the focus around the button.
|
||||
*
|
||||
* @note
|
||||
* Default value depends on context, so setting it to `false` will enable it.
|
||||
*/
|
||||
noFocusRing?: boolean;
|
||||
|
||||
/**
|
||||
* Disables the button - assigned `on*` methods will not be invoked if clicked.
|
||||
*
|
||||
* @note
|
||||
* Depending on where it is, it might still get focus. In such case it can be
|
||||
* partially disabled separately.
|
||||
*
|
||||
* @see focusable.
|
||||
*/
|
||||
disabled?: boolean;
|
||||
|
||||
/**
|
||||
* Enables/disables the navigation based focus on button - you won't be able to navigate to
|
||||
* it via the gamepad or keyboard.
|
||||
*
|
||||
* @note
|
||||
* If set to `false`, it still can be clicked and **WILL** become focused until navigated away.
|
||||
* Depending on the context of where the button is, even a disabled button can focused.
|
||||
*/
|
||||
focusable?: boolean;
|
||||
|
||||
onClick?(e: MouseEvent): void;
|
||||
onPointerDown?(e: PointerEvent): void;
|
||||
onPointerUp?(e: PointerEvent): void;
|
||||
|
||||
33
src/deck-components/DialogCheckbox.tsx
Normal file
33
src/deck-components/DialogCheckbox.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { FC, ReactNode } from 'react';
|
||||
|
||||
import { findModule } from '../webpack';
|
||||
import { DialogCommonProps } from './Dialog';
|
||||
import { FooterLegendProps } from './FooterLegend';
|
||||
|
||||
export interface DialogCheckboxProps extends DialogCommonProps, FooterLegendProps {
|
||||
onChange?(checked: boolean): void;
|
||||
label?: ReactNode;
|
||||
description?: ReactNode;
|
||||
disabled?: boolean;
|
||||
tooltip?: string;
|
||||
color?: string;
|
||||
highlightColor?: string;
|
||||
bottomSeparator?: 'standard' | 'thick' | 'none';
|
||||
controlled?: boolean;
|
||||
checked?: boolean;
|
||||
onClick?(evt: Event): void;
|
||||
}
|
||||
|
||||
export const DialogCheckbox = Object.values(findModule((m: any) => {
|
||||
if (typeof m !== 'object') return false;
|
||||
for (const prop in m) {
|
||||
if (m[prop]?.prototype?.GetPanelElementProps) return true;
|
||||
}
|
||||
return false;
|
||||
})).find((m: any) =>
|
||||
m.contextType &&
|
||||
m.prototype?.render.toString().includes('fallback:') &&
|
||||
m?.prototype?.SetChecked &&
|
||||
m?.prototype?.Toggle &&
|
||||
m?.prototype?.GetPanelElementProps
|
||||
) as FC<DialogCheckboxProps>;
|
||||
@@ -8,6 +8,7 @@ export interface FocusableProps extends HTMLAttributes<HTMLDivElement>, FooterLe
|
||||
'flow-children'?: string;
|
||||
focusClassName?: string;
|
||||
focusWithinClassName?: string;
|
||||
noFocusRing?: boolean;
|
||||
onActivate?: (e: CustomEvent) => void;
|
||||
onCancel?: (e: CustomEvent) => void;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export enum GamepadButton {
|
||||
INVALID,
|
||||
OK,
|
||||
@@ -29,30 +31,29 @@ export enum GamepadButton {
|
||||
STEAM_GUIDE,
|
||||
STEAM_QUICK_MENU,
|
||||
}
|
||||
|
||||
export enum NavEntryPositionPreferences {
|
||||
export declare enum NavEntryPositionPreferences {
|
||||
FIRST,
|
||||
LAST,
|
||||
MAINTAIN_X,
|
||||
MAINTAIN_Y,
|
||||
PREFERRED_CHILD,
|
||||
PREFERRED_CHILD
|
||||
}
|
||||
|
||||
export interface GamepadEventDetail {
|
||||
button: number;
|
||||
is_repeat?: boolean;
|
||||
source: number;
|
||||
}
|
||||
|
||||
export type GamepadEvent = CustomEvent<GamepadEventDetail>;
|
||||
|
||||
export declare type ActionDescriptionMap = {
|
||||
[key in GamepadButton]?: ReactNode
|
||||
}
|
||||
export declare type GamepadEvent = CustomEvent<GamepadEventDetail>;
|
||||
export interface FooterLegendProps {
|
||||
actionDescriptionMap?: unknown;
|
||||
onOKActionDescription?: string;
|
||||
onCancelActionDescription?: string;
|
||||
onSecondaryActionDescription?: string;
|
||||
onOptionsActionDescription?: string;
|
||||
onMenuActionDescription?: string;
|
||||
actionDescriptionMap?: ActionDescriptionMap;
|
||||
onOKActionDescription?: ReactNode;
|
||||
onCancelActionDescription?: ReactNode;
|
||||
onSecondaryActionDescription?: ReactNode;
|
||||
onOptionsActionDescription?: ReactNode;
|
||||
onMenuActionDescription?: ReactNode;
|
||||
onButtonDown?: (evt: GamepadEvent) => void;
|
||||
onButtonUp?: (evt: GamepadEvent) => void;
|
||||
onOKButton?: (evt: GamepadEvent) => void;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export interface ItemProps {
|
||||
label?: string;
|
||||
description?: string;
|
||||
label?: ReactNode;
|
||||
description?: ReactNode;
|
||||
layout?: 'below' | 'inline';
|
||||
icon?: ReactNode;
|
||||
bottomSeparator?: 'standard' | 'thick' | 'none';
|
||||
|
||||
26
src/deck-components/Marquee.tsx
Normal file
26
src/deck-components/Marquee.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { CSSProperties, FC } from 'react';
|
||||
|
||||
import { findModuleChild } from '../webpack';
|
||||
|
||||
export interface MarqueeProps {
|
||||
play?: boolean;
|
||||
direction?: 'left' | 'right';
|
||||
speed?: number;
|
||||
delay?: number;
|
||||
fadeLength?: number;
|
||||
center?: boolean;
|
||||
resetOnPause?: boolean;
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Marquee: FC<MarqueeProps> = findModuleChild((m) => {
|
||||
if (typeof m !== 'object') return;
|
||||
for (const prop in m) {
|
||||
if (m[prop]?.toString && m[prop].toString().includes('.Marquee') && m[prop].toString().includes('--fade-length')) {
|
||||
return m[prop];
|
||||
}
|
||||
}
|
||||
return;
|
||||
});
|
||||
@@ -1,6 +1,8 @@
|
||||
import { FC, ReactNode } from 'react';
|
||||
|
||||
import { fakeRenderComponent } from '../utils';
|
||||
import { findModuleChild } from '../webpack';
|
||||
import { FooterLegendProps } from './FooterLegend';
|
||||
|
||||
export const showContextMenu: (children: ReactNode, parent?: EventTarget) => void = findModuleChild((m) => {
|
||||
if (typeof m !== 'object') return undefined;
|
||||
@@ -11,7 +13,7 @@ export const showContextMenu: (children: ReactNode, parent?: EventTarget) => voi
|
||||
}
|
||||
});
|
||||
|
||||
export interface MenuProps {
|
||||
export interface MenuProps extends FooterLegendProps {
|
||||
label: string;
|
||||
onCancel?(): void;
|
||||
cancelText?: string;
|
||||
@@ -38,15 +40,26 @@ export const MenuGroup: FC<MenuGroupProps> = findModuleChild((m) => {
|
||||
if (typeof m !== 'object') return undefined;
|
||||
|
||||
for (let prop in m) {
|
||||
if (m[prop]?.prototype?.RenderSubMenu && m[prop]?.prototype?.ShowSubMenu) {
|
||||
if (
|
||||
(m[prop]?.toString()?.includes('bInGamepadUI:') &&
|
||||
fakeRenderComponent(() => m[prop]())?.type?.prototype?.RenderSubMenu) ||
|
||||
(m[prop]?.prototype?.RenderSubMenu && m[prop]?.prototype?.ShowSubMenu)
|
||||
) {
|
||||
return m[prop];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export interface MenuItemProps {
|
||||
onSelected?(): void;
|
||||
export interface MenuItemProps extends FooterLegendProps {
|
||||
bInteractableItem?: boolean;
|
||||
onClick?(evt: Event): void;
|
||||
onSelected?(evt: Event): void;
|
||||
onMouseEnter?(evt: MouseEvent): void;
|
||||
onMoveRight?(): void;
|
||||
selected?: boolean;
|
||||
disabled?: boolean;
|
||||
bPlayAudio?: boolean;
|
||||
tone?: 'positive' | 'emphasis' | 'destructive';
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
@@ -54,7 +67,10 @@ export const MenuItem: FC<MenuItemProps> = findModuleChild((m) => {
|
||||
if (typeof m !== 'object') return undefined;
|
||||
|
||||
for (let prop in m) {
|
||||
if (m[prop]?.prototype?.OnOKButton && m[prop]?.prototype?.OnMouseEnter) {
|
||||
if (
|
||||
m[prop]?.render?.toString()?.includes('bPlayAudio:') ||
|
||||
(m[prop]?.prototype?.OnOKButton && m[prop]?.prototype?.OnMouseEnter)
|
||||
) {
|
||||
return m[prop];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { FC, ReactNode } from 'react';
|
||||
|
||||
import { findSP } from '../utils';
|
||||
import { findModuleChild } from '../webpack';
|
||||
import { findModule, findModuleChild } from '../webpack';
|
||||
|
||||
// All of the popout options + strTitle are related. Proper usage is not yet known...
|
||||
export interface ShowModalProps {
|
||||
@@ -29,7 +29,30 @@ export interface ShowModalResult {
|
||||
Update: (modal: ReactNode) => void;
|
||||
}
|
||||
|
||||
const showModalRaw: (modal: ReactNode, parent?: EventTarget, props?: ShowModalProps) => Promise<ShowModalResult> =
|
||||
const showModalRaw:
|
||||
| ((
|
||||
modal: ReactNode,
|
||||
parent?: EventTarget,
|
||||
title?: string,
|
||||
props?: ShowModalProps,
|
||||
unknown1?: unknown,
|
||||
hideActions?: { bHideActions?: boolean },
|
||||
modalManager?: unknown,
|
||||
) => ShowModalResult)
|
||||
| void = findModuleChild((m) => {
|
||||
if (typeof m !== 'object') return undefined;
|
||||
for (let prop in m) {
|
||||
if (
|
||||
typeof m[prop] === 'function' &&
|
||||
m[prop].toString().includes('props.bDisableBackgroundDismiss') &&
|
||||
!m[prop]?.prototype?.Cancel
|
||||
) {
|
||||
return m[prop];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const oldShowModalRaw: ((modal: ReactNode, parent?: EventTarget, props?: ShowModalProps) => ShowModalResult) | void =
|
||||
findModuleChild((m) => {
|
||||
if (typeof m !== 'object') return undefined;
|
||||
for (let prop in m) {
|
||||
@@ -39,8 +62,23 @@ const showModalRaw: (modal: ReactNode, parent?: EventTarget, props?: ShowModalPr
|
||||
}
|
||||
});
|
||||
|
||||
export const showModal = (modal: ReactNode, parent?: EventTarget, props?: ShowModalProps): Promise<ShowModalResult> => {
|
||||
return showModalRaw(modal, parent || findSP(), props);
|
||||
export const showModal = (
|
||||
modal: ReactNode,
|
||||
parent?: EventTarget,
|
||||
props: ShowModalProps = {
|
||||
strTitle: 'Decky Dialog',
|
||||
bHideMainWindowForPopouts: false,
|
||||
},
|
||||
): ShowModalResult => {
|
||||
if (showModalRaw) {
|
||||
return showModalRaw(modal, parent || findSP(), props.strTitle, props, undefined, {
|
||||
bHideActions: props.bHideActionIcons,
|
||||
});
|
||||
} else if (oldShowModalRaw) {
|
||||
return oldShowModalRaw(modal, parent || findSP(), props);
|
||||
} else {
|
||||
throw new Error('[DFL:Modals]: Cannot find showModal function');
|
||||
}
|
||||
};
|
||||
|
||||
export interface ModalRootProps {
|
||||
@@ -79,11 +117,40 @@ export const ConfirmModal = findModuleChild((m) => {
|
||||
}
|
||||
}) as FC<ConfirmModalProps>;
|
||||
|
||||
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];
|
||||
// new as of december 2022 on beta
|
||||
export const ModalRoot = (Object.values(
|
||||
findModule((m: any) => {
|
||||
if (typeof m !== 'object') return false;
|
||||
|
||||
for (let prop in m) {
|
||||
if (m[prop]?.m_mapModalManager) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}) as FC<ModalRootProps>;
|
||||
|
||||
return false;
|
||||
}) || {},
|
||||
)?.find((x: any) => x?.type?.toString()?.includes('((function(){')) ||
|
||||
// before december 2022 beta
|
||||
Object.values(
|
||||
findModule((m: any) => {
|
||||
if (typeof m !== 'object') return false;
|
||||
|
||||
for (let prop in m) {
|
||||
if (m[prop]?.toString()?.includes('"ModalManager","DialogWrapper"')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}) || {},
|
||||
)?.find((x: any) => x?.type?.toString()?.includes('((function(){')) ||
|
||||
// old
|
||||
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>;
|
||||
|
||||
@@ -63,28 +63,38 @@ export type AppOverview = {
|
||||
sort_as: string;
|
||||
};
|
||||
|
||||
export interface Router {
|
||||
CloseSideMenus(): void;
|
||||
OpenQuickAccessMenu(quickAccessTab?: QuickAccessTab): void;
|
||||
GetQuickAccessTab(): QuickAccessTab;
|
||||
Navigate(path: string): void;
|
||||
NavigateBackOrOpenMenu(): void;
|
||||
NavigateToAppProperties(): void;
|
||||
NavigateToBugForum(): void;
|
||||
NavigateToExternalWeb(url: string): void;
|
||||
NavigateToHelp(): void;
|
||||
NavigateToInvites(): void;
|
||||
NavigateToRunningApp(replace?: boolean): void;
|
||||
NavigateToStorage(): void;
|
||||
NavigateToStore(): void;
|
||||
NavigateToStoreApp(appId: number | string): void;
|
||||
NavigateToStoreFreeToPlay(): void;
|
||||
NavigateToStoreManual(): void;
|
||||
NavigateToStoreNewReleases(): void;
|
||||
NavigateToStoreOnSale(): void;
|
||||
ToggleSideMenu(sideMenu: SideMenu): void;
|
||||
CloseSideMenus(): void;
|
||||
export interface MenuStore {
|
||||
OpenSideMenu(sideMenu: SideMenu): void;
|
||||
OpenQuickAccessMenu(quickAccessTab?: QuickAccessTab): void;
|
||||
OpenMainMenu(): void;
|
||||
}
|
||||
|
||||
export interface WindowRouter {
|
||||
BrowserWindow: Window;
|
||||
MenuStore: MenuStore;
|
||||
Navigate(path: string): void;
|
||||
NavigateToChat(): void;
|
||||
NavigateToSteamWeb(url: string): void;
|
||||
NavigateBack(): void;
|
||||
NavigateToWebRoute(unknown?: any, unknown2?: any): void;
|
||||
}
|
||||
|
||||
export interface WindowStore {
|
||||
GamepadUIMainWindowInstance?: WindowRouter; // Current
|
||||
SteamUIWindows: WindowRouter[];
|
||||
OverlayWindows: WindowRouter[]; // Used by desktop GamepadUI
|
||||
}
|
||||
|
||||
export interface Router {
|
||||
WindowStore?: WindowStore;
|
||||
CloseSideMenus(): void;
|
||||
Navigate(path: string): void;
|
||||
NavigateToAppProperties(): void;
|
||||
NavigateToExternalWeb(url: string): void;
|
||||
NavigateToInvites(): void;
|
||||
NavigateToChat(): void;
|
||||
NavigateToLibraryTab(): void;
|
||||
NavigateToLayoutPreview(e: unknown): void;
|
||||
OpenPowerMenu(unknown?: any): void;
|
||||
get RunningApps(): AppOverview[];
|
||||
get MainRunningApp(): AppOverview | undefined;
|
||||
@@ -96,3 +106,51 @@ export const Router = findModuleChild((m: Module) => {
|
||||
if (m[prop]?.Navigate && m[prop]?.NavigationManager) return m[prop];
|
||||
}
|
||||
}) as Router;
|
||||
|
||||
export interface Navigation {
|
||||
Navigate(path: string): void;
|
||||
NavigateBack(): void;
|
||||
NavigateToAppProperties(): void;
|
||||
NavigateToExternalWeb(url: string): void;
|
||||
NavigateToInvites(): void;
|
||||
NavigateToChat(): void;
|
||||
NavigateToLibraryTab(): void;
|
||||
NavigateToLayoutPreview(e: unknown): void;
|
||||
NavigateToSteamWeb(url: string): void;
|
||||
NavigateToWebRoute(unknown?: any, unknown2?: any): void;
|
||||
OpenSideMenu(sideMenu: SideMenu): void;
|
||||
OpenQuickAccessMenu(quickAccessTab?: QuickAccessTab): void;
|
||||
OpenMainMenu(): void;
|
||||
OpenPowerMenu(unknown?: any): void;
|
||||
CloseSideMenus(): void;
|
||||
}
|
||||
|
||||
export const Navigation = {
|
||||
Navigate: Router.Navigate.bind(Router),
|
||||
NavigateBack: Router.WindowStore?.GamepadUIMainWindowInstance?.NavigateBack.bind(
|
||||
Router.WindowStore.GamepadUIMainWindowInstance,
|
||||
),
|
||||
NavigateToAppProperties: Router.NavigateToAppProperties.bind(Router),
|
||||
NavigateToExternalWeb: Router.NavigateToExternalWeb.bind(Router),
|
||||
NavigateToInvites: Router.NavigateToInvites.bind(Router),
|
||||
NavigateToChat: Router.NavigateToChat.bind(Router),
|
||||
NavigateToLibraryTab: 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;
|
||||
|
||||
300
src/deck-components/SteamClient.ts
Normal file
300
src/deck-components/SteamClient.ts
Normal file
@@ -0,0 +1,300 @@
|
||||
export interface Apps {
|
||||
RegisterForAppOverviewChanges: any;
|
||||
RegisterForAppDetails: any;
|
||||
RegisterForLocalizationChanges: any;
|
||||
RegisterForWorkshopChanges: any;
|
||||
RegisterForWorkshopItemDownloads: any;
|
||||
GetLibraryBootstrapData: any;
|
||||
RegisterForAchievementChanges: any;
|
||||
GetFriendAchievementsForApp: any;
|
||||
GetMyAchievementsForApp: any;
|
||||
AddUserTagToApps: any;
|
||||
RemoveUserTagFromApps: any;
|
||||
ClearUserTagsOnApps: any;
|
||||
ClearAndSetUserTagsOnApp: any;
|
||||
SetAppHidden: any;
|
||||
ResetHiddenState: any;
|
||||
SetAppLaunchOptions: any;
|
||||
SetAppResolutionOverride: any;
|
||||
SetAppCurrentLanguage: any;
|
||||
SetAppAutoUpdateBehavior: any;
|
||||
SetAppBackgroundDownloadsBehavior: any;
|
||||
ToggleAppFamilyBlockedState: any;
|
||||
ToggleAppSteamCloudEnabled: any;
|
||||
ToggleAppSteamCloudSyncOnSuspendEnabled: any;
|
||||
ToggleOverrideResolutionForInternalDisplay: any;
|
||||
ToggleEnableSteamOverlayForApp: any;
|
||||
ToggleEnableDesktopTheatreForApp: any;
|
||||
BrowseLocalFilesForApp: any;
|
||||
BrowseScreenshotsForApp: any;
|
||||
BrowseScreenshotForApp: any;
|
||||
BackupFilesForApp: any;
|
||||
VerifyFilesForApp: any;
|
||||
CreateDesktopShortcutForApp: any;
|
||||
JoinAppContentBeta: any;
|
||||
JoinAppContentBetaByPassword: any;
|
||||
GetAchievementsInTimeRange: any;
|
||||
GetSubscribedWorkshopItems: any;
|
||||
SubscribeWorkshopItem: any;
|
||||
GetDownloadedWorkshopItems: any;
|
||||
DownloadWorkshopItem: any;
|
||||
SetLocalScreenshotCaption: any;
|
||||
SetLocalScreenshotSpoiler: any;
|
||||
GetDetailsForScreenshotUpload: any;
|
||||
UploadLocalScreenshot: any;
|
||||
DeleteLocalScreenshot: any;
|
||||
GetScreenshotsInTimeRange: any;
|
||||
GetFriendsWhoPlay: any;
|
||||
RequestLegacyCDKeysForApp: any;
|
||||
GetSoundtrackDetails: any;
|
||||
GetStoreTagLocalization: any;
|
||||
GetLaunchOptionsForApp: any;
|
||||
GetResolutionOverrideForApp: any;
|
||||
ScanForShortcuts: any;
|
||||
GetAllShortcuts: any;
|
||||
GetShortcutData: any;
|
||||
AddShortcut: any;
|
||||
RemoveShortcut: any;
|
||||
InstallFlatpakAppAndCreateShortcut: any;
|
||||
ListFlatpakApps: any;
|
||||
UninstallFlatpakApp: any;
|
||||
ShowControllerConfigurator: any;
|
||||
SetThirdPartyControllerConfiguration: any;
|
||||
ToggleAllowDesktopConfiguration: any;
|
||||
SetControllerRumblePreference: any;
|
||||
GetCachedAppDetails: any;
|
||||
SetCachedAppDetails: any;
|
||||
ReportLibraryAssetCacheMiss: any;
|
||||
SaveAchievementProgressCache: any;
|
||||
SetStreamingClientForApp: any;
|
||||
SetCustomArtworkForApp: any;
|
||||
ClearCustomArtworkForApp: any;
|
||||
SetCustomLogoPositionForApp: any;
|
||||
ClearCustomLogoPositionForApp: any;
|
||||
RequestIconDataForApp: any;
|
||||
SpecifyCompatTool: any;
|
||||
GetAvailableCompatTools: any;
|
||||
SetShortcutName: any;
|
||||
SetShortcutExe: any;
|
||||
SetShortcutStartDir: any;
|
||||
SetShortcutLaunchOptions: any;
|
||||
SetShortcutIsVR: any;
|
||||
PromptToChangeShortcut: any;
|
||||
PromptToSelectShortcutIcon: any;
|
||||
InstallApp: any;
|
||||
RunGame: any;
|
||||
VerifyApp: any;
|
||||
StreamGame: any;
|
||||
CancelLaunch: any;
|
||||
TerminateApp: any;
|
||||
UninstallApps: any;
|
||||
ShowStore: any;
|
||||
SetDLCEnabled: any;
|
||||
ContinueGameAction: any;
|
||||
CancelGameAction: any;
|
||||
GetActiveGameActions: any;
|
||||
GetGameActionDetails: any;
|
||||
GetGameActionForApp: any;
|
||||
SkipShaderProcessing: any;
|
||||
MarkEulaAccepted: any;
|
||||
MarkEulaRejected: any;
|
||||
LoadEula: any;
|
||||
GetConflictingFileTimestamps: any;
|
||||
GetCloudPendingRemoteOperations: any;
|
||||
ClearProton: any;
|
||||
RegisterForMarketingMessages: any;
|
||||
FetchMarketingMessages: any;
|
||||
MarkMarketingMessageSeen: any;
|
||||
ReportMarketingMessageSeen: any;
|
||||
RegisterForGameActionStart: any;
|
||||
RegisterForGameActionEnd: any;
|
||||
RegisterForGameActionTaskChange: any;
|
||||
RegisterForGameActionUserRequest: any;
|
||||
RegisterForGameActionShowError: any;
|
||||
RegisterForGameActionShowUI: any;
|
||||
OpenAppSettingsDialog: any;
|
||||
}
|
||||
|
||||
export interface Window {
|
||||
RegisterForExternalDisplayChanged: any;
|
||||
SetManualDisplayScaleFactor: any;
|
||||
SetAutoDisplayScale: any;
|
||||
Minimize: any;
|
||||
ProcessShuttingDown: any;
|
||||
ToggleMaximize: any;
|
||||
MoveTo: any;
|
||||
ResizeTo: any;
|
||||
SetMinSize: any;
|
||||
SetResizeGrip: any;
|
||||
SetComposition: any;
|
||||
GamescopeBlur: any;
|
||||
BringToFront: any;
|
||||
SetForegroundWindow: any;
|
||||
SetKeyFocus: any;
|
||||
FlashWindow: any;
|
||||
StopFlashWindow: any;
|
||||
ShowWindow: any;
|
||||
HideWindow: any;
|
||||
SetWindowIcon: any;
|
||||
GetWindowDimensions: any;
|
||||
GetWindowRestoreDetails: any;
|
||||
PositionWindowRelative: any;
|
||||
GetMousePositionDetails: any;
|
||||
IsWindowMinimized: any;
|
||||
GetBrowserID: any;
|
||||
}
|
||||
|
||||
export interface SteamClient {
|
||||
Apps: Apps;
|
||||
Browser: any;
|
||||
BrowserView: any;
|
||||
ClientNotifications: any;
|
||||
Cloud: any;
|
||||
Console: any;
|
||||
Downloads: any;
|
||||
FamilySharing: any;
|
||||
FriendSettings: any;
|
||||
Friends: any;
|
||||
GameSessions: any;
|
||||
Input: any;
|
||||
InstallFolder: any;
|
||||
Installs: any;
|
||||
MachineStorage: any;
|
||||
Messaging: any;
|
||||
Notifications: any;
|
||||
OpenVR: any;
|
||||
Overlay: any;
|
||||
Parental: any;
|
||||
RegisterIFrameNavigatedCallback: any;
|
||||
RemotePlay: any;
|
||||
RoamingStorage: any;
|
||||
Screenshots: any;
|
||||
Settings: any;
|
||||
SharedConnection: any;
|
||||
Stats: any;
|
||||
Storage: any;
|
||||
Streaming: any;
|
||||
System: any;
|
||||
UI: any;
|
||||
URL: any;
|
||||
Updates: any;
|
||||
User: any;
|
||||
WebChat: any;
|
||||
Window: Window;
|
||||
}
|
||||
|
||||
export interface SteamShortcut {
|
||||
appid: number;
|
||||
data: {
|
||||
bIsApplication: boolean;
|
||||
strAppName: string;
|
||||
strExePath: string;
|
||||
strArguments: string;
|
||||
strShortcutPath: string;
|
||||
strSortAs: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @prop unAppID is not properly set by Steam for non-steam game shortcuts, so it defaults to 0 for them
|
||||
*/
|
||||
export interface LifetimeNotification {
|
||||
unAppID: number;
|
||||
nInstanceID: number;
|
||||
bRunning: boolean;
|
||||
}
|
||||
|
||||
export type AppAchievements = {
|
||||
nAchieved: number;
|
||||
nTotal: number;
|
||||
vecAchievedHidden: any[];
|
||||
vecHighlight: any[];
|
||||
vecUnachieved: any[];
|
||||
};
|
||||
|
||||
export type AppLanguages = {
|
||||
strDisplayName: string;
|
||||
strShortName: string;
|
||||
};
|
||||
|
||||
export interface AppDetails {
|
||||
achievements: AppAchievements;
|
||||
bCanMoveInstallFolder: boolean;
|
||||
bCloudAvailable: boolean;
|
||||
bCloudEnabledForAccount: boolean;
|
||||
bCloudEnabledForApp: boolean;
|
||||
bCloudSyncOnSuspendAvailable: boolean;
|
||||
bCloudSyncOnSuspendEnabled: boolean;
|
||||
bCommunityMarketPresence: boolean;
|
||||
bEnableAllowDesktopConfiguration: boolean;
|
||||
bFreeRemovableLicense: boolean;
|
||||
bHasAllLegacyCDKeys: boolean;
|
||||
bHasAnyLocalContent: boolean;
|
||||
bHasLockedPrivateBetas: boolean;
|
||||
bIsExcludedFromSharing: boolean;
|
||||
bIsSubscribedTo: boolean;
|
||||
bOverlayEnabled: boolean;
|
||||
bOverrideInternalResolution: boolean;
|
||||
bRequiresLegacyCDKey: boolean;
|
||||
bShortcutIsVR: boolean;
|
||||
bShowCDKeyInMenus: boolean;
|
||||
bShowControllerConfig: boolean;
|
||||
bSupportsCDKeyCopyToClipboard: boolean;
|
||||
bVRGameTheatreEnabled: boolean;
|
||||
bWorkshopVisible: boolean;
|
||||
eAppOwnershipFlags: number;
|
||||
eAutoUpdateValue: number;
|
||||
eBackgroundDownloads: number;
|
||||
eCloudSync: number;
|
||||
eControllerRumblePreference: number;
|
||||
eDisplayStatus: number;
|
||||
eEnableThirdPartyControllerConfiguration: number;
|
||||
eSteamInputControllerMask: number;
|
||||
iInstallFolder: number;
|
||||
lDiskUsageBytes: number;
|
||||
lDlcUsageBytes: number;
|
||||
nBuildID: number;
|
||||
nCompatToolPriority: number;
|
||||
nPlaytimeForever: number;
|
||||
nScreenshots: number;
|
||||
rtLastTimePlayed: number;
|
||||
rtLastUpdated: number;
|
||||
rtPurchased: number;
|
||||
selectedLanguage: {
|
||||
strDisplayName: string;
|
||||
strShortName: string;
|
||||
};
|
||||
strCloudBytesAvailable: string;
|
||||
strCloudBytesUsed: string;
|
||||
strCompatToolDisplayName: string;
|
||||
strCompatToolName: string;
|
||||
strDeveloperName: string;
|
||||
strDeveloperURL: string;
|
||||
strDisplayName: string;
|
||||
strExternalSubscriptionURL: string;
|
||||
strFlatpakAppID: string;
|
||||
strHomepageURL: string;
|
||||
strLaunchOptions: string;
|
||||
strManualURL: string;
|
||||
strOwnerSteamID: string;
|
||||
strResolutionOverride: string;
|
||||
strSelectedBeta: string;
|
||||
strShortcutExe: string;
|
||||
strShortcutLaunchOptions: string;
|
||||
strShortcutStartDir: string;
|
||||
strSteamDeckBlogURL: string;
|
||||
unAppID: number;
|
||||
vecBetas: any[];
|
||||
vecDLC: any[];
|
||||
vecDeckCompatTestResults: any[];
|
||||
vecLanguages: AppLanguages[];
|
||||
vecLegacyCDKeys: any[];
|
||||
vecMusicAlbums: any[];
|
||||
vecPlatforms: string[];
|
||||
vecScreenShots: any[];
|
||||
}
|
||||
|
||||
export interface SteamAppOverview {
|
||||
display_name: string;
|
||||
gameid: string;
|
||||
}
|
||||
@@ -65,16 +65,11 @@ export interface TabsProps {
|
||||
autoFocusContents?: boolean;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
DeckyPluginLoader: any;
|
||||
}
|
||||
}
|
||||
|
||||
let tabsComponent: any;
|
||||
|
||||
const getTabs = async () => {
|
||||
if (tabsComponent) return tabsComponent;
|
||||
// @ts-ignore
|
||||
while (!window?.DeckyPluginLoader?.routerHook?.routes) {
|
||||
console.debug('[DFL:Tabs]: Waiting for Decky router...');
|
||||
await sleep(500);
|
||||
@@ -83,6 +78,7 @@ const getTabs = async () => {
|
||||
() => {
|
||||
return findInReactTree(
|
||||
findInReactTree(
|
||||
// @ts-ignore
|
||||
window.DeckyPluginLoader.routerHook.routes
|
||||
.find((x: any) => x.props.path == '/library/app/:appid/achievements')
|
||||
.props.children.type(),
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
export * from './Button';
|
||||
export * from './ButtonItem';
|
||||
export * from './Carousel';
|
||||
export * from './ControlsList';
|
||||
export * from './Dialog';
|
||||
export * from './DialogCheckbox';
|
||||
export * from './Dropdown';
|
||||
export * from './Field';
|
||||
export * from './Focusable';
|
||||
export * from './FocusRing';
|
||||
export * from './FooterLegend';
|
||||
export * from './Marquee';
|
||||
export * from './Menu';
|
||||
export * from './Modal';
|
||||
export * from './Panel';
|
||||
@@ -21,3 +24,10 @@ export * from './Tabs';
|
||||
export * from './TextField';
|
||||
export * from './Toggle';
|
||||
export * from './ToggleField';
|
||||
export * from './SteamClient';
|
||||
|
||||
import {SteamClient} from './SteamClient'
|
||||
|
||||
declare global {
|
||||
var SteamClient: SteamClient;
|
||||
}
|
||||
|
||||
@@ -349,6 +349,98 @@ type GamepadSliderClasses = Record<
|
||||
string
|
||||
>;
|
||||
|
||||
type AppDetailsHeaderClasses = Record<
|
||||
| 'AddBoxSizer'
|
||||
| 'Background'
|
||||
| 'Bottom'
|
||||
| 'BottomCenter'
|
||||
| 'BottomLeft'
|
||||
| 'BottomRight'
|
||||
| 'BoxSizer'
|
||||
| 'BoxSizerButtonContainer'
|
||||
| 'BoxSizerContainer'
|
||||
| 'BoxSizerDelete'
|
||||
| 'BoxSizerDragBox'
|
||||
| 'BoxSizerEdge'
|
||||
| 'BoxSizerGridBox'
|
||||
| 'BoxSizerInfo'
|
||||
| 'BoxSizerSettings'
|
||||
| 'BoxSizerValidRegion'
|
||||
| 'CenterCenter'
|
||||
| 'DialogButton'
|
||||
| 'EdgeDown'
|
||||
| 'FallbackArt'
|
||||
| 'Features'
|
||||
| 'FullscreenEnterActive'
|
||||
| 'FullscreenEnterDone'
|
||||
| 'FullscreenEnterStart'
|
||||
| 'FullscreenExitActive'
|
||||
| 'FullscreenExitDone'
|
||||
| 'FullscreenExitStart'
|
||||
| 'HeaderBackgroundImage'
|
||||
| 'ImgBlur'
|
||||
| 'ImgBlurBackdrop'
|
||||
| 'ImgContainer'
|
||||
| 'ImgSrc'
|
||||
| 'Left'
|
||||
| 'Loaded'
|
||||
| 'Middle'
|
||||
| 'NoArt'
|
||||
| 'PinBox'
|
||||
| 'Right'
|
||||
| 'SVGTitle'
|
||||
| 'SaveBoxSizer'
|
||||
| 'TextNameSpace'
|
||||
| 'TitleImageContainer'
|
||||
| 'TitleLogo'
|
||||
| 'TitleSection'
|
||||
| 'Top'
|
||||
| 'TopCapsule'
|
||||
| 'TopGradient'
|
||||
| 'TopLeft'
|
||||
| 'TopRight'
|
||||
| 'UpperCenter'
|
||||
| 'UpperLeft'
|
||||
| 'duration-app-launch',
|
||||
string
|
||||
>;
|
||||
|
||||
type AppDetailsClasses = Record<
|
||||
| 'BreakNarrow'
|
||||
| 'BreakShort'
|
||||
| 'BreakTall'
|
||||
| 'BreakUltraWide'
|
||||
| 'BreakWide'
|
||||
| 'Container'
|
||||
| 'GamepadUIBreakNarrow'
|
||||
| 'GamepadUIBreakShort'
|
||||
| 'GamepadUIBreakWide'
|
||||
| 'Glassy'
|
||||
| 'Header'
|
||||
| 'HeaderLoaded'
|
||||
| 'InnerContainer'
|
||||
| 'ItemFocusAnim-darkGrey'
|
||||
| 'ItemFocusAnim-darkerGrey'
|
||||
| 'ItemFocusAnim-darkerGrey-nocolor'
|
||||
| 'ItemFocusAnim-green'
|
||||
| 'ItemFocusAnim-grey'
|
||||
| 'ItemFocusAnimBorder-darkGrey'
|
||||
| 'PlayBar'
|
||||
| 'PreventScrolling'
|
||||
| 'RightBreakNarrow'
|
||||
| 'RightBreakUltraNarrow'
|
||||
| 'RightBreakUltraWide'
|
||||
| 'RightBreakWide'
|
||||
| 'ScrollContainer'
|
||||
| 'ShowPlayBar'
|
||||
| 'Throbber'
|
||||
| 'duration-app-launch'
|
||||
| 'fadein'
|
||||
| 'focusAnimation'
|
||||
| 'hoverAnimation',
|
||||
string
|
||||
>;
|
||||
|
||||
export const quickAccessMenuClasses: QuickAccessMenuClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.Title?.includes('quickaccessmenu'),
|
||||
);
|
||||
@@ -378,3 +470,9 @@ export const playSectionClasses: PlaySectionClasses = findModule(
|
||||
export const gamepadSliderClasses: GamepadSliderClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.SliderControlPanelGroup?.includes('gamepadslider'),
|
||||
);
|
||||
export const appDetailsHeaderClasses: AppDetailsHeaderClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.TopCapsule?.includes('sharedappdetailsheader'),
|
||||
);
|
||||
export const appDetailsClasses: AppDetailsClasses = findModule(
|
||||
(mod) => typeof mod === 'object' && mod?.HeaderLoaded?.includes('appdetails_'),
|
||||
);
|
||||
|
||||
@@ -26,8 +26,10 @@ export type RoutePatch = (route: RouteProps) => RouteProps;
|
||||
export interface RouterHook {
|
||||
addRoute(path: string, component: ComponentType, props?: Omit<RouteProps, 'path' | 'children'>): void;
|
||||
addPatch(path: string, patch: RoutePatch): RoutePatch;
|
||||
removePatch(path: string, patch: RoutePatch): void;
|
||||
addGlobalComponent(name: string, component: ComponentType): void;
|
||||
removeRoute(path: string): void;
|
||||
removePatch(path: string, patch: RoutePatch): void;
|
||||
removeGlobalComponent(name: string): void;
|
||||
}
|
||||
|
||||
export interface ToastData {
|
||||
@@ -40,6 +42,10 @@ export interface ToastData {
|
||||
contentClassName?: string;
|
||||
duration?: number;
|
||||
critical?: boolean;
|
||||
eType?: number;
|
||||
sound?: number;
|
||||
playSound?: boolean;
|
||||
showToast?: boolean;
|
||||
}
|
||||
|
||||
export interface Toaster {
|
||||
|
||||
@@ -16,6 +16,7 @@ export function findSP(): Window {
|
||||
// old (SP as host)
|
||||
if (document.title == 'SP') return window;
|
||||
// new (SP as popup)
|
||||
return FocusNavController.m_ActiveContext.m_rgGamepadNavigationTrees.find((x: any) => x.m_ID == 'root_1_').Root
|
||||
const context = FocusNavController.m_ActiveContext || FocusNavController.m_LastActiveContext;
|
||||
return context.m_rgGamepadNavigationTrees.find((x: any) => x.m_ID == 'root_1_').Root
|
||||
.Element.ownerDocument.defaultView;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user