mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-06-13 04:05:04 +03:00
Add loading bar to testing page and make downloading more robust
This commit is contained in:
@@ -137,27 +137,30 @@ class Updater:
|
||||
pass
|
||||
await sleep(60 * 60 * 6) # 6 hours
|
||||
|
||||
async def download_decky_binary(self, download_url: str, version: str, is_zip: bool = False):
|
||||
async def download_decky_binary(self, download_url: str, version: str, is_zip: bool = False, size_in_bytes: int | None = None):
|
||||
download_filename = "PluginLoader" if ON_LINUX else "PluginLoader.exe"
|
||||
download_temp_filename = download_filename + ".new"
|
||||
tab = await get_gamepadui_tab()
|
||||
await tab.open_websocket()
|
||||
|
||||
if size_in_bytes == None:
|
||||
size_in_bytes = 26214400 # 25MiB, a reasonable overestimate (19.6MiB as of 2024/02/25)
|
||||
|
||||
async with ClientSession() as web:
|
||||
logger.debug("Downloading binary")
|
||||
async with web.request("GET", download_url, ssl=helpers.get_ssl_context(), allow_redirects=True) as res:
|
||||
total = int(res.headers.get('content-length', 0))
|
||||
total = int(res.headers.get('content-length', size_in_bytes))
|
||||
if total == 0: total = 1
|
||||
with open(path.join(getcwd(), download_temp_filename), "wb") as out:
|
||||
progress = 0
|
||||
raw = 0
|
||||
async for c in res.content.iter_chunked(512):
|
||||
out.write(c)
|
||||
if total != 0:
|
||||
raw += len(c)
|
||||
new_progress = round((raw / total) * 100)
|
||||
if progress != new_progress:
|
||||
self.context.loop.create_task(self.context.ws.emit("updater/update_download_percentage", new_progress))
|
||||
progress = new_progress
|
||||
raw += len(c)
|
||||
new_progress = round((raw / total) * 100)
|
||||
if progress != new_progress:
|
||||
self.context.loop.create_task(self.context.ws.emit("updater/update_download_percentage", new_progress))
|
||||
progress = new_progress
|
||||
|
||||
with open(path.join(getcwd(), ".loader.version"), "w", encoding="utf-8") as out:
|
||||
out.write(version)
|
||||
@@ -277,9 +280,10 @@ class Updater:
|
||||
#If the request found at least one artifact to download...
|
||||
if int(jresp['total_count']) != 0:
|
||||
# this assumes that the artifact we want is the first one!
|
||||
down_link = f"https://nightly.link/SteamDeckHomebrew/decky-loader/actions/artifacts/{jresp['artifacts'][0]['id']}.zip"
|
||||
artifact = jresp['artifacts'][0]
|
||||
down_link = f"https://nightly.link/SteamDeckHomebrew/decky-loader/actions/artifacts/{artifact['id']}.zip"
|
||||
#Then fetch it and restart itself
|
||||
await self.download_decky_binary(down_link, f'PR-{pr_id}' , True)
|
||||
await self.download_decky_binary(down_link, f'PR-{pr_id}', is_zip=True, size_in_bytes=artifact.get('size_in_bytes',None))
|
||||
else:
|
||||
logger.error("workflow run not found", str(works))
|
||||
raise Exception("Workflow run not found.")
|
||||
|
||||
@@ -267,6 +267,8 @@
|
||||
"Testing": {
|
||||
"download": "Download",
|
||||
"header": "The following versions of Decky Loader are built from open third-party Pull Requests. The Decky Loader team has not verified their functionality or security, and they may be outdated.",
|
||||
"loading": "Loading open Pull Requests..."
|
||||
"loading": "Loading open Pull Requests...",
|
||||
"error": "Error Installing PR",
|
||||
"start_download_toast": "Downloading PR #{{id}}"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n
|
||||
}
|
||||
|
||||
export default function UpdaterSettings() {
|
||||
const { isLoaderUpdating, setIsLoaderUpdating, versionInfo, setVersionInfo } = useDeckyState();
|
||||
const { isLoaderUpdating, versionInfo, setVersionInfo } = useDeckyState();
|
||||
|
||||
const [checkingForUpdates, setCheckingForUpdates] = useState<boolean>(false);
|
||||
const [updateProgress, setUpdateProgress] = useState<number>(-1);
|
||||
@@ -77,7 +77,6 @@ export default function UpdaterSettings() {
|
||||
useEffect(() => {
|
||||
const a = DeckyBackend.addEventListener('updater/update_download_percentage', (percentage) => {
|
||||
setUpdateProgress(percentage);
|
||||
setIsLoaderUpdating(true);
|
||||
});
|
||||
|
||||
const b = DeckyBackend.addEventListener('updater/finish_download', () => {
|
||||
@@ -86,8 +85,8 @@ export default function UpdaterSettings() {
|
||||
});
|
||||
|
||||
return () => {
|
||||
DeckyBackend.removeEventListener('frontend/update_download_percentage', a);
|
||||
DeckyBackend.removeEventListener('frontend/finish_download', b);
|
||||
DeckyBackend.removeEventListener('updater/update_download_percentage', a);
|
||||
DeckyBackend.removeEventListener('updater/finish_download', b);
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
Field,
|
||||
Focusable,
|
||||
Navigation,
|
||||
ProgressBar,
|
||||
SteamSpinner,
|
||||
} from 'decky-frontend-lib';
|
||||
import { useEffect, useState } from 'react';
|
||||
@@ -26,8 +27,11 @@ const downloadTestingVersion = DeckyBackend.callable<[pr_id: number, sha: string
|
||||
|
||||
export default function TestingVersionList() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [testingVersions, setTestingVersions] = useState<TestingVersion[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [updateProgress, setUpdateProgress] = useState<number | null>(null);
|
||||
const [reloading, setReloading] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
@@ -36,6 +40,21 @@ export default function TestingVersionList() {
|
||||
})();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const a = DeckyBackend.addEventListener('updater/update_download_percentage', (percentage) => {
|
||||
setUpdateProgress(percentage);
|
||||
});
|
||||
|
||||
const b = DeckyBackend.addEventListener('updater/finish_download', () => {
|
||||
setReloading(true);
|
||||
});
|
||||
|
||||
return () => {
|
||||
DeckyBackend.removeEventListener('updater/update_download_percentage', a);
|
||||
DeckyBackend.removeEventListener('updater/finish_download', b);
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<>
|
||||
@@ -54,6 +73,7 @@ export default function TestingVersionList() {
|
||||
|
||||
return (
|
||||
<DialogBody>
|
||||
{updateProgress !== null && <ProgressBar nProgress={updateProgress} indeterminate={reloading} />}
|
||||
<DialogControlsSection>
|
||||
<h4>{t('Testing.header')}</h4>
|
||||
<ul style={{ listStyleType: 'none', padding: '0' }}>
|
||||
@@ -71,11 +91,18 @@ export default function TestingVersionList() {
|
||||
<DialogButton
|
||||
style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
|
||||
onClick={async () => {
|
||||
DeckyPluginLoader.toaster.toast({
|
||||
title: t('Testing.start_download_toast', { id: version.id }),
|
||||
body: null,
|
||||
});
|
||||
try {
|
||||
await downloadTestingVersion(version.id, version.head_sha);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
DeckyPluginLoader.toaster.toast({ title: 'Error Installing PR', body: e.message });
|
||||
DeckyPluginLoader.toaster.toast({
|
||||
title: t('Testing.error'),
|
||||
body: `${e.name}: ${e.message}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
setSetting('branch', UpdateBranch.Testing);
|
||||
|
||||
@@ -78,6 +78,9 @@ class PluginLoader extends Logger {
|
||||
'loader/add_multiple_plugins_install_prompt',
|
||||
this.addMultiplePluginsInstallPrompt.bind(this),
|
||||
);
|
||||
DeckyBackend.addEventListener('updater/update_download_percentage', () => {
|
||||
this.deckyState.setIsLoaderUpdating(true);
|
||||
});
|
||||
|
||||
this.tabsHook.init();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user