diff options
| author | Marco Rodolfi <marco.rodolfi@tuta.io> | 2023-05-27 13:55:26 +0200 |
|---|---|---|
| committer | Marco Rodolfi <marco.rodolfi@tuta.io> | 2023-05-27 13:55:26 +0200 |
| commit | 6e6f8caca807979be4889a5c1292aa15309a6a3a (patch) | |
| tree | db240b8b4851045308b26ebf7d7382625ecf2ff6 /frontend | |
| parent | 3a83062438e2e86dbaaf459f8af7a2fd5a8df215 (diff) | |
| download | decky-loader-6e6f8caca807979be4889a5c1292aa15309a6a3a.tar.gz decky-loader-6e6f8caca807979be4889a5c1292aa15309a6a3a.zip | |
Unified translation classes, fixed missing toaster translation and improved the error styling report.
Diffstat (limited to 'frontend')
| -rw-r--r-- | frontend/src/components/modals/PluginInstallModal.tsx | 46 | ||||
| -rw-r--r-- | frontend/src/components/modals/TPluginInstallModal.tsx | 95 | ||||
| -rw-r--r-- | frontend/src/plugin-loader.tsx | 95 | ||||
| -rw-r--r-- | frontend/src/utils/TranslationHelper.tsx | 59 |
4 files changed, 157 insertions, 138 deletions
diff --git a/frontend/src/components/modals/PluginInstallModal.tsx b/frontend/src/components/modals/PluginInstallModal.tsx index 0e8e3d47..b37dbc65 100644 --- a/frontend/src/components/modals/PluginInstallModal.tsx +++ b/frontend/src/components/modals/PluginInstallModal.tsx @@ -2,7 +2,7 @@ import { ConfirmModal, Navigation, QuickAccessTab } from 'decky-frontend-lib'; import { FC, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import TPluginInstallModal, { TranslatedPart } from './TPluginInstallModal'; +import TranslationHelper, { TranslationClass } from '../../utils/TranslationHelper'; interface PluginInstallModalProps { artifact: string; @@ -39,21 +39,47 @@ const PluginInstallModal: FC<PluginInstallModalProps> = ({ onCancel={async () => { await onCancel(); }} - strTitle={<TPluginInstallModal trans_part={TranslatedPart.TITLE} trans_type={installType} artifact={artifact} />} + strTitle={ + <div> + <TranslationHelper + trans_class={TranslationClass.PLUGIN_INSTALL_MODAL} + trans_text="title" + i18n_args={{ artifact: artifact }} + install_type={installType} + /> + </div> + } strOKButtonText={ loading ? ( - <TPluginInstallModal trans_part={TranslatedPart.BUTTON_PROC} trans_type={installType} /> + <div> + <TranslationHelper + trans_class={TranslationClass.PLUGIN_INSTALL_MODAL} + trans_text="button_processing" + install_type={installType} + /> + </div> ) : ( - <TPluginInstallModal trans_part={TranslatedPart.BUTTON_IDLE} trans_type={installType} /> + <div> + <TranslationHelper + trans_class={TranslationClass.PLUGIN_INSTALL_MODAL} + trans_text="button_idle" + install_type={installType} + /> + </div> ) } > - <TPluginInstallModal - trans_part={TranslatedPart.DESC} - trans_type={installType} - artifact={artifact} - version={version ? version : ''} - /> + <div> + <TranslationHelper + trans_class={TranslationClass.PLUGIN_INSTALL_MODAL} + trans_text="desc" + i18n_args={{ + artifact: artifact, + version: version, + }} + install_type={installType} + /> + </div> {hash == 'False' && <span style={{ color: 'red' }}>{t('PluginInstallModal.no_hash')}</span>} </ConfirmModal> ); diff --git a/frontend/src/components/modals/TPluginInstallModal.tsx b/frontend/src/components/modals/TPluginInstallModal.tsx deleted file mode 100644 index 3866560e..00000000 --- a/frontend/src/components/modals/TPluginInstallModal.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { FC } from 'react'; -import { Translation } from 'react-i18next'; - -import { InstallType } from '../../plugin'; - -export enum TranslatedPart { - TITLE, - DESC, - BUTTON_IDLE, - BUTTON_PROC, -} -interface TPluginInstallModalProps { - trans_part: TranslatedPart; - trans_type: number; - artifact?: string; - version?: string; -} - -const TPluginInstallModal: FC<TPluginInstallModalProps> = ({ trans_part, trans_type, artifact, version }) => { - return ( - <Translation> - {(t, {}) => { - switch (trans_part) { - case TranslatedPart.TITLE: - switch (trans_type) { - case InstallType.INSTALL: - return <div>{t('PluginInstallModal.install.title', { artifact: artifact })}</div>; - case InstallType.REINSTALL: - return <div>{t('PluginInstallModal.reinstall.title', { artifact: artifact })}</div>; - case InstallType.UPDATE: - return <div>{t('PluginInstallModal.update.title', { artifact: artifact })}</div>; - default: - return null; - } - case TranslatedPart.DESC: - switch (trans_type) { - case InstallType.INSTALL: - return ( - <div> - {t('PluginInstallModal.install.desc', { - artifact: artifact, - version: version, - })} - </div> - ); - case InstallType.REINSTALL: - return ( - <div> - {t('PluginInstallModal.reinstall.desc', { - artifact: artifact, - version: version, - })} - </div> - ); - case InstallType.UPDATE: - return ( - <div> - {t('PluginInstallModal.update.desc', { - artifact: artifact, - version: version, - })} - </div> - ); - default: - return null; - } - case TranslatedPart.BUTTON_IDLE: - switch (trans_type) { - case InstallType.INSTALL: - return <div>{t('PluginInstallModal.install.button_idle')}</div>; - case InstallType.REINSTALL: - return <div>{t('PluginInstallModal.reinstall.button_idle')}</div>; - case InstallType.UPDATE: - return <div>{t('PluginInstallModal.update.button_idle')}</div>; - default: - return null; - } - case TranslatedPart.BUTTON_PROC: - switch (trans_type) { - case InstallType.INSTALL: - return <div>{t('PluginInstallModal.install.button_processing')}</div>; - case InstallType.REINSTALL: - return <div>{t('PluginInstallModal.reinstall.button_processing')}</div>; - case InstallType.UPDATE: - return <div>{t('PluginInstallModal.update.button_processing')}</div>; - default: - return null; - } - } - }} - </Translation> - ); -}; - -export default TPluginInstallModal; diff --git a/frontend/src/plugin-loader.tsx b/frontend/src/plugin-loader.tsx index 71c8d0df..7a226920 100644 --- a/frontend/src/plugin-loader.tsx +++ b/frontend/src/plugin-loader.tsx @@ -1,8 +1,19 @@ -import { ConfirmModal, ModalRoot, Patch, QuickAccessTab, Router, showModal, sleep } from 'decky-frontend-lib'; -import { FC, lazy } from 'react'; -import { Trans, Translation } from 'react-i18next'; -import { IconContext } from 'react-icons'; -import { FaCog, FaExclamationCircle, FaPlug } from 'react-icons/fa'; +import { + ConfirmModal, + ModalRoot, + PanelSection, + PanelSectionRow, + Patch, + QuickAccessTab, + Router, + showModal, + sleep, + staticClasses, +} from 'decky-frontend-lib'; +import { CSSProperties, FC, lazy } from 'react'; +import { Trans } from 'react-i18next'; +import { BsGearFill } from 'react-icons/bs'; +import { FaArrowRight, FaExclamationCircle, FaPlug } from 'react-icons/fa'; import { DeckyState, DeckyStateContextProvider, useDeckyState } from './components/DeckyState'; import LegacyPlugin from './components/LegacyPlugin'; @@ -21,6 +32,7 @@ import OldTabsHook from './tabs-hook.old'; import Toaster from './toaster'; import { VerInfo, callUpdaterMethod } from './updater'; import { getSetting } from './utils/settings'; +import TranslationHelper, { TranslationClass } from './utils/TranslationHelper'; const StorePage = lazy(() => import('./components/store/Store')); const SettingsPage = lazy(() => import('./components/settings')); @@ -100,10 +112,14 @@ class PluginLoader extends Logger { const versionInfo = await this.updateVersion(); if (versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current) { this.toaster.toast({ - //title: t('PluginLoader.decky_title'), - title: 'Decky', - //body: t('PluginLoader.decky_update_available', { tag_name: versionInfo?.remote?.tag_name }), - body: `Update to ${versionInfo?.remote?.tag_name} available!`, + title: <TranslationHelper trans_class={TranslationClass.PLUGIN_LOADER} trans_text="decky_title" />, + body: ( + <TranslationHelper + trans_class={TranslationClass.PLUGIN_LOADER} + trans_text="decky_update_available" + i18n_args={{ tag_name: versionInfo?.remote?.tag_name }} + /> + ), onClick: () => Router.Navigate('/decky/settings'), }); this.deckyState.setHasLoaderUpdate(true); @@ -122,10 +138,14 @@ class PluginLoader extends Logger { const updates = await this.checkPluginUpdates(); if (updates?.size > 0) { this.toaster.toast({ - //title: t('PluginLoader.decky_title'), - title: 'Decky', - //body: t('PluginLoader.plugin_update', { count: updates.size }), - body: `Updates available for ${updates.size} plugin${updates.size > 1 ? 's' : ''}!`, + title: <TranslationHelper trans_class={TranslationClass.PLUGIN_LOADER} trans_text="decky_title" />, + body: ( + <TranslationHelper + trans_class={TranslationClass.PLUGIN_LOADER} + trans_text="plugin_update" + i18n_args={{ count: updates.size }} + /> + ), onClick: () => Router.Navigate('/decky/settings/plugins'), }); } @@ -256,25 +276,29 @@ class PluginLoader extends Logger { }); } catch (e) { this.error('Error loading plugin ' + name, e); + const style: CSSProperties = { verticalAlign: 'middle' }; const TheError: FC<{}> = () => ( - <Translation> - {(t, {}) => { - return ( - <> - {t('PluginLoader.error')}:{' '} - <pre> - <code>{e instanceof Error ? e.stack : JSON.stringify(e)}</code> - </pre> - <div> - <Trans - i18nKey="PluginLoader.plugin_error_uninstall" - components={[<FaCog style={{ verticalAlign: 'middle' }} />]} - /> - </div> - </> - ); - }} - </Translation> + <PanelSection> + <PanelSectionRow> + <div className={staticClasses.FriendsTitle} style={{ display: 'flex', justifyContent: 'center' }}> + {<TranslationHelper trans_class={TranslationClass.PLUGIN_LOADER} trans_text="error" />} + </div> + </PanelSectionRow> + <PanelSectionRow> + <pre style={{ overflowX: 'scroll' }}> + <code>{e instanceof Error ? e.stack : JSON.stringify(e)}</code> + </pre> + </PanelSectionRow> + <PanelSectionRow> + <div className={staticClasses.Text}> + <Trans + i18nKey="PluginLoader.plugin_error_uninstall" + values={{ name: name }} + components={[<BsGearFill style={style} />, <FaArrowRight style={style} />, <FaPlug style={style} />]} + /> + </div> + </PanelSectionRow> + </PanelSection> ); this.plugins.push({ name: name, @@ -283,8 +307,13 @@ class PluginLoader extends Logger { icon: <FaExclamationCircle />, }); this.toaster.toast({ - //title: t('PluginLoader.plugin_load_error.toast', { name: name }), - title: 'Error loading ' + name, + title: ( + <TranslationHelper + trans_class={TranslationClass.PLUGIN_LOADER} + trans_text="plugin_load_error.toast" + i18n_args={{ name: name }} + /> + ), body: '' + e, icon: <FaExclamationCircle />, }); diff --git a/frontend/src/utils/TranslationHelper.tsx b/frontend/src/utils/TranslationHelper.tsx new file mode 100644 index 00000000..457a3159 --- /dev/null +++ b/frontend/src/utils/TranslationHelper.tsx @@ -0,0 +1,59 @@ +import { FC } from 'react'; +import { Translation } from 'react-i18next'; + +import Logger from '../logger'; +import { InstallType } from '../plugin'; + +export enum TranslationClass { + PLUGIN_LOADER = 'PluginLoader', + PLUGIN_INSTALL_MODAL = 'PluginInstallModal', +} + +interface TranslationHelperProps { + trans_class: TranslationClass; + trans_text: string; + i18n_args?: {}; + install_type?: number; +} + +const logger = new Logger('TranslationHelper'); + +const TranslationHelper: FC<TranslationHelperProps> = ({ + trans_class, + trans_text, + i18n_args = null, + install_type = 0, +}) => { + return ( + <Translation> + {(t, {}) => { + switch (trans_class) { + case TranslationClass.PLUGIN_LOADER: + return i18n_args + ? t(TranslationClass.PLUGIN_LOADER + '.' + trans_text, i18n_args) + : t(TranslationClass.PLUGIN_LOADER + '.' + trans_text); + case TranslationClass.PLUGIN_INSTALL_MODAL: + switch (install_type) { + case InstallType.INSTALL: + return i18n_args + ? t(TranslationClass.PLUGIN_INSTALL_MODAL + '.install.' + trans_text, i18n_args) + : t(TranslationClass.PLUGIN_INSTALL_MODAL + '.install.' + trans_text); + case InstallType.REINSTALL: + return i18n_args + ? t(TranslationClass.PLUGIN_INSTALL_MODAL + '.reinstall.' + trans_text, i18n_args) + : t(TranslationClass.PLUGIN_INSTALL_MODAL + '.reinstall.' + trans_text); + case InstallType.UPDATE: + return i18n_args + ? t(TranslationClass.PLUGIN_INSTALL_MODAL + '.update.' + trans_text, i18n_args) + : t(TranslationClass.PLUGIN_INSTALL_MODAL + '.update.' + trans_text); + } + default: + logger.error('We should never fall in the default case!'); + return ''; + } + }} + </Translation> + ); +}; + +export default TranslationHelper; |
