Addition of proper branch slection (#168)

* This is a bit better, but branch selection still isn't working -_-

* I'm the king of oversight

* Selecting different branch checks for updates

* Stable doesn't detect old versions, which indicates it doesn't work

* Start adding deckyState for plugin updating

* Few tweaks

* Disable nightly selection

* Update decky-frontend-lib and move useSetting set setting to async
This commit is contained in:
TrainDoctor
2022-09-01 13:46:49 -07:00
committed by GitHub
parent 16a6e9b6a9
commit eb439574be
9 changed files with 80 additions and 49 deletions
+38 -11
View File
@@ -1,25 +1,26 @@
import uuid
from logging import getLogger
from json.decoder import JSONDecodeError
from asyncio import sleep
from ensurepip import version
from json.decoder import JSONDecodeError
from logging import getLogger
from os import getcwd, path, remove
from subprocess import call
from aiohttp import ClientSession, web
from injector import inject_to_tab, get_tab
from os import getcwd, path, remove
from subprocess import call
import helpers
from injector import get_tab, inject_to_tab
from settings import SettingsManager
logger = getLogger("Updater")
class Updater:
def __init__(self, context) -> 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,
@@ -27,6 +28,13 @@ class Updater:
}
self.remoteVer = None
self.allRemoteVers = None
try:
self.currentBranch = self.get_branch(self.context.settings)
if int(self.currentBranch) == -1:
raise ValueError("get_branch could not determine branch!")
except:
self.currentBranch = 0
logger.error("Current branch could not be determined, defaulting to \"Stable\"")
try:
with open(path.join(getcwd(), ".loader.version"), 'r') as version_file:
self.localVer = version_file.readline().replace("\n", "")
@@ -55,6 +63,10 @@ class Updater:
res["success"] = False
return web.json_response(res)
async def get_branch(self, manager: SettingsManager):
logger.debug("current branch: %i" % manager.getSetting("branch", -1))
return manager.getSetting("branch", -1)
async def get_version(self):
if self.localVer:
return {
@@ -67,11 +79,27 @@ class Updater:
return {"current": "unknown", "remote": self.remoteVer, "all": self.allRemoteVers, "updatable": False}
async def check_for_updates(self):
logger.debug("checking for updates")
selectedBranch = await self.get_branch(self.context.settings)
async with ClientSession() as web:
async with web.request("GET", "https://api.github.com/repos/SteamDeckHomebrew/decky-loader/releases", ssl=helpers.get_ssl_context()) as res:
remoteVersions = await res.json()
self.allRemoteVers = remoteVersions
self.remoteVer = next(filter(lambda ver: ver["prerelease"] and ver["tag_name"].startswith("v") and ver["tag_name"].find("-pre"), remoteVersions), None)
logger.debug("determining release type to find, branch is %i" % selectedBranch)
if selectedBranch == 0:
logger.debug("release type: release")
self.remoteVer = next(filter(lambda ver: ver["tag_name"].startswith("v") and not ver["prerelease"] and ver["tag_name"], remoteVersions), None)
elif selectedBranch == 1:
logger.debug("release type: pre-release")
self.remoteVer = next(filter(lambda ver: ver["prerelease"] and ver["tag_name"].startswith("v") and ver["tag_name"].find("-pre"), remoteVersions), None)
# elif selectedBranch == 2:
# logger.debug("release type: nightly")
# self.remoteVer = next(filter(lambda ver: ver["prerelease"] and ver["tag_name"].startswith("v") and ver["tag_name"].find("nightly"), remoteVersions), None)
else:
logger.error("release type: NOT FOUND")
raise ValueError("no valid branch found")
# doesn't make it to this line below or farther
# logger.debug("Remote Version: %s" % self.remoteVer.find("name"))
logger.info("Updated remote version information")
tab = await get_tab("SP")
await tab.evaluate_js(f"window.DeckyPluginLoader.notifyUpdates()", False, True, False)
@@ -88,7 +116,6 @@ class Updater:
async def do_update(self):
version = self.remoteVer["tag_name"]
#TODO don't hardcode this
download_url = self.remoteVer["assets"][0]["browser_download_url"]
tab = await get_tab("SP")
+1 -1
View File
@@ -39,7 +39,7 @@
}
},
"dependencies": {
"decky-frontend-lib": "^1.8.0",
"decky-frontend-lib": "^1.8.2",
"react-icons": "^4.4.0",
"react-markdown": "^8.0.3",
"remark-gfm": "^3.0.1"
+4 -4
View File
@@ -9,7 +9,7 @@ specifiers:
'@types/react': 16.14.0
'@types/react-router': 5.1.18
'@types/webpack': ^5.28.0
decky-frontend-lib: ^1.8.0
decky-frontend-lib: ^1.8.2
husky: ^8.0.1
import-sort-style-module: ^6.0.0
inquirer: ^8.2.4
@@ -27,7 +27,7 @@ specifiers:
typescript: ^4.7.4
dependencies:
decky-frontend-lib: 1.8.0
decky-frontend-lib: 1.8.2
react-icons: 4.4.0_react@16.14.0
react-markdown: 8.0.3_vshvapmxg47tngu7tvrsqpq55u
remark-gfm: 3.0.1
@@ -875,8 +875,8 @@ packages:
dependencies:
ms: 2.1.2
/decky-frontend-lib/1.8.0:
resolution: {integrity: sha512-ZPJdbkNI5d/d/19Hv97FVgFyMerYUzwXavYGv8euLMrbH9XuVM4KAx0mbKkO0SQUl75HKQ3LxsaCpA6QLDr9EA==}
/decky-frontend-lib/1.8.2:
resolution: {integrity: sha512-SwGoUBpKd8OM3kovItW+oCpevDiDXFu0UaUh1vyD4BYG0s+4uQBdeevWLhyJHk0402pAUDrOL8022jpana5dnA==}
dependencies:
minimist: 1.2.6
dev: false
+12 -1
View File
@@ -2,6 +2,7 @@ import { FC, createContext, useContext, useEffect, useState } from 'react';
import { Plugin } from '../plugin';
import { PluginUpdateMapping } from '../store';
import { VerInfo } from '../updater';
interface PublicDeckyState {
plugins: Plugin[];
@@ -9,6 +10,7 @@ interface PublicDeckyState {
updates: PluginUpdateMapping | null;
hasLoaderUpdate?: boolean;
isLoaderUpdating: boolean;
versionInfo: VerInfo | null;
}
export class DeckyState {
@@ -17,6 +19,7 @@ export class DeckyState {
private _updates: PluginUpdateMapping | null = null;
private _hasLoaderUpdate: boolean = false;
private _isLoaderUpdating: boolean = false;
private _versionInfo: VerInfo | null = null;
public eventBus = new EventTarget();
@@ -27,9 +30,15 @@ export class DeckyState {
updates: this._updates,
hasLoaderUpdate: this._hasLoaderUpdate,
isLoaderUpdating: this._isLoaderUpdating,
versionInfo: this._versionInfo,
};
}
setVersionInfo(versionInfo: VerInfo) {
this._versionInfo = versionInfo;
this.notifyUpdate();
}
setPlugins(plugins: Plugin[]) {
this._plugins = plugins;
this.notifyUpdate();
@@ -66,6 +75,7 @@ export class DeckyState {
}
interface DeckyStateContext extends PublicDeckyState {
setVersionInfo(versionInfo: VerInfo): void;
setIsLoaderUpdating(hasUpdate: boolean): void;
setActivePlugin(name: string): void;
closeActivePlugin(): void;
@@ -93,12 +103,13 @@ export const DeckyStateContextProvider: FC<Props> = ({ children, deckyState }) =
}, []);
const setIsLoaderUpdating = (hasUpdate: boolean) => deckyState.setIsLoaderUpdating(hasUpdate);
const setVersionInfo = (versionInfo: VerInfo) => deckyState.setVersionInfo(versionInfo);
const setActivePlugin = (name: string) => deckyState.setActivePlugin(name);
const closeActivePlugin = () => deckyState.closeActivePlugin();
return (
<DeckyStateContext.Provider
value={{ ...publicDeckyState, setIsLoaderUpdating, setActivePlugin, closeActivePlugin }}
value={{ ...publicDeckyState, setIsLoaderUpdating, setVersionInfo, setActivePlugin, closeActivePlugin }}
>
{children}
</DeckyStateContext.Provider>
@@ -1,18 +1,21 @@
import { Dropdown, Field } from 'decky-frontend-lib';
import { FunctionComponent } from 'react';
import { callUpdaterMethod } from '../../../../updater';
import { useSetting } from '../../../../utils/hooks/useSetting';
enum UpdateBranch {
Stable,
Prerelease,
Nightly,
// Nightly,
}
const BranchSelect: FunctionComponent<{}> = () => {
const [selectedBranch, setSelectedBranch] = useSetting<UpdateBranch>('branch', UpdateBranch.Prerelease);
return (
// Returns numerical values from 0 to 2 (with current branch setup as of 8/28/22)
// 0 being stable, 1 being pre-release and 2 being nightly
<Field label="Update Channel">
<Dropdown
rgOptions={Object.values(UpdateBranch)
@@ -22,8 +25,10 @@ const BranchSelect: FunctionComponent<{}> = () => {
data: UpdateBranch[branch],
}))}
selectedOption={selectedBranch}
onChange={(newVal) => {
setSelectedBranch(newVal.data);
onChange={async (newVal) => {
await setSelectedBranch(newVal.data);
callUpdaterMethod('check_for_updates');
console.log('switching branches!');
}}
/>
</Field>
@@ -55,20 +55,12 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n
}
export default function UpdaterSettings() {
const { isLoaderUpdating, setIsLoaderUpdating } = useDeckyState();
const { isLoaderUpdating, setIsLoaderUpdating, versionInfo, setVersionInfo } = useDeckyState();
const [versionInfo, setVersionInfo] = useState<VerInfo | null>(null);
const [checkingForUpdates, setCheckingForUpdates] = useState<boolean>(false);
const [updateProgress, setUpdateProgress] = useState<number>(-1);
const [reloading, setReloading] = useState<boolean>(false);
useEffect(() => {
(async () => {
const res = (await callUpdaterMethod('get_version')) as { result: VerInfo };
setVersionInfo(res.result);
})();
}, []);
useEffect(() => {
window.DeckyUpdater = {
updateProgress: (i) => {
@@ -3,7 +3,7 @@ import { useState } from 'react';
import { FaShapes } from 'react-icons/fa';
import { installFromURL } from '../../../../store';
// import BranchSelect from './BranchSelect';
import BranchSelect from './BranchSelect';
import RemoteDebuggingSettings from './RemoteDebugging';
import UpdaterSettings from './Updater';
@@ -22,7 +22,7 @@ export default function GeneralSettings() {
/>
</Field> */}
<UpdaterSettings />
{/* <BranchSelect /> */}
<BranchSelect />
<RemoteDebuggingSettings />
<Field
label="Manual plugin install"
+3 -4
View File
@@ -52,10 +52,8 @@ class PluginLoader extends Logger {
),
icon: (
<DeckyStateContextProvider deckyState={this.deckyState}>
<>
<FaPlug />
<TabIcon />
</>
<FaPlug />
<TabIcon />
</DeckyStateContextProvider>
),
});
@@ -105,6 +103,7 @@ class PluginLoader extends Logger {
public async notifyUpdates() {
const versionInfo = (await callUpdaterMethod('get_version')).result as VerInfo;
this.deckyState.setVersionInfo(versionInfo);
if (versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current) {
this.toaster.toast({
title: 'Decky',
+11 -14
View File
@@ -10,9 +10,8 @@ interface SetSettingArgs<T> {
value: T;
}
export function useSetting<T>(key: string, def: T): [value: T | null, setValue: (value: T) => void] {
export function useSetting<T>(key: string, def: T): [value: T | null, setValue: (value: T) => Promise<void>] {
const [value, setValue] = useState(def);
const [ready, setReady] = useState<boolean>(false);
useEffect(() => {
(async () => {
@@ -20,20 +19,18 @@ export function useSetting<T>(key: string, def: T): [value: T | null, setValue:
key,
default: def,
} as GetSettingArgs<T>)) as { result: T };
setReady(true);
setValue(res.result);
})();
}, []);
useEffect(() => {
if (ready)
(async () => {
await window.DeckyPluginLoader.callServerMethod('set_setting', {
key,
value,
} as SetSettingArgs<T>);
})();
}, [value]);
return [value, setValue];
return [
value,
async (val: T) => {
setValue(val);
await window.DeckyPluginLoader.callServerMethod('set_setting', {
key,
value: val,
} as SetSettingArgs<T>);
},
];
}