mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-06-13 12:15:09 +03:00
port updater to ws, also small refactoring
This commit is contained in:
@@ -2,7 +2,6 @@ from __future__ import annotations
|
||||
import os
|
||||
import shutil
|
||||
from asyncio import sleep
|
||||
from json.decoder import JSONDecodeError
|
||||
from logging import getLogger
|
||||
from os import getcwd, path, remove
|
||||
from typing import TYPE_CHECKING, List, TypedDict
|
||||
@@ -10,7 +9,7 @@ if TYPE_CHECKING:
|
||||
from .main import PluginManager
|
||||
from .localplatform.localplatform import chmod, service_restart, ON_LINUX, get_keep_systemd_service, get_selinux
|
||||
|
||||
from aiohttp import ClientSession, web
|
||||
from aiohttp import ClientSession
|
||||
|
||||
from . import helpers
|
||||
from .injector import get_gamepadui_tab
|
||||
@@ -30,14 +29,6 @@ class Updater:
|
||||
def __init__(self, context: PluginManager) -> None:
|
||||
self.context = context
|
||||
self.settings = self.context.settings
|
||||
# Exposes updater methods to frontend
|
||||
self.updater_methods = {
|
||||
"get_branch": self._get_branch,
|
||||
"get_version": self.get_version,
|
||||
"do_update": self.do_update,
|
||||
"do_restart": self.do_restart,
|
||||
"check_for_updates": self.check_for_updates
|
||||
}
|
||||
self.remoteVer: RemoteVer | None = None
|
||||
self.allRemoteVers: List[RemoteVer] = []
|
||||
self.localVer = helpers.get_loader_version()
|
||||
@@ -49,27 +40,12 @@ class Updater:
|
||||
logger.error("Current branch could not be determined, defaulting to \"Stable\"")
|
||||
|
||||
if context:
|
||||
context.web_app.add_routes([
|
||||
web.post("/updater/{method_name}", self._handle_server_method_call)
|
||||
])
|
||||
context.ws.add_route("updater/get_version_info", self.get_version_info);
|
||||
context.ws.add_route("updater/check_for_updates", self.check_for_updates);
|
||||
context.ws.add_route("updater/do_restart", self.do_restart);
|
||||
context.ws.add_route("updater/do_update", self.do_update);
|
||||
context.loop.create_task(self.version_reloader())
|
||||
|
||||
async def _handle_server_method_call(self, request: web.Request):
|
||||
method_name = request.match_info["method_name"]
|
||||
try:
|
||||
args = await request.json()
|
||||
except JSONDecodeError:
|
||||
args = {}
|
||||
res = {}
|
||||
try:
|
||||
r = await self.updater_methods[method_name](**args) # type: ignore
|
||||
res["result"] = r
|
||||
res["success"] = True
|
||||
except Exception as e:
|
||||
res["result"] = str(e)
|
||||
res["success"] = False
|
||||
return web.json_response(res)
|
||||
|
||||
def get_branch(self, manager: SettingsManager):
|
||||
ver = manager.getSetting("branch", -1)
|
||||
logger.debug("current branch: %i" % ver)
|
||||
@@ -102,7 +78,7 @@ class Updater:
|
||||
url = "https://raw.githubusercontent.com/SteamDeckHomebrew/decky-loader/main/dist/plugin_loader-prerelease.service"
|
||||
return str(url)
|
||||
|
||||
async def get_version(self):
|
||||
async def get_version_info(self):
|
||||
return {
|
||||
"current": self.localVer,
|
||||
"remote": self.remoteVer,
|
||||
@@ -139,7 +115,7 @@ class Updater:
|
||||
logger.info("Updated remote version information")
|
||||
tab = await get_gamepadui_tab()
|
||||
await tab.evaluate_js(f"window.DeckyPluginLoader.notifyUpdates()", False, True, False)
|
||||
return await self.get_version()
|
||||
return await self.get_version_info()
|
||||
|
||||
async def version_reloader(self):
|
||||
await sleep(30)
|
||||
|
||||
@@ -16,7 +16,7 @@ from .helpers import get_csrf_token
|
||||
|
||||
class MessageType(IntEnum):
|
||||
ERROR = -1
|
||||
# Call-reply, Frontend -> Backend
|
||||
# Call-reply, Frontend -> Backend -> Frontend
|
||||
CALL = 0
|
||||
REPLY = 1
|
||||
# Pub/Sub, Backend -> Frontend
|
||||
|
||||
@@ -46,7 +46,7 @@ const MultiplePluginsInstallModal: FC<MultiplePluginsInstallModalProps> = ({
|
||||
setLoading(true);
|
||||
await onOK();
|
||||
setTimeout(() => Navigation.OpenQuickAccessMenu(QuickAccessTab.Decky), 250);
|
||||
setTimeout(() => window.DeckyPluginLoader.checkPluginUpdates(), 1000);
|
||||
setTimeout(() => DeckyPluginLoader.checkPluginUpdates(), 1000);
|
||||
}}
|
||||
onCancel={async () => {
|
||||
await onCancel();
|
||||
|
||||
@@ -34,7 +34,7 @@ const PluginInstallModal: FC<PluginInstallModalProps> = ({
|
||||
setLoading(true);
|
||||
await onOK();
|
||||
setTimeout(() => Navigation.OpenQuickAccessMenu(QuickAccessTab.Decky), 250);
|
||||
setTimeout(() => window.DeckyPluginLoader.checkPluginUpdates(), 1000);
|
||||
setTimeout(() => DeckyPluginLoader.checkPluginUpdates(), 1000);
|
||||
}}
|
||||
onCancel={async () => {
|
||||
await onCancel();
|
||||
|
||||
@@ -19,7 +19,7 @@ const PluginUninstallModal: FC<PluginUninstallModalProps> = ({ name, title, butt
|
||||
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();
|
||||
await DeckyPluginLoader.hiddenPluginsService.invalidate();
|
||||
}}
|
||||
strTitle={title}
|
||||
strOKButtonText={buttonText}
|
||||
|
||||
@@ -95,7 +95,7 @@ const sortOptions = [
|
||||
},
|
||||
];
|
||||
|
||||
const getList = window.DeckyBackend.callable<
|
||||
const getList = DeckyBackend.callable<
|
||||
[
|
||||
path: string,
|
||||
includeFiles?: boolean,
|
||||
|
||||
@@ -13,9 +13,7 @@ function rePatch() {
|
||||
const details = window.appDetailsStore.GetAppDetails(appid);
|
||||
logger.debug('game details', details);
|
||||
// strShortcutStartDir
|
||||
const file = await window.DeckyPluginLoader.openFilePicker(
|
||||
details?.strShortcutStartDir.replaceAll('"', '') || '/',
|
||||
);
|
||||
const file = await DeckyPluginLoader.openFilePicker(details?.strShortcutStartDir.replaceAll('"', '') || '/');
|
||||
logger.debug('user selected', file);
|
||||
window.SteamClient.Apps.SetShortcutExe(appid, JSON.stringify(file.path));
|
||||
const pathArr = file.path.split('/');
|
||||
|
||||
@@ -28,20 +28,13 @@ const installFromZip = async () => {
|
||||
logger.error('The default path has not been found!');
|
||||
return;
|
||||
}
|
||||
window.DeckyPluginLoader.openFilePickerV2(
|
||||
FileSelectionType.FILE,
|
||||
path,
|
||||
true,
|
||||
true,
|
||||
undefined,
|
||||
['zip'],
|
||||
false,
|
||||
false,
|
||||
).then((val) => {
|
||||
const url = `file://${val.path}`;
|
||||
console.log(`Installing plugin locally from ${url}`);
|
||||
installFromURL(url);
|
||||
});
|
||||
DeckyPluginLoader.openFilePickerV2(FileSelectionType.FILE, path, true, true, undefined, ['zip'], false, false).then(
|
||||
(val) => {
|
||||
const url = `file://${val.path}`;
|
||||
console.log(`Installing plugin locally from ${url}`);
|
||||
installFromURL(url);
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export default function DeveloperSettings() {
|
||||
@@ -92,10 +85,7 @@ export default function DeveloperSettings() {
|
||||
<DialogButton
|
||||
onClick={async () => {
|
||||
try {
|
||||
let tabId = await window.DeckyBackend.call<[name: string], string>(
|
||||
'utilities/get_tab_id',
|
||||
'SharedJSContext',
|
||||
);
|
||||
let tabId = await DeckyBackend.call<[name: string], string>('utilities/get_tab_id', 'SharedJSContext');
|
||||
Navigation.NavigateToExternalWeb(
|
||||
'localhost:8080/devtools/inspector.html?ws=localhost:8080/devtools/page/' + tabId,
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { FunctionComponent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Logger from '../../../../logger';
|
||||
import { callUpdaterMethod } from '../../../../updater';
|
||||
import { checkForUpdates } from '../../../../updater';
|
||||
import { useSetting } from '../../../../utils/hooks/useSetting';
|
||||
|
||||
const logger = new Logger('BranchSelect');
|
||||
@@ -37,7 +37,7 @@ const BranchSelect: FunctionComponent<{}> = () => {
|
||||
selectedOption={selectedBranch}
|
||||
onChange={async (newVal) => {
|
||||
await setSelectedBranch(newVal.data);
|
||||
callUpdaterMethod('check_for_updates');
|
||||
checkForUpdates();
|
||||
logger.log('switching branches!');
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useDeckyState } from '../../../DeckyState';
|
||||
|
||||
const NotificationSettings: FC = () => {
|
||||
const { notificationSettings } = useDeckyState();
|
||||
const notificationService = window.DeckyPluginLoader.notificationService;
|
||||
const notificationService = DeckyPluginLoader.notificationService;
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ export default function RemoteDebuggingSettings() {
|
||||
value={allowRemoteDebugging || false}
|
||||
onChange={(toggleValue) => {
|
||||
setAllowRemoteDebugging(toggleValue);
|
||||
if (toggleValue) window.DeckyBackend.call('allow_remote_debugging');
|
||||
else window.DeckyBackend.call('disallow_remote_debugging');
|
||||
if (toggleValue) DeckyBackend.call('allow_remote_debugging');
|
||||
else DeckyBackend.call('disallow_remote_debugging');
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
@@ -15,7 +15,7 @@ import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaExclamation } from 'react-icons/fa';
|
||||
|
||||
import { VerInfo, callUpdaterMethod, finishUpdate } from '../../../../updater';
|
||||
import { VerInfo, checkForUpdates, doRestart, doUpdate } from '../../../../updater';
|
||||
import { useDeckyState } from '../../../DeckyState';
|
||||
import InlinePatchNotes from '../../../patchnotes/InlinePatchNotes';
|
||||
import WithSuspense from '../../../WithSuspense';
|
||||
@@ -85,7 +85,7 @@ export default function UpdaterSettings() {
|
||||
finish: async () => {
|
||||
setUpdateProgress(0);
|
||||
setReloading(true);
|
||||
await finishUpdate();
|
||||
await doRestart();
|
||||
},
|
||||
};
|
||||
}, []);
|
||||
@@ -122,13 +122,13 @@ export default function UpdaterSettings() {
|
||||
!versionInfo?.remote || versionInfo?.remote?.tag_name == versionInfo?.current
|
||||
? async () => {
|
||||
setCheckingForUpdates(true);
|
||||
const res = (await callUpdaterMethod('check_for_updates')) as { result: VerInfo };
|
||||
setVersionInfo(res.result);
|
||||
const verInfo = await checkForUpdates();
|
||||
setVersionInfo(verInfo);
|
||||
setCheckingForUpdates(false);
|
||||
}
|
||||
: async () => {
|
||||
setUpdateProgress(0);
|
||||
callUpdaterMethod('do_update');
|
||||
doUpdate();
|
||||
}
|
||||
}
|
||||
>
|
||||
|
||||
@@ -35,7 +35,7 @@ async function reinstallPlugin(pluginName: string, currentVersion?: string) {
|
||||
|
||||
type PluginTableData = PluginData & { name: string; hidden: boolean; onHide(): void; onShow(): void };
|
||||
|
||||
const reloadPluginBackend = window.DeckyBackend.callable<[pluginName: string], void>('loader/reload_plugin');
|
||||
const reloadPluginBackend = DeckyBackend.callable<[pluginName: string], void>('loader/reload_plugin');
|
||||
|
||||
function PluginInteractables(props: { entry: ReorderableEntry<PluginTableData> }) {
|
||||
const { t } = useTranslation();
|
||||
@@ -58,14 +58,14 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginTableData> }
|
||||
console.error('Error Reloading Plugin Backend', err);
|
||||
}
|
||||
|
||||
window.DeckyPluginLoader.importPlugin(name, version);
|
||||
DeckyPluginLoader.importPlugin(name, version);
|
||||
}}
|
||||
>
|
||||
{t('PluginListIndex.reload')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onSelected={() =>
|
||||
window.DeckyPluginLoader.uninstallPlugin(
|
||||
DeckyPluginLoader.uninstallPlugin(
|
||||
name,
|
||||
t('PluginLoader.plugin_uninstall.title', { name }),
|
||||
t('PluginLoader.plugin_uninstall.button'),
|
||||
@@ -143,11 +143,11 @@ export default function PluginList() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
window.DeckyPluginLoader.checkPluginUpdates();
|
||||
DeckyPluginLoader.checkPluginUpdates();
|
||||
}, []);
|
||||
|
||||
const [pluginEntries, setPluginEntries] = useState<ReorderableEntry<PluginTableData>[]>([]);
|
||||
const hiddenPluginsService = window.DeckyPluginLoader.hiddenPluginsService;
|
||||
const hiddenPluginsService = DeckyPluginLoader.hiddenPluginsService;
|
||||
|
||||
useEffect(() => {
|
||||
setPluginEntries(
|
||||
|
||||
@@ -38,7 +38,7 @@ export async function setShowValveInternal(show: boolean) {
|
||||
}
|
||||
|
||||
export async function setShouldConnectToReactDevTools(enable: boolean) {
|
||||
window.DeckyPluginLoader.toaster.toast({
|
||||
DeckyPluginLoader.toaster.toast({
|
||||
title: enable ? (
|
||||
<TranslationHelper trans_class={TranslationClass.DEVELOPER} trans_text={'enabling'} />
|
||||
) : (
|
||||
@@ -48,7 +48,7 @@ export async function setShouldConnectToReactDevTools(enable: boolean) {
|
||||
icon: <FaReact />,
|
||||
});
|
||||
await sleep(5000);
|
||||
return enable ? window.DeckyBackend.call('utilities/enable_rdt') : window.DeckyBackend.call('utilities/disable_rdt');
|
||||
return enable ? DeckyBackend.call('utilities/enable_rdt') : DeckyBackend.call('utilities/disable_rdt');
|
||||
}
|
||||
|
||||
export async function startup() {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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();
|
||||
await DeckyBackend.connect();
|
||||
console.debug('Starting Decky!');
|
||||
await import('./start');
|
||||
})();
|
||||
|
||||
@@ -28,10 +28,10 @@ import { NotificationService } from './notification-service';
|
||||
import { InstallType, Plugin } from './plugin';
|
||||
import RouterHook from './router-hook';
|
||||
import { deinitSteamFixes, initSteamFixes } from './steamfixes';
|
||||
import { checkForUpdates } from './store';
|
||||
import { checkForPluginUpdates } from './store';
|
||||
import TabsHook from './tabs-hook';
|
||||
import Toaster from './toaster';
|
||||
import { VerInfo, callUpdaterMethod } from './updater';
|
||||
import { getVersionInfo } from './updater';
|
||||
import { getSetting, setSetting } from './utils/settings';
|
||||
import TranslationHelper, { TranslationClass } from './utils/TranslationHelper';
|
||||
|
||||
@@ -106,9 +106,7 @@ class PluginLoader extends Logger {
|
||||
.then(() => this.log('Initialized'));
|
||||
}
|
||||
|
||||
private getPluginsFromBackend = window.DeckyBackend.callable<[], { name: string; version: string }[]>(
|
||||
'loader/get_plugins',
|
||||
);
|
||||
private getPluginsFromBackend = DeckyBackend.callable<[], { name: string; version: string }[]>('loader/get_plugins');
|
||||
|
||||
private async loadPlugins() {
|
||||
// wait for SP window to exist before loading plugins
|
||||
@@ -129,13 +127,13 @@ class PluginLoader extends Logger {
|
||||
}
|
||||
|
||||
public async getUserInfo() {
|
||||
const userInfo = await window.DeckyBackend.call<[], UserInfo>('utilities/get_user_info');
|
||||
const userInfo = await DeckyBackend.call<[], UserInfo>('utilities/get_user_info');
|
||||
setSetting('user_info.user_name', userInfo.username);
|
||||
setSetting('user_info.user_home', userInfo.path);
|
||||
}
|
||||
|
||||
public async updateVersion() {
|
||||
const versionInfo = (await callUpdaterMethod('get_version')).result as VerInfo;
|
||||
const versionInfo = await getVersionInfo();
|
||||
this.deckyState.setVersionInfo(versionInfo);
|
||||
|
||||
return versionInfo;
|
||||
@@ -164,7 +162,7 @@ class PluginLoader extends Logger {
|
||||
}
|
||||
|
||||
public async checkPluginUpdates() {
|
||||
const updates = await checkForUpdates(this.plugins);
|
||||
const updates = await checkForPluginUpdates(this.plugins);
|
||||
this.deckyState.setUpdates(updates);
|
||||
return updates;
|
||||
}
|
||||
@@ -199,8 +197,8 @@ class PluginLoader extends Logger {
|
||||
version={version}
|
||||
hash={hash}
|
||||
installType={install_type}
|
||||
onOK={() => window.DeckyBackend.call<[string]>('utilities/confirm_plugin_install', request_id)}
|
||||
onCancel={() => window.DeckyBackend.call<[string]>('utilities/cancel_plugin_install', request_id)}
|
||||
onOK={() => DeckyBackend.call<[string]>('utilities/confirm_plugin_install', request_id)}
|
||||
onCancel={() => DeckyBackend.call<[string]>('utilities/cancel_plugin_install', request_id)}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
@@ -212,8 +210,8 @@ class PluginLoader extends Logger {
|
||||
showModal(
|
||||
<MultiplePluginsInstallModal
|
||||
requests={requests}
|
||||
onOK={() => window.DeckyBackend.call<[string]>('utilities/confirm_plugin_install', request_id)}
|
||||
onCancel={() => window.DeckyBackend.call<[string]>('utilities/cancel_plugin_install', request_id)}
|
||||
onOK={() => DeckyBackend.call<[string]>('utilities/confirm_plugin_install', request_id)}
|
||||
onCancel={() => DeckyBackend.call<[string]>('utilities/cancel_plugin_install', request_id)}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
@@ -298,7 +296,7 @@ class PluginLoader extends Logger {
|
||||
let res = await fetch(`http://127.0.0.1:1337/plugins/${name}/frontend_bundle`, {
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Authentication: window.deckyAuthToken,
|
||||
Authentication: deckyAuthToken,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -364,7 +362,7 @@ class PluginLoader extends Logger {
|
||||
this.warn(
|
||||
`Calling ${methodName} via callServerMethod, which is deprecated and will be removed in a future release. Please switch to the backend API.`,
|
||||
);
|
||||
return await window.DeckyBackend.call<[methodName: string, kwargs: any], any>(
|
||||
return await DeckyBackend.call<[methodName: string, kwargs: any], any>(
|
||||
'utilities/_call_legacy_utility',
|
||||
methodName,
|
||||
args,
|
||||
@@ -429,7 +427,7 @@ class PluginLoader extends Logger {
|
||||
const pluginAPI = {
|
||||
backend: {
|
||||
call<Args extends any[] = any[], Return = void>(method: string, ...args: Args): Promise<Return> {
|
||||
return window.DeckyBackend.call<[pluginName: string, method: string, ...args: Args], Return>(
|
||||
return DeckyBackend.call<[pluginName: string, method: string, ...args: Args], Return>(
|
||||
'loader/call_plugin_method',
|
||||
pluginName,
|
||||
method,
|
||||
@@ -448,7 +446,7 @@ class PluginLoader extends Logger {
|
||||
openFilePickerV2: this.openFilePickerV2,
|
||||
// Legacy
|
||||
async callPluginMethod(methodName: string, args = {}) {
|
||||
return window.DeckyBackend.call<[pluginName: string, methodName: string, kwargs: any], any>(
|
||||
return DeckyBackend.call<[pluginName: string, methodName: string, kwargs: any], any>(
|
||||
'loader/call_legacy_plugin_method',
|
||||
pluginName,
|
||||
methodName,
|
||||
@@ -472,7 +470,7 @@ class PluginLoader extends Logger {
|
||||
}
|
||||
// this is terrible but a. we're going to redo this entire method anyway and b. it was already terrible
|
||||
try {
|
||||
const ret = await window.DeckyBackend.call<
|
||||
const ret = await DeckyBackend.call<
|
||||
[method: string, url: string, extra_opts?: any],
|
||||
{ status: number; headers: { [key: string]: string }; body: string }
|
||||
>('utilities/http_request', method, url, req);
|
||||
@@ -481,14 +479,12 @@ class PluginLoader extends Logger {
|
||||
return { success: false, result: e?.toString() };
|
||||
}
|
||||
},
|
||||
executeInTab: window.DeckyBackend.callable<
|
||||
executeInTab: DeckyBackend.callable<
|
||||
[tab: String, runAsync: Boolean, code: string],
|
||||
{ success: boolean; result: any }
|
||||
>('utilities/execute_in_tab'),
|
||||
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'),
|
||||
injectCssIntoTab: DeckyBackend.callable<[tab: string, style: string], string>('utilities/inject_css_into_tab'),
|
||||
removeCssFromTab: DeckyBackend.callable<[tab: string, cssId: string]>('utilities/remove_css_from_tab'),
|
||||
};
|
||||
|
||||
return pluginAPI;
|
||||
|
||||
@@ -22,7 +22,7 @@ type installPluginArgs = [
|
||||
installType?: InstallType,
|
||||
];
|
||||
|
||||
export let installPlugin = window.DeckyBackend.callable<installPluginArgs>('utilities/install_plugin');
|
||||
export let installPlugin = DeckyBackend.callable<installPluginArgs>('utilities/install_plugin');
|
||||
|
||||
type installPluginsArgs = [
|
||||
requests: {
|
||||
@@ -34,6 +34,6 @@ type installPluginsArgs = [
|
||||
}[],
|
||||
];
|
||||
|
||||
export let installPlugins = window.DeckyBackend.callable<installPluginsArgs>('utilities/install_plugins');
|
||||
export let installPlugins = DeckyBackend.callable<installPluginsArgs>('utilities/install_plugins');
|
||||
|
||||
export let uninstallPlugin = window.DeckyBackend.callable<[name: string]>('utilities/uninstall_plugin');
|
||||
export let uninstallPlugin = DeckyBackend.callable<[name: string]>('utilities/uninstall_plugin');
|
||||
|
||||
+12
-14
@@ -6,15 +6,13 @@ import PluginLoader from './plugin-loader';
|
||||
import { DeckyUpdater } from './updater';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
DeckyPluginLoader: PluginLoader;
|
||||
DeckyUpdater?: DeckyUpdater;
|
||||
importDeckyPlugin: Function;
|
||||
deckyHasLoaded: boolean;
|
||||
deckyHasConnectedRDT?: boolean;
|
||||
deckyAuthToken: string;
|
||||
DFL?: any;
|
||||
}
|
||||
export var DeckyPluginLoader: PluginLoader;
|
||||
export var DeckyUpdater: DeckyUpdater | undefined; // TODO get rid of this
|
||||
export var importDeckyPlugin: Function;
|
||||
export var deckyHasLoaded: boolean;
|
||||
export var deckyHasConnectedRDT: boolean | undefined;
|
||||
export var deckyAuthToken: string;
|
||||
export var DFL: any | undefined;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
@@ -37,7 +35,7 @@ declare global {
|
||||
backend: {
|
||||
loadPath: 'http://127.0.0.1:1337/locales/{{lng}}.json',
|
||||
customHeaders: {
|
||||
Authentication: window.deckyAuthToken,
|
||||
Authentication: deckyAuthToken,
|
||||
},
|
||||
requestOptions: {
|
||||
credentials: 'include',
|
||||
@@ -45,12 +43,12 @@ declare global {
|
||||
},
|
||||
});
|
||||
|
||||
window.DeckyPluginLoader?.dismountAll();
|
||||
window.DeckyPluginLoader?.deinit();
|
||||
window?.DeckyPluginLoader?.dismountAll();
|
||||
window?.DeckyPluginLoader?.deinit();
|
||||
window.DeckyPluginLoader = new PluginLoader();
|
||||
window.DeckyPluginLoader.init();
|
||||
DeckyPluginLoader.init();
|
||||
window.importDeckyPlugin = function (name: string, version: string) {
|
||||
window.DeckyPluginLoader?.importPlugin(name, version);
|
||||
DeckyPluginLoader?.importPlugin(name, version);
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export async function getStore(): Promise<Store> {
|
||||
}
|
||||
|
||||
export async function getPluginList(): Promise<StorePlugin[]> {
|
||||
let version = await window.DeckyPluginLoader.updateVersion();
|
||||
let version = await DeckyPluginLoader.updateVersion();
|
||||
let store = await getSetting<Store | null>('store', null);
|
||||
let customURL = await getSetting<string>('store-url', 'https://plugins.deckbrew.xyz/plugins');
|
||||
let storeURL;
|
||||
@@ -112,7 +112,7 @@ export async function requestMultiplePluginInstalls(requests: PluginInstallReque
|
||||
);
|
||||
}
|
||||
|
||||
export async function checkForUpdates(plugins: Plugin[]): Promise<PluginUpdateMapping> {
|
||||
export async function checkForPluginUpdates(plugins: Plugin[]): Promise<PluginUpdateMapping> {
|
||||
const serverData = await getPluginList();
|
||||
const updateMap = new Map<string, StorePluginVersion>();
|
||||
for (let plugin of plugins) {
|
||||
|
||||
+4
-17
@@ -28,20 +28,7 @@ export interface VerInfo {
|
||||
updatable: boolean;
|
||||
}
|
||||
|
||||
export async function callUpdaterMethod(methodName: string, args = {}) {
|
||||
const response = await fetch(`http://127.0.0.1:1337/updater/${methodName}`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authentication: window.deckyAuthToken,
|
||||
},
|
||||
body: JSON.stringify(args),
|
||||
});
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
export async function finishUpdate() {
|
||||
callUpdaterMethod('do_restart');
|
||||
}
|
||||
export const doUpdate = DeckyBackend.callable('updater/do_update');
|
||||
export const doRestart = DeckyBackend.callable('updater/do_restart');
|
||||
export const getVersionInfo = DeckyBackend.callable<[], VerInfo>('updater/get_version_info');
|
||||
export const checkForUpdates = DeckyBackend.callable<[], VerInfo>('updater/check_for_updates');
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
export async function getSetting<T>(key: string, def: T): Promise<T> {
|
||||
const res = await window.DeckyBackend.call<[string, T], T>('utilities/settings/get', key, def);
|
||||
const res = await 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.DeckyBackend.call<[string, T], void>('utilities/settings/set', key, value);
|
||||
await DeckyBackend.call<[string, T], void>('utilities/settings/set', key, value);
|
||||
}
|
||||
|
||||
@@ -3,14 +3,12 @@ import { sleep } from 'decky-frontend-lib';
|
||||
import Logger from './logger';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
DeckyBackend: WSRouter;
|
||||
}
|
||||
export var DeckyBackend: WSRouter;
|
||||
}
|
||||
|
||||
enum MessageType {
|
||||
ERROR = -1,
|
||||
// Call-reply, Frontend -> Backend
|
||||
// Call-reply, Frontend -> Backend -> Frontend
|
||||
CALL = 0,
|
||||
REPLY = 1,
|
||||
// Pub/Sub, Backend -> Frontend
|
||||
@@ -22,8 +20,6 @@ interface CallMessage {
|
||||
args: any[];
|
||||
route: string;
|
||||
id: number;
|
||||
// TODO implement this
|
||||
// skipResponse?: boolean;
|
||||
}
|
||||
|
||||
interface ReplyMessage {
|
||||
@@ -61,7 +57,7 @@ export class WSRouter extends Logger {
|
||||
connect() {
|
||||
return (this.connectPromise = new Promise<void>((resolve) => {
|
||||
// Auth is a query param as JS WebSocket doesn't support headers
|
||||
this.ws = new WebSocket(`ws://127.0.0.1:1337/ws?auth=${window.deckyAuthToken}`);
|
||||
this.ws = new WebSocket(`ws://127.0.0.1:1337/ws?auth=${deckyAuthToken}`);
|
||||
|
||||
this.ws.addEventListener('open', () => {
|
||||
this.debug('WS Connected');
|
||||
@@ -129,7 +125,7 @@ export class WSRouter extends Logger {
|
||||
if (this.runningCalls.has(data.id)) {
|
||||
this.runningCalls.get(data.id)!.reject(data.error);
|
||||
this.runningCalls.delete(data.id);
|
||||
this.debug(`Errored PY call ${data.id} with error`, data.error);
|
||||
this.debug(`Rejected PY call ${data.id} with error`, data.error);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -143,7 +139,7 @@ export class WSRouter extends Logger {
|
||||
}
|
||||
|
||||
// this.call<[number, number], string>('methodName', 1, 2);
|
||||
call<Args extends any[] = any[], Return = void>(route: string, ...args: Args): Promise<Return> {
|
||||
call<Args extends any[] = [], Return = void>(route: string, ...args: Args): Promise<Return> {
|
||||
const resolver = this.createPromiseResolver<Return>();
|
||||
|
||||
const id = ++this.reqId;
|
||||
@@ -157,7 +153,7 @@ export class WSRouter extends Logger {
|
||||
return resolver.promise;
|
||||
}
|
||||
|
||||
callable<Args extends any[] = any[], Return = void>(route: string): (...args: Args) => Promise<Return> {
|
||||
callable<Args extends any[] = [], Return = void>(route: string): (...args: Args) => Promise<Return> {
|
||||
return (...args) => this.call<Args, Return>(route, ...args);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user