From 6e6f8caca807979be4889a5c1292aa15309a6a3a Mon Sep 17 00:00:00 2001 From: Marco Rodolfi Date: Sat, 27 May 2023 13:55:26 +0200 Subject: Unified translation classes, fixed missing toaster translation and improved the error styling report. --- backend/locales/en-US.json | 2 +- backend/locales/it-IT.json | 2 +- .../src/components/modals/PluginInstallModal.tsx | 46 ++++++++--- .../src/components/modals/TPluginInstallModal.tsx | 95 ---------------------- frontend/src/plugin-loader.tsx | 95 ++++++++++++++-------- frontend/src/utils/TranslationHelper.tsx | 59 ++++++++++++++ 6 files changed, 159 insertions(+), 140 deletions(-) delete mode 100644 frontend/src/components/modals/TPluginInstallModal.tsx create mode 100644 frontend/src/utils/TranslationHelper.tsx diff --git a/backend/locales/en-US.json b/backend/locales/en-US.json index 9bcaed62..6301008d 100644 --- a/backend/locales/en-US.json +++ b/backend/locales/en-US.json @@ -56,7 +56,7 @@ "decky_title": "Decky", "decky_update_available": "Update to {{tag_name}} available!", "error": "Error", - "plugin_error_uninstall": "Please go to <0> in the Decky menu if you need to uninstall this plugin.", + "plugin_error_uninstall": "Loading {{name}} has caused an exception as shown above. This usually means that the plugin requires an update for the new version of SteamUI. Check if an update is present or evaluate his removal in <0> Settings <1> <2> Plugins.", "plugin_load_error": { "message": "Error loading plugin {{name}}", "toast": "Error loading {{name}}" diff --git a/backend/locales/it-IT.json b/backend/locales/it-IT.json index 3665bdfe..5092b051 100644 --- a/backend/locales/it-IT.json +++ b/backend/locales/it-IT.json @@ -56,7 +56,7 @@ "decky_title": "Decky", "decky_update_available": "Disponibile aggiornamento a {{tag_name}}!", "error": "Errore", - "plugin_error_uninstall": "Per rimuovere questo plugin vai su <0> nel menu di Decky.", + "plugin_error_uninstall": "Il plugin {{name}} ha causato un'eccezione che è descritta sopra. Questo tipicamente significa che il plugin deve essere aggiornato per funzionare sulla nuova versione di SteamUI. Controlla se è disponibile un'aggiornamento o valutane la rimozione andando in <0> Impostazioni <1> <2> Plugins.", "plugin_load_error": { "message": "Errore caricando il plugin {{name}}", "toast": "Errore caricando {{name}}" 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 = ({ onCancel={async () => { await onCancel(); }} - strTitle={} + strTitle={ +
+ +
+ } strOKButtonText={ loading ? ( - +
+ +
) : ( - +
+ +
) } > - +
+ +
{hash == 'False' && {t('PluginInstallModal.no_hash')}} ); 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 = ({ trans_part, trans_type, artifact, version }) => { - return ( - - {(t, {}) => { - switch (trans_part) { - case TranslatedPart.TITLE: - switch (trans_type) { - case InstallType.INSTALL: - return
{t('PluginInstallModal.install.title', { artifact: artifact })}
; - case InstallType.REINSTALL: - return
{t('PluginInstallModal.reinstall.title', { artifact: artifact })}
; - case InstallType.UPDATE: - return
{t('PluginInstallModal.update.title', { artifact: artifact })}
; - default: - return null; - } - case TranslatedPart.DESC: - switch (trans_type) { - case InstallType.INSTALL: - return ( -
- {t('PluginInstallModal.install.desc', { - artifact: artifact, - version: version, - })} -
- ); - case InstallType.REINSTALL: - return ( -
- {t('PluginInstallModal.reinstall.desc', { - artifact: artifact, - version: version, - })} -
- ); - case InstallType.UPDATE: - return ( -
- {t('PluginInstallModal.update.desc', { - artifact: artifact, - version: version, - })} -
- ); - default: - return null; - } - case TranslatedPart.BUTTON_IDLE: - switch (trans_type) { - case InstallType.INSTALL: - return
{t('PluginInstallModal.install.button_idle')}
; - case InstallType.REINSTALL: - return
{t('PluginInstallModal.reinstall.button_idle')}
; - case InstallType.UPDATE: - return
{t('PluginInstallModal.update.button_idle')}
; - default: - return null; - } - case TranslatedPart.BUTTON_PROC: - switch (trans_type) { - case InstallType.INSTALL: - return
{t('PluginInstallModal.install.button_processing')}
; - case InstallType.REINSTALL: - return
{t('PluginInstallModal.reinstall.button_processing')}
; - case InstallType.UPDATE: - return
{t('PluginInstallModal.update.button_processing')}
; - default: - return null; - } - } - }} -
- ); -}; - -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: , + body: ( + + ), 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: , + body: ( + + ), 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<{}> = () => ( - - {(t, {}) => { - return ( - <> - {t('PluginLoader.error')}:{' '} -
-                    {e instanceof Error ? e.stack : JSON.stringify(e)}
-                  
-
- ]} - /> -
- - ); - }} -
+ + +
+ {} +
+
+ +
+                {e instanceof Error ? e.stack : JSON.stringify(e)}
+              
+
+ +
+ , , ]} + /> +
+
+
); this.plugins.push({ name: name, @@ -283,8 +307,13 @@ class PluginLoader extends Logger { icon: , }); this.toaster.toast({ - //title: t('PluginLoader.plugin_load_error.toast', { name: name }), - title: 'Error loading ' + name, + title: ( + + ), body: '' + e, icon: , }); 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 = ({ + trans_class, + trans_text, + i18n_args = null, + install_type = 0, +}) => { + return ( + + {(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 ''; + } + }} + + ); +}; + +export default TranslationHelper; -- cgit v1.2.3