diff options
| author | AAGaming <aa@mail.catvibers.me> | 2023-08-05 01:11:43 -0400 |
|---|---|---|
| committer | marios8543 <marios8543@gmail.com> | 2023-11-14 00:04:56 +0200 |
| commit | 34d1a34b10f4386865f3c241c5ae4026d2bfd8bd (patch) | |
| tree | d9560bceecd2cb3d0a2b89d9f75bc29a7dfdc3dd /frontend | |
| parent | cfb6fe69e3f111de0d75a9d90e570bac392e1ee3 (diff) | |
| download | decky-loader-34d1a34b10f4386865f3c241c5ae4026d2bfd8bd.tar.gz decky-loader-34d1a34b10f4386865f3c241c5ae4026d2bfd8bd.zip | |
Migrate most of frontend callServerMethod usage over to websocket
Diffstat (limited to 'frontend')
| -rw-r--r-- | frontend/src/components/modals/PluginUninstallModal.tsx | 4 | ||||
| -rw-r--r-- | frontend/src/components/modals/filepicker/index.tsx | 90 | ||||
| -rw-r--r-- | frontend/src/components/settings/pages/developer/index.tsx | 13 | ||||
| -rw-r--r-- | frontend/src/components/settings/pages/general/RemoteDebugging.tsx | 4 | ||||
| -rw-r--r-- | frontend/src/developer.tsx | 4 | ||||
| -rw-r--r-- | frontend/src/index.ts | 6 | ||||
| -rw-r--r-- | frontend/src/plugin-loader.tsx | 36 | ||||
| -rw-r--r-- | frontend/src/plugin.ts | 24 | ||||
| -rw-r--r-- | frontend/src/start.tsx | 2 | ||||
| -rw-r--r-- | frontend/src/store.tsx | 21 | ||||
| -rw-r--r-- | frontend/src/utils/settings.ts | 4 | ||||
| -rw-r--r-- | frontend/src/wsrouter.ts | 13 |
12 files changed, 115 insertions, 106 deletions
diff --git a/frontend/src/components/modals/PluginUninstallModal.tsx b/frontend/src/components/modals/PluginUninstallModal.tsx index e7ecbc99..e9c243b6 100644 --- a/frontend/src/components/modals/PluginUninstallModal.tsx +++ b/frontend/src/components/modals/PluginUninstallModal.tsx @@ -1,6 +1,8 @@ import { ConfirmModal } from 'decky-frontend-lib'; import { FC } from 'react'; +import { uninstallPlugin } from '../../plugin'; + interface PluginUninstallModalProps { name: string; title: string; @@ -14,7 +16,7 @@ const PluginUninstallModal: FC<PluginUninstallModalProps> = ({ name, title, butt <ConfirmModal closeModal={closeModal} onOK={async () => { - await window.DeckyPluginLoader.callServerMethod('uninstall_plugin', { name }); + await uninstallPlugin(name); // uninstalling a plugin resets the hidden setting for it server-side // we invalidate here so if you re-install it, you won't have an out-of-date hidden filter await window.DeckyPluginLoader.hiddenPluginsService.invalidate(); diff --git a/frontend/src/components/modals/filepicker/index.tsx b/frontend/src/components/modals/filepicker/index.tsx index c4e72d95..2dfa3ccd 100644 --- a/frontend/src/components/modals/filepicker/index.tsx +++ b/frontend/src/components/modals/filepicker/index.tsx @@ -95,29 +95,20 @@ const sortOptions = [ }, ]; -function getList( - path: string, - includeFiles: boolean, - includeFolders: boolean = true, - includeExt: string[] | null = null, - includeHidden: boolean = false, - orderBy: SortOptions = SortOptions.name_desc, - filterFor: RegExp | ((file: File) => boolean) | null = null, - pageNumber: number = 1, - max: number = 1000, -): Promise<{ result: FileListing | string; success: boolean }> { - return window.DeckyPluginLoader.callServerMethod('filepicker_ls', { - path, - include_files: includeFiles, - include_folders: includeFolders, - include_ext: includeExt ? includeExt : [], - include_hidden: includeHidden, - order_by: orderBy, - filter_for: filterFor, - page: pageNumber, - max: max, - }); -} +const getList = window.DeckyBackend.callable< + [ + path: string, + includeFiles?: boolean, + includeFolders?: boolean, + includeExt?: string[] | null, + includeHidden?: boolean, + orderBy?: SortOptions, + filterFor?: RegExp | ((file: File) => boolean) | null, + pageNumber?: number, + max?: number, + ], + FileListing +>('utilities/filepicker_ls'); const iconStyles = { paddingRight: '10px', @@ -126,20 +117,20 @@ const iconStyles = { const FilePicker: FunctionComponent<FilePickerProps> = ({ startPath, - //What are we allowing to show in the file picker + // What are we allowing to show in the file picker includeFiles = true, includeFolders = true, - //Parameter for specifying a specific filename match + // Parameter for specifying a specific filename match filter = undefined, - //Filter for specific extensions as an array + // Filter for specific extensions as an array validFileExtensions = undefined, - //Allow to override the fixed extension above + // Allow to override the fixed extension above allowAllFiles = true, - //If we need to show hidden files and folders (both Win and Linux should work) + // If we need to show hidden files and folders (both Win and Linux should work) defaultHidden = false, // false by default makes sense for most users - //How much files per page to show, default 1000 + // How many files per page to show, default 1000 max = 1000, - //Which picking option to select by default + // Which picking option to select by default fileSelType = FileSelectionType.FOLDER, onSubmit, closeModal, @@ -190,21 +181,27 @@ const FilePicker: FunctionComponent<FilePickerProps> = ({ useEffect(() => { (async () => { setLoading(true); - const listing = await getList( - path, - includeFiles, - includeFolders, - selectedExts, - showHidden, - sort, - filter, - page, - max, - ); - if (!listing.success) { + try { + const listing = await getList( + path, + includeFiles, + includeFolders, + selectedExts, + showHidden, + sort, + filter, + page, + max, + ); + setRawError(null); + setError(FileErrorTypes.None); + setFiles(listing.files); + setLoading(false); + setListing(listing); + logger.log('reloaded', path, listing); + } catch (theError: any) { setListing({ files: [], realpath: path, total: 0 }); setLoading(false); - const theError = listing.result as string; switch (theError) { case theError.match(/\[Errno\s2.*/i)?.input: case theError.match(/\[WinError\s3.*/i)?.input: @@ -220,14 +217,7 @@ const FilePicker: FunctionComponent<FilePickerProps> = ({ } logger.debug(theError); return; - } else { - setRawError(null); - setError(FileErrorTypes.None); - setFiles((listing.result as FileListing).files); } - setLoading(false); - setListing(listing.result as FileListing); - logger.log('reloaded', path, listing); })(); }, [error, path, includeFiles, includeFolders, showHidden, sort, selectedExts, page]); diff --git a/frontend/src/components/settings/pages/developer/index.tsx b/frontend/src/components/settings/pages/developer/index.tsx index 5ed76515..36d3b5c0 100644 --- a/frontend/src/components/settings/pages/developer/index.tsx +++ b/frontend/src/components/settings/pages/developer/index.tsx @@ -91,13 +91,16 @@ export default function DeveloperSettings() { > <DialogButton onClick={async () => { - let res = await window.DeckyPluginLoader.callServerMethod('get_tab_id', { name: 'SharedJSContext' }); - if (res.success) { + try { + let tabId = await window.DeckyBackend.call<[name: string], string>( + 'utilities/get_tab_id', + 'SharedJSContext', + ); Navigation.NavigateToExternalWeb( - 'localhost:8080/devtools/inspector.html?ws=localhost:8080/devtools/page/' + res.result, + 'localhost:8080/devtools/inspector.html?ws=localhost:8080/devtools/page/' + tabId, ); - } else { - console.error('Unable to find ID for SharedJSContext tab ', res.result); + } catch (e) { + console.error('Unable to find ID for SharedJSContext tab ', e); Navigation.NavigateToExternalWeb('localhost:8080'); } }} diff --git a/frontend/src/components/settings/pages/general/RemoteDebugging.tsx b/frontend/src/components/settings/pages/general/RemoteDebugging.tsx index 60d57d91..60e0e3c1 100644 --- a/frontend/src/components/settings/pages/general/RemoteDebugging.tsx +++ b/frontend/src/components/settings/pages/general/RemoteDebugging.tsx @@ -18,8 +18,8 @@ export default function RemoteDebuggingSettings() { value={allowRemoteDebugging || false} onChange={(toggleValue) => { setAllowRemoteDebugging(toggleValue); - if (toggleValue) window.DeckyPluginLoader.callServerMethod('allow_remote_debugging'); - else window.DeckyPluginLoader.callServerMethod('disallow_remote_debugging'); + if (toggleValue) window.DeckyBackend.call('allow_remote_debugging'); + else window.DeckyBackend.call('disallow_remote_debugging'); }} /> </Field> diff --git a/frontend/src/developer.tsx b/frontend/src/developer.tsx index 43f550d7..8bd09812 100644 --- a/frontend/src/developer.tsx +++ b/frontend/src/developer.tsx @@ -50,9 +50,7 @@ export async function setShouldConnectToReactDevTools(enable: boolean) { icon: <FaReact />, }); await sleep(5000); - return enable - ? window.DeckyPluginLoader.callServerMethod('enable_rdt') - : window.DeckyPluginLoader.callServerMethod('disable_rdt'); + return enable ? window.DeckyBackend.call('utilities/enable_rdt') : window.DeckyBackend.call('utilities/disable_rdt'); } export async function startup() { diff --git a/frontend/src/index.ts b/frontend/src/index.ts index 6588cb5c..3a0c4880 100644 --- a/frontend/src/index.ts +++ b/frontend/src/index.ts @@ -2,5 +2,11 @@ (async () => { console.debug('Setting up decky-frontend-lib...'); window.DFL = await import('decky-frontend-lib'); + console.debug('Authenticating to Decky backend...'); + window.deckyAuthToken = await fetch('http://127.0.0.1:1337/auth/token').then((r) => r.text()); + console.debug('Connecting to Decky backend...'); + window.DeckyBackend = new (await import('./wsrouter')).WSRouter(); + await window.DeckyBackend.connect(); + console.debug('Starting Decky!'); await import('./start'); })(); diff --git a/frontend/src/plugin-loader.tsx b/frontend/src/plugin-loader.tsx index 86592016..3c9ba818 100644 --- a/frontend/src/plugin-loader.tsx +++ b/frontend/src/plugin-loader.tsx @@ -34,7 +34,6 @@ import Toaster from './toaster'; import { VerInfo, callUpdaterMethod } from './updater'; import { getSetting, setSetting } from './utils/settings'; import TranslationHelper, { TranslationClass } from './utils/TranslationHelper'; -import { WSRouter } from './wsrouter'; const StorePage = lazy(() => import('./components/store/Store')); const SettingsPage = lazy(() => import('./components/settings')); @@ -49,8 +48,6 @@ class PluginLoader extends Logger { public toaster: Toaster = new Toaster(); private deckyState: DeckyState = new DeckyState(); - public ws: WSRouter = new WSRouter(); - public hiddenPluginsService = new HiddenPluginsService(this.deckyState); public notificationService = new NotificationService(this.deckyState); @@ -105,15 +102,13 @@ class PluginLoader extends Logger { initFilepickerPatches(); - this.ws.connect().then(() => { - this.getUserInfo(); + this.getUserInfo(); - this.updateVersion(); - }); + this.updateVersion(); } public async getUserInfo() { - const userInfo = (await this.callServerMethod('get_user_info')).result as UserInfo; + const userInfo = await window.DeckyBackend.call<[], UserInfo>('utilities/get_user_info'); setSetting('user_info.user_name', userInfo.username); setSetting('user_info.user_home', userInfo.path); } @@ -183,8 +178,8 @@ class PluginLoader extends Logger { version={version} hash={hash} installType={install_type} - onOK={() => this.callServerMethod('confirm_plugin_install', { request_id })} - onCancel={() => this.callServerMethod('cancel_plugin_install', { request_id })} + onOK={() => window.DeckyBackend.call<[string]>('utilities/confirm_plugin_install', request_id)} + onCancel={() => window.DeckyBackend.call<[string]>('utilities/cancel_plugin_install', request_id)} />, ); } @@ -196,8 +191,8 @@ class PluginLoader extends Logger { showModal( <MultiplePluginsInstallModal requests={requests} - onOK={() => this.callServerMethod('confirm_plugin_install', { request_id })} - onCancel={() => this.callServerMethod('cancel_plugin_install', { request_id })} + onOK={() => window.DeckyBackend.call<[string]>('utilities/confirm_plugin_install', request_id)} + onCancel={() => window.DeckyBackend.call<[string]>('utilities/cancel_plugin_install', request_id)} />, ); } @@ -360,6 +355,7 @@ class PluginLoader extends Logger { selectFiles?: boolean, regex?: RegExp, ): Promise<{ path: string; realpath: string }> { + console.warn('openFilePicker is deprecated and will be removed. Please migrate to openFilePickerV2'); if (selectFiles) { return this.openFilePickerV2(FileSelectionType.FILE, startPath, true, true, regex); } else { @@ -443,18 +439,10 @@ class PluginLoader extends Logger { code, }); }, - injectCssIntoTab(tab: string, style: string) { - return this.callServerMethod('inject_css_into_tab', { - tab, - style, - }); - }, - removeCssFromTab(tab: string, cssId: any) { - return this.callServerMethod('remove_css_from_tab', { - tab, - css_id: cssId, - }); - }, + injectCssIntoTab: window.DeckyBackend.callable<[tab: string, style: string], string>( + 'utilities/inject_css_into_tab', + ), + removeCssFromTab: window.DeckyBackend.callable<[tab: string, cssId: string]>('utilities/remove_css_from_tab'), }; } } diff --git a/frontend/src/plugin.ts b/frontend/src/plugin.ts index fa1bb28a..21d45654 100644 --- a/frontend/src/plugin.ts +++ b/frontend/src/plugin.ts @@ -13,3 +13,27 @@ export enum InstallType { REINSTALL, UPDATE, } + +type installPluginArgs = [ + artifact: string, + name?: string, + version?: string, + hash?: string | boolean, + installType?: InstallType, +]; + +export let installPlugin = window.DeckyBackend.callable<installPluginArgs>('utilities/install_plugin'); + +type installPluginsArgs = [ + requests: { + artifact: string; + name?: string; + version?: string; + hash?: string | boolean; + installType?: InstallType; + }[], +]; + +export let installPlugins = window.DeckyBackend.callable<installPluginsArgs>('utilities/install_plugins'); + +export let uninstallPlugin = window.DeckyBackend.callable<[name: string]>('utilities/uninstall_plugin'); diff --git a/frontend/src/start.tsx b/frontend/src/start.tsx index 94b22ffe..a125e3d4 100644 --- a/frontend/src/start.tsx +++ b/frontend/src/start.tsx @@ -19,8 +19,6 @@ declare global { } (async () => { - window.deckyAuthToken = await fetch('http://127.0.0.1:1337/auth/token').then((r) => r.text()); - i18n .use(Backend) .use(initReactI18next) diff --git a/frontend/src/store.tsx b/frontend/src/store.tsx index bc419430..5ae98ec4 100644 --- a/frontend/src/store.tsx +++ b/frontend/src/store.tsx @@ -1,4 +1,4 @@ -import { InstallType, Plugin } from './plugin'; +import { InstallType, Plugin, installPlugin, installPlugins } from './plugin'; import { getSetting, setSetting } from './utils/settings'; export enum Store { @@ -92,33 +92,24 @@ export async function getPluginList(): Promise<StorePlugin[]> { export async function installFromURL(url: string) { const splitURL = url.split('/'); - await window.DeckyPluginLoader.callServerMethod('install_plugin', { - name: splitURL[splitURL.length - 1].replace('.zip', ''), - artifact: url, - }); + await installPlugin(url, splitURL[splitURL.length - 1].replace('.zip', '')); } export async function requestPluginInstall(plugin: string, selectedVer: StorePluginVersion, installType: InstallType) { const artifactUrl = selectedVer.artifact ?? pluginUrl(selectedVer.hash); - await window.DeckyPluginLoader.callServerMethod('install_plugin', { - name: plugin, - artifact: artifactUrl, - version: selectedVer.name, - hash: selectedVer.hash, - install_type: installType, - }); + await installPlugin(artifactUrl, plugin, selectedVer.name, selectedVer.hash, installType); } export async function requestMultiplePluginInstalls(requests: PluginInstallRequest[]) { - await window.DeckyPluginLoader.callServerMethod('install_plugins', { - requests: requests.map(({ plugin, installType, selectedVer }) => ({ + await installPlugins( + requests.map(({ plugin, installType, selectedVer }) => ({ name: plugin, artifact: selectedVer.artifact ?? pluginUrl(selectedVer.hash), version: selectedVer.name, hash: selectedVer.hash, install_type: installType, })), - }); + ); } export async function checkForUpdates(plugins: Plugin[]): Promise<PluginUpdateMapping> { diff --git a/frontend/src/utils/settings.ts b/frontend/src/utils/settings.ts index d390d7ba..cba4887f 100644 --- a/frontend/src/utils/settings.ts +++ b/frontend/src/utils/settings.ts @@ -1,8 +1,8 @@ export async function getSetting<T>(key: string, def: T): Promise<T> { - const res = await window.DeckyPluginLoader.ws.call<[string, T], T>('utilities/settings/get', key, def); + const res = await window.DeckyBackend.call<[string, T], T>('utilities/settings/get', key, def); return res; } export async function setSetting<T>(key: string, value: T): Promise<void> { - await window.DeckyPluginLoader.ws.call<[string, T], void>('utilities/settings/set', key, value); + await window.DeckyBackend.call<[string, T], void>('utilities/settings/set', key, value); } diff --git a/frontend/src/wsrouter.ts b/frontend/src/wsrouter.ts index 3a36b5b0..e50b06a7 100644 --- a/frontend/src/wsrouter.ts +++ b/frontend/src/wsrouter.ts @@ -1,5 +1,11 @@ import Logger from './logger'; +declare global { + interface Window { + DeckyBackend: WSRouter; + } +} + enum MessageType { // Call-reply CALL, @@ -94,7 +100,6 @@ export class WSRouter extends Logger { } async onMessage(msg: MessageEvent) { - this.debug('WS Message', msg); try { const data = JSON.parse(msg.data) as Message; switch (data.type) { @@ -108,7 +113,7 @@ export class WSRouter extends Logger { await this.write({ type: MessageType.ERROR, id: data.id, error: (e as Error)?.stack || e }); } } else { - await this.write({ type: MessageType.ERROR, id: data.id, error: 'Route does not exist.' }); + await this.write({ type: MessageType.ERROR, id: data.id, error: `Route ${data.route} does not exist.` }); } break; @@ -152,6 +157,10 @@ export class WSRouter extends Logger { return resolver.promise; } + callable<Args extends any[] = any[], Return = void>(route: string): (...args: Args) => Promise<Return> { + return (...args) => this.call<Args, Return>(route, ...args); + } + async onError(error: any) { this.error('WS DISCONNECTED', error); await this.connect(); |
