summaryrefslogtreecommitdiff
path: root/frontend/src/plugin-loader.tsx
diff options
context:
space:
mode:
authorAAGaming <aa@mail.catvibers.me>2022-09-09 16:25:52 -0400
committerAAGaming <aa@mail.catvibers.me>2022-09-09 16:25:52 -0400
commitb5b041fdee3cdb3576cd4d1c77580f57da0b6435 (patch)
tree2b63ccb6410868fe4f0c6f3882614d0f7a180be4 /frontend/src/plugin-loader.tsx
parent9d980618a78b41bc3262c5185df67ccf6076a296 (diff)
downloaddecky-loader-b5b041fdee3cdb3576cd4d1c77580f57da0b6435.tar.gz
decky-loader-b5b041fdee3cdb3576cd4d1c77580f57da0b6435.zip
add file picker, add library file picker patch, bump lib, logger tweaks
Diffstat (limited to 'frontend/src/plugin-loader.tsx')
-rw-r--r--frontend/src/plugin-loader.tsx83
1 files changed, 48 insertions, 35 deletions
diff --git a/frontend/src/plugin-loader.tsx b/frontend/src/plugin-loader.tsx
index 4d3415c8..493e5935 100644
--- a/frontend/src/plugin-loader.tsx
+++ b/frontend/src/plugin-loader.tsx
@@ -1,13 +1,15 @@
-import { ModalRoot, QuickAccessTab, Router, SteamSpinner, showModal, sleep, staticClasses } from 'decky-frontend-lib';
-import { Suspense, lazy } from 'react';
+import { ConfirmModal, ModalRoot, QuickAccessTab, Router, showModal, sleep, staticClasses } from 'decky-frontend-lib';
+import { lazy } from 'react';
import { FaPlug } from 'react-icons/fa';
import { DeckyState, DeckyStateContextProvider, useDeckyState } from './components/DeckyState';
import LegacyPlugin from './components/LegacyPlugin';
+import { deinitFilepickerPatches, initFilepickerPatches } from './components/modals/filepicker/patches';
import PluginInstallModal from './components/modals/PluginInstallModal';
import NotificationBadge from './components/NotificationBadge';
import PluginView from './components/PluginView';
import TitleView from './components/TitleView';
+import WithSuspense from './components/WithSuspense';
import Logger from './logger';
import { Plugin } from './plugin';
import RouterHook from './router-hook';
@@ -16,6 +18,11 @@ import TabsHook from './tabs-hook';
import Toaster from './toaster';
import { VerInfo, callUpdaterMethod } from './updater';
+const StorePage = lazy(() => import('./components/store/Store'));
+const SettingsPage = lazy(() => import('./components/settings'));
+
+const FilePicker = lazy(() => import('./components/modals/filepicker'));
+
declare global {
interface Window {}
}
@@ -58,47 +65,22 @@ class PluginLoader extends Logger {
),
});
- const StorePage = lazy(() => import('./components/store/Store'));
- const SettingsPage = lazy(() => import('./components/settings'));
-
this.routerHook.addRoute('/decky/store', () => (
- <Suspense
- fallback={
- <div
- style={{
- marginTop: '40px',
- height: 'calc( 100% - 40px )',
- overflowY: 'scroll',
- }}
- >
- <SteamSpinner />
- </div>
- }
- >
+ <WithSuspense>
<StorePage />
- </Suspense>
+ </WithSuspense>
));
this.routerHook.addRoute('/decky/settings', () => {
return (
<DeckyStateContextProvider deckyState={this.deckyState}>
- <Suspense
- fallback={
- <div
- style={{
- marginTop: '40px',
- height: 'calc( 100% - 40px )',
- overflowY: 'scroll',
- }}
- >
- <SteamSpinner />
- </div>
- }
- >
+ <WithSuspense>
<SettingsPage />
- </Suspense>
+ </WithSuspense>
</DeckyStateContextProvider>
);
});
+
+ initFilepickerPatches();
}
public async notifyUpdates() {
@@ -147,7 +129,7 @@ class PluginLoader extends Logger {
public uninstallPlugin(name: string) {
showModal(
- <ModalRoot
+ <ConfirmModal
onOK={async () => {
await this.callServerMethod('uninstall_plugin', { name });
}}
@@ -158,7 +140,7 @@ class PluginLoader extends Logger {
<div className={staticClasses.Title} style={{ flexDirection: 'column' }}>
Uninstall {name}?
</div>
- </ModalRoot>,
+ </ConfirmModal>,
);
}
@@ -176,6 +158,7 @@ class PluginLoader extends Logger {
public deinit() {
this.routerHook.removeRoute('/decky/store');
this.routerHook.removeRoute('/decky/settings');
+ deinitFilepickerPatches();
}
public unloadPlugin(name: string) {
@@ -257,11 +240,41 @@ class PluginLoader extends Logger {
return response.json();
}
+ openFilePicker(
+ startPath: string,
+ includeFiles?: boolean,
+ regex?: RegExp,
+ ): Promise<{ path: string; realpath: string }> {
+ return new Promise((resolve, reject) => {
+ const Content = ({ closeModal }: { closeModal?: () => void }) => (
+ // Purposely outside of the FilePicker component as lazy-loaded ModalRoots don't focus correctly
+ <ModalRoot
+ onCancel={() => {
+ reject('User canceled');
+ closeModal?.();
+ }}
+ >
+ <WithSuspense>
+ <FilePicker
+ startPath={startPath}
+ includeFiles={includeFiles}
+ regex={regex}
+ onSubmit={resolve}
+ closeModal={closeModal}
+ />
+ </WithSuspense>
+ </ModalRoot>
+ );
+ showModal(<Content />);
+ });
+ }
+
createPluginAPI(pluginName: string) {
return {
routerHook: this.routerHook,
toaster: this.toaster,
callServerMethod: this.callServerMethod,
+ openFilePicker: this.openFilePicker,
async callPluginMethod(methodName: string, args = {}) {
const response = await fetch(`http://127.0.0.1:1337/plugins/${pluginName}/methods/${methodName}`, {
method: 'POST',