From 372771a228c9fbb31ec4a943dd6cfa9915741c6c Mon Sep 17 00:00:00 2001 From: Party Wumpus <48649272+PartyWumpus@users.noreply.github.com> Date: Mon, 13 May 2024 14:42:55 +0100 Subject: plugin install progress (#614) * Frontend progress bars * Backend bit * closure is stale i think so no closure for you * Fix formatting of the progress svgs * Reset progress bar when new plugin starts downloading --- .../modals/MultiplePluginsInstallModal.tsx | 55 ++++++++++++++++++++-- .../src/components/modals/PluginInstallModal.tsx | 30 +++++++++++- 2 files changed, 80 insertions(+), 5 deletions(-) (limited to 'frontend') diff --git a/frontend/src/components/modals/MultiplePluginsInstallModal.tsx b/frontend/src/components/modals/MultiplePluginsInstallModal.tsx index 73b8acb1..ba49ba92 100644 --- a/frontend/src/components/modals/MultiplePluginsInstallModal.tsx +++ b/frontend/src/components/modals/MultiplePluginsInstallModal.tsx @@ -1,6 +1,7 @@ -import { ConfirmModal, Navigation, QuickAccessTab } from '@decky/ui'; -import { FC, useMemo, useState } from 'react'; +import { ConfirmModal, Navigation, ProgressBarWithInfo, QuickAccessTab } from '@decky/ui'; +import { FC, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { FaCheck, FaDownload } from 'react-icons/fa'; import { InstallType } from '../../plugin'; @@ -27,8 +28,42 @@ const MultiplePluginsInstallModal: FC = ({ closeModal, }) => { const [loading, setLoading] = useState(false); + const [percentage, setPercentage] = useState(0); + const [pluginsCompleted, setPluginsCompleted] = useState([]); + const [pluginInProgress, setInProgress] = useState(); + const [downloadInfo, setDownloadInfo] = useState(null); const { t } = useTranslation(); + function updateDownloadState(percent: number, trans_text: string | undefined, trans_info: Record) { + setPercentage(percent); + if (trans_text === undefined) { + setDownloadInfo(null); + } else { + setDownloadInfo(t(trans_text, trans_info)); + } + } + + function startDownload(name: string) { + setInProgress(name); + setPercentage(0); + } + + function finishDownload(name: string) { + setPluginsCompleted((list) => [...list, name]); + } + + useEffect(() => { + DeckyBackend.addEventListener('loader/plugin_download_info', updateDownloadState); + DeckyBackend.addEventListener('loader/plugin_download_start', startDownload); + DeckyBackend.addEventListener('loader/plugin_download_finish', finishDownload); + + return () => { + DeckyBackend.removeEventListener('loader/plugin_download_info', updateDownloadState); + DeckyBackend.removeEventListener('loader/plugin_download_start', startDownload); + DeckyBackend.removeEventListener('loader/plugin_download_finish', finishDownload); + }; + }, []); + // used as part of the title translation // if we know all operations are of a specific type, we can show so in the title to make decision easier const installTypeGrouped = useMemo((): TitleTranslationMapping => { @@ -66,7 +101,10 @@ const MultiplePluginsInstallModal: FC = ({ return (
  • -
    {description}
    + + {description}{' '} + {(pluginsCompleted.includes(name) && ) || (name === pluginInProgress && )} + {hash === 'False' && (
    {t('PluginInstallModal.no_hash')}
    )} @@ -74,6 +112,17 @@ const MultiplePluginsInstallModal: FC = ({ ); })} + {/* TODO: center the progress bar and make it 80% width */} + {loading && ( + + )} ); diff --git a/frontend/src/components/modals/PluginInstallModal.tsx b/frontend/src/components/modals/PluginInstallModal.tsx index 1d149b2a..8b3128a1 100644 --- a/frontend/src/components/modals/PluginInstallModal.tsx +++ b/frontend/src/components/modals/PluginInstallModal.tsx @@ -1,5 +1,5 @@ -import { ConfirmModal, Navigation, QuickAccessTab } from '@decky/ui'; -import { FC, useState } from 'react'; +import { ConfirmModal, Navigation, ProgressBarWithInfo, QuickAccessTab } from '@decky/ui'; +import { FC, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import TranslationHelper, { TranslationClass } from '../../utils/TranslationHelper'; @@ -24,8 +24,26 @@ const PluginInstallModal: FC = ({ closeModal, }) => { const [loading, setLoading] = useState(false); + const [percentage, setPercentage] = useState(0); + const [downloadInfo, setDownloadInfo] = useState(null); const { t } = useTranslation(); + function updateDownloadState(percent: number, trans_text: string | undefined, trans_info: Record) { + setPercentage(percent); + if (trans_text === undefined) { + setDownloadInfo(null); + } else { + setDownloadInfo(t(trans_text, trans_info)); + } + } + + useEffect(() => { + DeckyBackend.addEventListener('loader/plugin_download_info', updateDownloadState); + return () => { + DeckyBackend.removeEventListener('loader/plugin_download_info', updateDownloadState); + }; + }, []); + return ( = ({ install_type={installType} /> + {loading && ( + + )} {hash == 'False' && {t('PluginInstallModal.no_hash')}} ); -- cgit v1.2.3