From 35e7c80835866575ea1d8f725f8c07183753e49b Mon Sep 17 00:00:00 2001 From: Marco Rodolfi Date: Tue, 2 May 2023 17:42:39 +0200 Subject: [Feature] Implement internazionalization for Decky Loader (#361) * First iteration for internationalization of the loader * First iteration for internationalization of the loader * Cleanup node mess * Cleanup node mess pt2 * Additional touches * Latest decky changed merged into i18n and updated translation. * Styling fixes * Initial backend hosting implementation * Added correct url path of the loopback server. * Added correct url path of the loopback server. * Some better namespaced text. * Added whitelist for locales path. * Refactor languages and fix hooks logic bugs. * Small typo in language translation structure. * Working backend, automatically swtich languages with steam and language fixes. * Fix to languages * Key fixes * Additional language fixes. * Additional json changes * Final text revision and added a vscode tasks to automatically extract text from code. * Typo in the middleware * Remove unused imports * Cleanup whitespaces. * Import changes * Revert "Import changes" This reverts commit 8e8231950fd7cc6cece87040e326d0a72ba79567. * Update index.d.ts * Clean up unused imports * Delete pnpm-lock.yaml * Update rollup.config.js * Update PluginInstallModal.tsx * Update index.tsx * Update plugin-loader.tsx * Update plugin-loader.tsx * Revert "Delete pnpm-lock.yaml" This reverts commit 3a39f36f2193cc976d36ffe07338239e363d5b04. * Additional strings reworks. * Fixes for issues coming from github merge. * Fixes for master * Styling fixes * Styling pt2 * Missed a few strings in master, * Styling fixes * Additional master merge fixes. * Final cleanup and adaptation to master. * Final empty language cleanup and few string added * Small changes to italian translation * Disabled translation on a few components inside plugin-loader for missing react hooks. * Fixed passing tag to translation. * Disable debug output for reducing console spam. * Return correct content type * Small italian language change * Added support for country code * Fixed missing translation for uninstall popup. * Fix class name shenanigans for toast notification * Update dependencies * Fixed github workflow to include the new locales folder * Update dependencies to latest version (unless it's React) and fixed the new small errors that cropped up * Missed a file name change * Updated dev dependencies to latest version * Missed a few dev dependencies * Revert "Update dependencies to latest version (unless it's React) and fixed the new small errors that cropped up" Messed up merge with a different main branch * Messed up deletion of rollup config. * Fix broken pnpm lock file * Missed a localized string during the merge * Fixed a parameter mistake in the uninstall text parameter * Fix pnpm random issues * Small italian language tweaks * Fix wrong parameter passed to the uninstall function call * Another fix on a wrong function parameter * Additional translation text on the store and branch selection channels * Changed the default type passed to map to being able to index the two arrays. * Reverted and reworked the last changes * Distinguish events in UI for installing vs reinstalling plugins * Additional fixes for reinstall prompt * Revert the use of intevalPlural since the parser doesn't seem to support that. * Missed a routing path in the backend * Small bugfixes * Small fixes * Correctly adding the parameter to the request headers. * Refactoring of the UI popup modal * Fix pnpm shenanigans * Final fixes for the install UI localization * Clean up unnedeed backend code * Small rework on text selection. * Cleaned up parser configuration * Removed extracttext dependency to pnpmsetup * Merged translation and cleaned up parser * Fixed JSON structure after manual merge. * Added translation to the file picker * Revert changes to PluginInstallModal * Reworked the text modal for the final time * Missed the proper linted text * Missed the backend change * Final branch cleanup * Fixed small translation bleeding Caused from the manual merge of _old.json files. * fix extra space in browser.py * fix extra newline in plugin-loader.tsx * Cleanup i18next-parser.config.mjs * Update plugin-loader.tsx * Cleanup language files * Better labeling of text * Fixed language typos in BranchSelect * Fixed language typos in StoreSelect * Cleanup plugin-loader.tsx from unused imports * Removed the path bypass since I'm using authentication from the frontend. * Reimplemented this component as a functional component. * Updated dependencies and lockfile * Removed static route from main.py Already handled in loader.py * Small italian coherency fixes * Fix small typography fixes on plugin name uninstall * Fixed italian typo on removal popup * Reenabled manual escaping value in i18next * Set to fallback to the default language if the string in the JSON file is empty. * Fixed pnpm wankery * Added a missed italian text translation string --------- Co-authored-by: AAGaming --- .../settings/pages/general/BranchSelect.tsx | 11 +++++++++-- .../settings/pages/general/RemoteDebugging.tsx | 10 ++++------ .../settings/pages/general/StoreSelect.tsx | 15 +++++++++++---- .../components/settings/pages/general/Updater.tsx | 22 +++++++++++++--------- .../components/settings/pages/general/index.tsx | 14 ++++++++------ 5 files changed, 45 insertions(+), 27 deletions(-) (limited to 'frontend/src/components/settings/pages/general') diff --git a/frontend/src/components/settings/pages/general/BranchSelect.tsx b/frontend/src/components/settings/pages/general/BranchSelect.tsx index 5387b655..d966ff62 100644 --- a/frontend/src/components/settings/pages/general/BranchSelect.tsx +++ b/frontend/src/components/settings/pages/general/BranchSelect.tsx @@ -1,5 +1,6 @@ import { Dropdown, Field } from 'decky-frontend-lib'; import { FunctionComponent } from 'react'; +import { useTranslation } from 'react-i18next'; import Logger from '../../../../logger'; import { callUpdaterMethod } from '../../../../updater'; @@ -14,17 +15,23 @@ enum UpdateBranch { } const BranchSelect: FunctionComponent<{}> = () => { + const { t } = useTranslation(); + const tBranches = [ + t('BranchSelect.update_channel.stable'), + t('BranchSelect.update_channel.prerelease'), + t('BranchSelect.update_channel.testing'), + ]; const [selectedBranch, setSelectedBranch] = useSetting('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 - + typeof branch == 'string') .map((branch) => ({ - label: branch, + label: tBranches[UpdateBranch[branch]], data: UpdateBranch[branch], }))} selectedOption={selectedBranch} diff --git a/frontend/src/components/settings/pages/general/RemoteDebugging.tsx b/frontend/src/components/settings/pages/general/RemoteDebugging.tsx index db604c69..60d57d91 100644 --- a/frontend/src/components/settings/pages/general/RemoteDebugging.tsx +++ b/frontend/src/components/settings/pages/general/RemoteDebugging.tsx @@ -1,19 +1,17 @@ import { Field, Toggle } from 'decky-frontend-lib'; +import { useTranslation } from 'react-i18next'; import { FaChrome } from 'react-icons/fa'; import { useSetting } from '../../../../utils/hooks/useSetting'; export default function RemoteDebuggingSettings() { const [allowRemoteDebugging, setAllowRemoteDebugging] = useSetting('cef_forward', false); + const { t } = useTranslation(); return ( - Allows unauthenticated access to the CEF debugger to anyone in your network. - - } + label={t('RemoteDebugging.remote_cef.label')} + description={{t('RemoteDebugging.remote_cef.desc')}} icon={} > = () => { const [selectedStore, setSelectedStore] = useSetting('store', Store.Default); const [selectedStoreURL, setSelectedStoreURL] = useSetting('store-url', null); + const { t } = useTranslation(); + const tStores = [ + t('StoreSelect.store_channel.default'), + t('StoreSelect.store_channel.testing'), + t('StoreSelect.store_channel.custom'), + ]; // Returns numerical values from 0 to 2 (with current branch setup as of 8/28/22) // 0 being Default, 1 being Testing and 2 being Custom return ( <> - + typeof store == 'string') .map((store) => ({ - label: store, + label: tStores[Store[store]], data: Store[store], }))} selectedOption={selectedStore} @@ -33,11 +40,11 @@ const StoreSelect: FunctionComponent<{}> = () => { {selectedStore == Store.Custom && ( setSelectedStoreURL(e?.target.value || null)} /> diff --git a/frontend/src/components/settings/pages/general/Updater.tsx b/frontend/src/components/settings/pages/general/Updater.tsx index 1ee31e6c..927a99b0 100644 --- a/frontend/src/components/settings/pages/general/Updater.tsx +++ b/frontend/src/components/settings/pages/general/Updater.tsx @@ -12,6 +12,7 @@ import { import { useCallback } from 'react'; import { Suspense, lazy } from 'react'; import { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { FaExclamation } from 'react-icons/fa'; import { VerInfo, callUpdaterMethod, finishUpdate } from '../../../../updater'; @@ -23,6 +24,7 @@ const MarkdownRenderer = lazy(() => import('../../../Markdown')); function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | null; closeModal?: () => {} }) { const SP = findSP(); + const { t } = useTranslation(); return ( @@ -45,7 +47,7 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n {versionInfo.all[id].body} ) : ( - 'no patch notes for this version' + t('Updater.no_patch_notes_desc') )} @@ -58,7 +60,7 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n initialColumn={0} autoFocus={true} fnGetColumnWidth={() => SP.innerWidth} - name="Decky Updates" + name={t('Updater.decky_updates') as string} /> @@ -72,6 +74,8 @@ export default function UpdaterSettings() { const [updateProgress, setUpdateProgress] = useState(-1); const [reloading, setReloading] = useState(false); + const { t } = useTranslation(); + useEffect(() => { window.DeckyUpdater = { updateProgress: (i) => { @@ -93,14 +97,14 @@ export default function UpdaterSettings() { return ( <> Up to date: running {versionInfo?.current} + {t('Updater.updates.lat_version', { ver: versionInfo?.current })} ) } icon={ @@ -129,10 +133,10 @@ export default function UpdaterSettings() { } > {checkingForUpdates - ? 'Checking' + ? t('Updater.updates.checking') : !versionInfo?.remote || versionInfo?.remote?.tag_name == versionInfo?.current - ? 'Check For Updates' - : 'Install Update'} + ? t('Updater.updates.check_button') + : t('Updater.updates.install_button')} ) : ( )} diff --git a/frontend/src/components/settings/pages/general/index.tsx b/frontend/src/components/settings/pages/general/index.tsx index 97fd3e42..96ae6782 100644 --- a/frontend/src/components/settings/pages/general/index.tsx +++ b/frontend/src/components/settings/pages/general/index.tsx @@ -1,4 +1,5 @@ import { DialogBody, DialogControlsSection, DialogControlsSectionHeader, Field, Toggle } from 'decky-frontend-lib'; +import { useTranslation } from 'react-i18next'; import { useDeckyState } from '../../../DeckyState'; import BranchSelect from './BranchSelect'; @@ -13,21 +14,22 @@ export default function GeneralSettings({ setIsDeveloper: (val: boolean) => void; }) { const { versionInfo } = useDeckyState(); + const { t } = useTranslation(); return ( - Updates + {t('SettingsGeneralIndex.updates.header')} - Beta Participation + {t('SettingsGeneralIndex.beta.header')} - Other - + {t('SettingsGeneralIndex.other.header')} + { @@ -37,8 +39,8 @@ export default function GeneralSettings({ - About - + {t('SettingsGeneralIndex.about.header')} +
{versionInfo?.current}
-- cgit v1.2.3