From ce3850512e158f86d6fb94cfb648340f5572f70a Mon Sep 17 00:00:00 2001 From: "Re*Index. (ot_inc)" <32851879+reindex-ot@users.noreply.github.com> Date: Thu, 16 Jul 2026 17:26:17 +0900 Subject: [PATCH] Add Japanese Translation --- .../ExtensionBar/ExtensionContextMenu.tsx | 9 +- .../ManagerExtensionItem.tsx | 5 +- .../ToolbarManagerContextMenu.tsx | 7 +- frontend/extensionInitialization.tsx | 11 +- .../extensionInstallationFailedDialog.tsx | 37 ++- .../ExtensionDetailInfo.tsx | 27 ++- .../ExtensionManagerComponent.tsx | 7 +- .../ExtensionManagerPopup.tsx | 5 +- .../ExtensionManagerRoot.tsx | 5 +- .../Settings/DynamicListManager.tsx | 19 +- .../Settings/ExtendiumSettings.tsx | 33 ++- .../Settings/settingsStore.ts | 4 +- frontend/i18n.ts | 216 ++++++++++++++++++ frontend/legacyExtensionDialog.tsx | 31 +-- 14 files changed, 342 insertions(+), 74 deletions(-) create mode 100644 frontend/i18n.ts diff --git a/frontend/components/ExtensionBar/ExtensionContextMenu.tsx b/frontend/components/ExtensionBar/ExtensionContextMenu.tsx index 49dc996..7c37cef 100644 --- a/frontend/components/ExtensionBar/ExtensionContextMenu.tsx +++ b/frontend/components/ExtensionBar/ExtensionContextMenu.tsx @@ -6,6 +6,7 @@ import React, { JSX } from 'react'; import { createOptionsWindow } from '../../windowManagement'; import { Separator } from '../Separator'; import { useExtensionsBarStore } from '../stores/extensionsBarStore'; +import { t } from '../../i18n'; function ExtensionContextMenu({ extension }: { readonly extension: Extension; }): JSX.Element { const { setExtensionsOrder } = useExtensionsBarStore(); @@ -29,11 +30,11 @@ function ExtensionContextMenu({ extension }: { readonly extension: Extension; }) {extension.name} - {extension.options.hasOptions() && { createOptionsWindow(extension); }}>Options} - { uninstallExtension(extension.id); }}>Remove extension - Unpin + {extension.options.hasOptions() && { createOptionsWindow(extension); }}>{t('options')}} + { uninstallExtension(extension.id); }}>{t('removeExtension')} + {t('unpin')} - { openExtensionManagerPopup(`info/${extension.id}`); }}>Manage + { openExtensionManagerPopup(`info/${extension.id}`); }}>{t('manage')} ); diff --git a/frontend/components/ToolbarExtensionManager/ManagerExtensionItem.tsx b/frontend/components/ToolbarExtensionManager/ManagerExtensionItem.tsx index 29ed1bf..a5337d2 100644 --- a/frontend/components/ToolbarExtensionManager/ManagerExtensionItem.tsx +++ b/frontend/components/ToolbarExtensionManager/ManagerExtensionItem.tsx @@ -4,6 +4,7 @@ import { openExtensionManagerPopup } from 'extensions-manager/ExtensionManagerPo import React from 'react'; import { FaCog } from 'react-icons/fa'; import { LuPin, LuPinOff } from 'react-icons/lu'; +import { t } from '../../i18n'; export function ManagerExtensionItem({ extension, pinned, pinExtension, unpinExtension }: { readonly extension: Extension; readonly pinned: boolean; pinExtension(extensionId: string): void; unpinExtension(extensionId: string): void; }): React.JSX.Element { @@ -22,10 +23,10 @@ export function ManagerExtensionItem({ extension, pinned, pinExtension, unpinExt icon={{extension.name}} padding="standard" > - + {pinned ? : } - { openExtensionManagerPopup(`info/${extension.id}`); }} style={{ padding: '0 8px' }} title="Manage"> + { openExtensionManagerPopup(`info/${extension.id}`); }} style={{ padding: '0 8px' }} title={t('manage')}> diff --git a/frontend/components/ToolbarExtensionManager/ToolbarManagerContextMenu.tsx b/frontend/components/ToolbarExtensionManager/ToolbarManagerContextMenu.tsx index 7796e23..859b20b 100644 --- a/frontend/components/ToolbarExtensionManager/ToolbarManagerContextMenu.tsx +++ b/frontend/components/ToolbarExtensionManager/ToolbarManagerContextMenu.tsx @@ -5,6 +5,7 @@ import React, { useMemo } from 'react'; import { FaCog } from 'react-icons/fa'; import { useExtensionsStore } from 'stores/extensionsStore'; import { useExtensionsBarStore } from '../stores/extensionsBarStore'; +import { t } from '../../i18n'; import { ManagerExtensionItem } from './ManagerExtensionItem'; export function ToolbarManagerContextMenu(): React.JSX.Element { @@ -35,8 +36,8 @@ export function ToolbarManagerContextMenu(): React.JSX.Element { <>
- - Extensions + + {t('extensions')} {enabledExtensions .sort((a, b) => a.name.localeCompare(b.name)) .map(extension => ( @@ -49,7 +50,7 @@ export function ToolbarManagerContextMenu(): React.JSX.Element { /> ))}
{ openExtensionManagerPopup(); }}> - } label="Manage extensions" /> + } label={t('manageExtensions')} />
diff --git a/frontend/extensionInitialization.tsx b/frontend/extensionInitialization.tsx index 392a800..53a84e2 100644 --- a/frontend/extensionInitialization.tsx +++ b/frontend/extensionInitialization.tsx @@ -6,6 +6,7 @@ import { BROKEN_EXTENSION_IDS, INTERNAL_HOME_PAGE_URL } from 'constant'; import React from 'react'; import { mainWindow } from 'shared'; import { useExtensionsStore } from 'stores/extensionsStore'; +import { t } from './i18n'; export async function initializeExtension(): Promise { const { setExtension, removeExtension } = useExtensionsStore.getState(); @@ -58,23 +59,23 @@ export async function initializeExtension(): Promise { function showBrokenExtensionWarning(extensionId: string, extensionName: string): void { const dialog = showModal(

- We've automatically detected an extension ({extensionName}:{extensionId}) that is known to cause Steam to become unresponsive, crash or become fully bricked. + {t('unsupportedDesc1').replace('{extensionName}', extensionName).replace('{extensionId}', extensionId)}

- You WILL NEED to remove this extension to prevent potential issues with your Steam client. + {t('unsupportedDesc2')}
- You can find more information about compatible extensions on the Extendium github page. + {t('unsupportedDesc3')}
)} - strOKButtonText="Uninstall extension" + strOKButtonText={t('uninstallBtn')} onOK={() => { uninstallExtension(extensionId).then(() => { dialog.Close(); diff --git a/frontend/extensionInstallationFailedDialog.tsx b/frontend/extensionInstallationFailedDialog.tsx index 3ab0f10..055e906 100644 --- a/frontend/extensionInstallationFailedDialog.tsx +++ b/frontend/extensionInstallationFailedDialog.tsx @@ -2,6 +2,7 @@ import { ConfirmModal, showModal } from '@steambrew/client'; import { IgnoreInternalExtensionRequirement, InstallInternalExtension } from 'callables'; import React from 'react'; import { mainWindow } from 'shared'; +import { t } from './i18n'; function openInExternalBrowser(event: React.MouseEvent): void { event.preventDefault(); @@ -10,30 +11,46 @@ function openInExternalBrowser(event: React.MouseEvent): void } export function showExtensionInstallationFailedDialog(): void { + const readmeParts = t('failedDesc3').split('{readmeLink}'); + const githubParts = t('failedDesc4').split('{githubLink}'); + const firstPart = githubParts[0]; + const rest = githubParts[1] ?? ''; + const discordParts = rest.split('{discordLink}'); + const dialog = showModal(

- Extendium needs a helper extension to work fully, but the automatic installation didn't complete successfully. + {t('failedDesc1')}

- Without the helper extension, some extensions like Augmented Steam won't work properly. + {t('failedDesc2')}

- You can try the automatic installation again, or manually install the helper extension - by following the step-by-step instructions in the readme here. + {readmeParts[0]} + + {t('here')} + + {readmeParts[1]}

- If the problem persists, please check the plugin logs for more details and report this issue - on the Extendium GitHub repository or the discord channel with your log. + {firstPart} + + {t('githubRepo')} + + {discordParts[0]} + + {t('discordChannel')} + + {discordParts[1]}

)} - strOKButtonText="Try installation again" - strMiddleButtonText="Ignore and don't show again" - strCancelButtonText="Understood, I will manually install it" + strOKButtonText={t('tryAgain')} + strMiddleButtonText={t('ignoreBtn')} + strCancelButtonText={t('understoodBtn')} bDisableBackgroundDismiss bHideCloseIcon onOK={async () => { diff --git a/frontend/extensions-manager/ExtensionDetailInfo.tsx b/frontend/extensions-manager/ExtensionDetailInfo.tsx index 12a0507..fee73c1 100644 --- a/frontend/extensions-manager/ExtensionDetailInfo.tsx +++ b/frontend/extensions-manager/ExtensionDetailInfo.tsx @@ -8,6 +8,7 @@ import { FaExclamationCircle } from 'react-icons/fa'; import { MdArrowBack, MdArrowForward, MdOpenInNew } from 'react-icons/md'; import { mainWindow } from 'shared'; import { createOptionsWindow } from 'windowManagement'; +import { t } from '../i18n'; export function ExtensionDetailInfo({ extension }: { readonly extension: Extension | undefined; }): React.ReactNode { const [views, setViews] = React.useState([]); @@ -20,7 +21,7 @@ export function ExtensionDetailInfo({ extension }: { readonly extension: Extensi - Error in extension + {t('errorInExtension')} ); @@ -53,6 +54,10 @@ export function ExtensionDetailInfo({ extension }: { readonly extension: Extensi } }, []); + const errorInstructions = t('errorInstructions'); + const devmodeText = t('enableDevModeText'); + const parts = errorInstructions.split('{devmodeLink}'); + return (
@@ -64,23 +69,23 @@ export function ExtensionDetailInfo({ extension }: { readonly extension: Extensi
-
Description
+
{t('description')}
{extension.description}
-
Version
+
{t('version')}
{extension.version}
-
Id
+
{t('id')}
{extension.id}
{views.length > 0 && (
-
Inspect views
+
{t('inspectViews')}
    {views.map(view => ( @@ -105,10 +110,14 @@ export function ExtensionDetailInfo({ extension }: { readonly extension: Extensi
    - Errors + {t('errors')}
    - For detailed error information, { initializeViews(); }}>enable dev mode and open the console of the specified view in the list above + + {parts[0]} + { initializeViews(); }}>{devmodeText} + {parts[1]} +
      {extension.logger.errors.map(error => (
    • {error}
    • @@ -120,13 +129,13 @@ export function ExtensionDetailInfo({ extension }: { readonly extension: Extensi {extension.options.hasOptions() && (
      { createOptionsWindow(extension); }}> - Extension options + {t('extensionOptions')}
      )}
      { fullyUninstallExtension(); }}> - Remove extension + {t('removeExtension')}
    diff --git a/frontend/extensions-manager/ExtensionManagerComponent.tsx b/frontend/extensions-manager/ExtensionManagerComponent.tsx index d4a1651..7869105 100644 --- a/frontend/extensions-manager/ExtensionManagerComponent.tsx +++ b/frontend/extensions-manager/ExtensionManagerComponent.tsx @@ -7,6 +7,7 @@ import React from 'react'; import { useExtensionsStore } from 'stores/extensionsStore'; import { getExtensionCompatibility, type CompatibilityStatus } from '../extensionCompatibility'; import { useSettingsStore } from '../extensions-manager/Settings/settingsStore'; +import { t } from '../i18n'; export function ExtensionManagerComponent({ extension }: { readonly extension: Extension; }): React.ReactNode { const { setManagerPopup } = usePopupsStore(); @@ -59,7 +60,7 @@ export function ExtensionManagerComponent({ extension }: { readonly extension: E { SteamClient.System.OpenInSystemBrowser(COMPATIBILITY_LIST_URL); }} > {compatibility} @@ -72,8 +73,8 @@ export function ExtensionManagerComponent({ extension }: { readonly extension: E
- { setManagerPopup({ route: `info/${extension.id}` }); }}>Details - { fullyUninstallExtension(); }}>Remove + { setManagerPopup({ route: `info/${extension.id}` }); }}>{t('details')} + { fullyUninstallExtension(); }}>{t('remove')}
diff --git a/frontend/extensions-manager/ExtensionManagerPopup.tsx b/frontend/extensions-manager/ExtensionManagerPopup.tsx index 24f8ad7..cf7b584 100644 --- a/frontend/extensions-manager/ExtensionManagerPopup.tsx +++ b/frontend/extensions-manager/ExtensionManagerPopup.tsx @@ -9,6 +9,7 @@ import { useExtensionsStore } from 'stores/extensionsStore'; import { ExtensionDetailInfo } from './ExtensionDetailInfo'; import { ExtensionManagerRoot } from './ExtensionManagerRoot'; import { ExtendiumSettings } from './Settings/ExtendiumSettings'; +import { t } from '../i18n'; function ExtensionManagerPopup(): React.ReactNode { const { managerPopup, setManagerPopup } = usePopupsStore(); @@ -27,12 +28,12 @@ function ExtensionManagerPopup(): React.ReactNode { } else if (managerPopup.route.startsWith('settings')) { content = ; } else { - content =

Error you somehow got to an undefined route please report this with this route "{managerPopup.route}"

; + content =

{t('undefinedRoute').replace('{route}', managerPopup.route ?? '')}

; } return ( { setManagerPopup({ open: false }); }} popupWidth={1280} popupHeight={mainWindow.innerHeight * 0.65} diff --git a/frontend/extensions-manager/ExtensionManagerRoot.tsx b/frontend/extensions-manager/ExtensionManagerRoot.tsx index 059fffe..bf2b47a 100644 --- a/frontend/extensions-manager/ExtensionManagerRoot.tsx +++ b/frontend/extensions-manager/ExtensionManagerRoot.tsx @@ -6,6 +6,7 @@ import React from 'react'; import { FaCog, FaStore } from 'react-icons/fa'; import { IoExtensionPuzzle } from 'react-icons/io5'; import { useExtensionsStore } from 'stores/extensionsStore'; +import { t } from '../i18n'; import { ExtensionManagerComponent } from './ExtensionManagerComponent'; export function ExtensionManagerRoot(): React.ReactNode { @@ -20,14 +21,14 @@ export function ExtensionManagerRoot(): React.ReactNode { className={`span-icon ${settingsClasses.SettingsDialogButton}`} > - Install extension + {t('installExtension')} { OpenTargetPage('chrome://extensions'); }} className={`span-icon ${settingsClasses.SettingsDialogButton}`} > - Advanced extension management + {t('advancedExtManagement')}
{title}
- +
{items.length === 0 ? (
- No links yet. + {t('extLinksEmpty')}
) : ( @@ -100,21 +101,21 @@ export default function DynamicListManager({ } }} /> -
)) diff --git a/frontend/extensions-manager/Settings/ExtendiumSettings.tsx b/frontend/extensions-manager/Settings/ExtendiumSettings.tsx index 8d94548..6eb1d2b 100644 --- a/frontend/extensions-manager/Settings/ExtendiumSettings.tsx +++ b/frontend/extensions-manager/Settings/ExtendiumSettings.tsx @@ -2,12 +2,13 @@ import { DialogBody, Field, SliderField, Toggle } from '@steambrew/client'; import { usePopupsStore } from 'components/stores/popupsStore'; import React from 'react'; import { MdArrowBack } from 'react-icons/md'; +import { t } from '../../i18n'; import { ExternalLinksManager } from './ExternalLinksMananger'; import { useSettingsStore } from './settingsStore'; export function ExtendiumSettings(): React.ReactNode { const { setManagerPopup } = usePopupsStore(); - const { barMarginLeft, barMarginRight, showCompatibilityPills, openLinksInCurrentTab, setSettings } = useSettingsStore(); + const { barMarginLeft, barMarginRight, showCompatibilityPills, openLinksInCurrentTab, language, setSettings } = useSettingsStore(); return ( @@ -15,11 +16,11 @@ export function ExtendiumSettings(): React.ReactNode { -

Extendium Settings

+

{t('settingsTitle')}

- + - +
- Show compatibility pills + {t('showCompPillsSpan')} { setSettings({ showCompatibilityPills: value }); }} value={showCompatibilityPills} />
+ +
+ +
+
- +
- Open in current tab + {t('openLinksSpan')} { setSettings({ openLinksInCurrentTab: value }); }} value={openLinksInCurrentTab} diff --git a/frontend/extensions-manager/Settings/settingsStore.ts b/frontend/extensions-manager/Settings/settingsStore.ts index 547aae7..5056872 100644 --- a/frontend/extensions-manager/Settings/settingsStore.ts +++ b/frontend/extensions-manager/Settings/settingsStore.ts @@ -8,6 +8,7 @@ interface SettingsStore { barMarginRight: number; openLinksInCurrentTab: boolean; showCompatibilityPills: boolean; + language: 'auto' | 'en' | 'ja'; } const settingsStorageKey = 'extendium_settingsStore'; @@ -19,7 +20,8 @@ export const useSettingsStore = create()(persist( barMarginRight: 0, showCompatibilityPills: true, openLinksInCurrentTab: false, - setSettings: (settings: SettingsStore): void => { + language: 'auto', + setSettings: (settings: Partial): void => { set((state) => { const newState = { ...state, ...settings }; if (newState.openLinksInCurrentTab !== state.openLinksInCurrentTab) { diff --git a/frontend/i18n.ts b/frontend/i18n.ts new file mode 100644 index 0000000..cbbaa0d --- /dev/null +++ b/frontend/i18n.ts @@ -0,0 +1,216 @@ +import { useSettingsStore } from './extensions-manager/Settings/settingsStore'; + +export const translations = { + en: { + // ExtensionManagerComponent + details: 'Details', + remove: 'Remove', + clickForCompList: 'Compatibility: {compatibility}, click for compatibility list', + + // ExtensionDetailInfo + errorInExtension: 'Error in extension', + description: 'Description', + version: 'Version', + id: 'Id', + inspectViews: 'Inspect views', + errors: 'Errors', + errorInstructions: 'For detailed error information, {devmodeLink} and open the console of the specified view in the list above', + enableDevModeText: 'enable dev mode', + extensionOptions: 'Extension options', + removeExtension: 'Remove extension', + + // ExtensionManagerRoot + installExtension: 'Install extension', + advancedExtManagement: 'Advanced extension management', + + // ExtensionManagerPopup + extensions: 'Extensions', + undefinedRoute: 'Error you somehow got to an undefined route "{route}" please report this.', + + // ExtendiumSettings + settingsTitle: 'Extendium Settings', + settingsDesc: 'If the extension bar is covered up by other buttons or you want to move it you can change the margin here', + marginRight: 'Margin right', + marginLeft: 'Margin left', + showCompPillsLabel: 'Show compatibility status pills next to extension names in the extension manager', + showCompPillsSpan: 'Show compatibility pills', + openLinksLabel: 'Always open links in current tab on left click (ignores target blank)', + openLinksSpan: 'Open in current tab', + languageLabel: 'UI Language', + languageDesc: 'Choose the language used for the Extendium plugin user interface', + langAuto: 'Auto (Steam System)', + langEn: 'English', + langJa: '日本語', + + // DynamicListManager + extLinksTitle: 'External links', + extLinksDesc: 'Manage URL patterns that should always open in an external browser. For each entry, provide a string to match against the URL. If \'Regex\' is checked, the string is treated as a regular expression. Otherwise, it performs a simple case sensitive text search.', + extLinksPlaceholder: 'Paste or type a link…', + extLinksAdd: 'Add link', + extLinksEmpty: 'No links yet.', + extLinksRemove: 'Remove', + extLinksRegex: 'Regex', + extLinksRegexTooltip: 'Treat match as a regular expression', + + // ExtensionContextMenu + unpin: 'Unpin', + manage: 'Manage', + options: 'Options', + + // ToolbarManagerContextMenu & ManagerExtensionItem + pin: 'Pin', + manageExtensions: 'Manage extensions', + + // extensionInstallationFailedDialog + failedTitle: 'Extendium installation failed', + failedDesc1: 'Extendium needs a helper extension to work fully, but the automatic installation didn\'t complete successfully.', + failedDesc2: 'Without the helper extension, some extensions like Augmented Steam won\'t work properly.', + failedDesc3: 'You can try the automatic installation again, or manually install the helper extension by following the step-by-step instructions in the readme {readmeLink}.', + here: 'here', + failedDesc4: 'If the problem persists, please check the plugin logs for more details and report this issue on the {githubLink} or the {discordLink} with your log.', + githubRepo: 'Extendium GitHub repository', + discordChannel: 'discord channel', + tryAgain: 'Try installation again', + ignoreBtn: 'Ignore and don\'t show again', + understoodBtn: 'Understood, I will manually install it', + + // extensionInitialization + unsupportedTitle: 'Unsupported extension installed', + unsupportedDesc1: 'We\'ve automatically detected an extension ({extensionName}:{extensionId}) that is known to cause Steam to become unresponsive, crash or become fully bricked.', + unsupportedDesc2: 'You WILL NEED to remove this extension to prevent potential issues with your Steam client.', + unsupportedDesc3: 'You can find more information about compatible extensions on the Extendium github page.', + uninstallBtn: 'Uninstall extension', + + // legacyExtensionDialog + legacyTitle: 'Legacy Extendium Extensions Detected', + legacyDesc: 'The following extensions were found in Extendium\'s .extensions folder. These were previously installed using Extendium\'s old installation method and will no longer work.', + legacyReinstall: 'Please reinstall them from the Chrome Web Store to ensure they function correctly.', + legacyDeleteInstruction: 'To not show this dialog again use the "Delete All" button below to delete all legacy extensions.', + openInWebStore: 'Open in Chrome Web Store', + manuallyInstalled: 'Manually installed (no web store link)', + deleteConfirmTitle: 'Delete All Legacy Extensions?', + deleteConfirmDesc: 'Are you sure you want to delete all legacy extension folders? This action cannot be undone.', + deleteAllBtn: 'Delete All', + deletedTitle: 'Legacy Extensions Deleted', + deletedDesc: 'All legacy extension folders have been deleted.', + okBtn: 'OK', + openAllInWebStore: 'Open All in Web Store', + closeBtn: 'Close', + }, + ja: { + // ExtensionManagerComponent + details: '詳細', + remove: '削除', + clickForCompList: '互換性: {compatibility}。クリックして互換性リストを開く', + + // ExtensionDetailInfo + errorInExtension: '拡張機能のエラー', + description: '説明', + version: 'バージョン', + id: 'ID', + inspectViews: 'ビューを検査', + errors: 'エラー', + errorInstructions: '詳細なエラー情報は、{devmodeLink}し、上記のリストの指定されたビューのコンソールを開いてください。', + enableDevModeText: '開発者モードを有効', + extensionOptions: '拡張機能のオプション', + removeExtension: '拡張機能を削除', + + // ExtensionManagerRoot + installExtension: '拡張機能をインストール', + advancedExtManagement: '高度な拡張機能管理', + + // ExtensionManagerPopup + extensions: '拡張機能', + undefinedRoute: 'エラー: 未定義のルート "{route}" に到達しました。この問題を報告してください。', + + // ExtendiumSettings + settingsTitle: 'Extendiumの設定', + settingsDesc: '拡張機能バーが他のボタンで隠れてしまう場合や、位置を調整したい場合は、ここで余白を変更できます。', + marginRight: '右の余白', + marginLeft: '左の余白', + showCompPillsLabel: '拡張機能の管理で拡張機能名の横に互換性のステータスバッジを表示', + showCompPillsSpan: '互換性バッジを表示する', + openLinksLabel: '左クリック時に常に現在のタブでリンクを開く(target="_blank" を無視)', + openLinksSpan: '現在のタブで開く', + languageLabel: 'UIの言語', + languageDesc: 'Extendiumプラグインのユーザーインターフェースで使用する言語を選択します', + langAuto: '自動 (Steamの言語)', + langEn: 'English', + langJa: '日本語', + + // DynamicListManager + extLinksTitle: '外部リンク', + extLinksDesc: '常に外部ブラウザーで開くべきURLパターンを管理します。各エントリについて、URLと照合する文字列を指定してください。「Regex」がチェックされている場合、文字列は正規表現として扱われます。それ以外の場合は、単純な大文字小文字を区別するテキスト検索が行われます。', + extLinksPlaceholder: 'リンクを貼り付け、または入力...', + extLinksAdd: 'リンクを追加', + extLinksEmpty: 'リンクはまだありません。', + extLinksRemove: '削除', + extLinksRegex: '正規表現', + extLinksRegexTooltip: 'パターンを正規表現として扱います', + + // ExtensionContextMenu + unpin: 'ピン留めを外す', + manage: '管理', + options: 'オプション', + + // ToolbarManagerContextMenu & ManagerExtensionItem + pin: 'ピン留めする', + manageExtensions: '拡張機能を管理', + + // extensionInstallationFailedDialog + failedTitle: 'Extendiumのインストールに失敗しました', + failedDesc1: 'Extendiumを完全に動作させるにはヘルパー拡張機能が必要ですが、自動インストールが正常に完了しませんでした。', + failedDesc2: 'ヘルパー拡張機能がないと、Augmented Steam などの一部の拡張機能が正常に動作しません。', + failedDesc3: '自動インストールを再試行するか、{readmeLink}のREADMEにあるステップバイステップの手順に従ってヘルパー拡張機能を手動でインストールしてください。', + here: 'こちら', + failedDesc4: '問題が解決しない場合は、プラグインのログで詳細を確認し、ログを添えて{githubLink}または{discordLink}でこの問題を報告してください。', + githubRepo: 'ExtendiumのGitHubリポジトリ', + discordChannel: 'Discordチャンネル', + tryAgain: 'インストールを再試行', + ignoreBtn: '無視して再表示しない', + understoodBtn: '理解しました。手動でインストールします。', + + // extensionInitialization + unsupportedTitle: 'サポートされていない拡張機能がインストールされました', + unsupportedDesc1: 'Steamが応答しなくなったり、クラッシュしたり、完全に動作しなくなったり(ブリック)することが知られている拡張機能 ({extensionName}:{extensionId}) が自動的に検出されました。', + unsupportedDesc2: 'Steamクライアントの潜在的な問題を回避するために、この拡張機能を削除する必要があります。', + unsupportedDesc3: '互換性のある拡張機能に関する詳細情報は、ExtendiumのGitHubページで確認できます。', + uninstallBtn: '拡張機能をアンインストール', + + // legacyExtensionDialog + legacyTitle: '古いExtendium拡張機能を検出しました', + legacyDesc: '以下の拡張機能がExtendiumの「.extensions」フォルダー内に見つかりました。これらは以前のExtendiumの古いインストール方法でインストールされたため、現在は動作しません。', + legacyReinstall: '正常に動作させるために、Chromeウェブストアから再インストールしてください。', + legacyDeleteInstruction: 'このダイアログを再表示しないようにするには、下の「すべて削除」ボタンを使用して古い拡張機能をすべて削除してください。', + openInWebStore: 'Chrome ウェブストアで開く', + manuallyInstalled: '手動インストール(ウェブストアのリンクなし)', + deleteConfirmTitle: '古い拡張機能をすべて削除しますか?', + deleteConfirmDesc: '古い拡張機能のフォルダーをすべて削除してもよろしいですか?この操作は取り消せません。', + deleteAllBtn: 'すべて削除', + deletedTitle: '古い拡張機能を削除しました', + deletedDesc: 'すべての古い拡張機能フォルダーが削除されました。', + okBtn: 'OK', + openAllInWebStore: 'すべてウェブストアで開く', + closeBtn: '閉じる', + } +}; + +export type TranslationKey = keyof typeof translations.en; + +export function getLanguage(): 'en' | 'ja' { + const storeLanguage = useSettingsStore.getState().language; + if (storeLanguage === 'en') return 'en'; + if (storeLanguage === 'ja') return 'ja'; + + // Auto-detect based on navigator.language + const lang = navigator.language || ''; + if (lang.toLowerCase().startsWith('ja')) { + return 'ja'; + } + return 'en'; +} + +export function t(key: TranslationKey): string { + const lang = getLanguage(); + return translations[lang][key] || translations.en[key] || String(key); +} diff --git a/frontend/legacyExtensionDialog.tsx b/frontend/legacyExtensionDialog.tsx index 863fdf3..7af0338 100644 --- a/frontend/legacyExtensionDialog.tsx +++ b/frontend/legacyExtensionDialog.tsx @@ -4,6 +4,7 @@ import { OpenTargetPage } from 'chrome/ChromePageManager'; import { showConfirmationModal } from 'components/ConfirmationModal'; import React from 'react'; import { mainWindow } from 'shared'; +import { t } from './i18n'; export interface LegacyExtension { extensionId?: string; @@ -22,11 +23,11 @@ function LegacyExtensionDialogDescription({ extensions }: { readonly extensions: return ( <>

- The following extensions were found in Extendium's .extensions folder. These were previously installed using Extendium's old installation method and will no longer work. + {t('legacyDesc')}
- Please reinstall them from the Chrome Web Store to ensure they function correctly. + {t('legacyReinstall')}
- To not show this dialog again use the "Delete All" button below to delete all legacy extensions. + {t('legacyDeleteInstruction')}

{extensions.map(ext => ( @@ -35,11 +36,11 @@ function LegacyExtensionDialogDescription({ extensions }: { readonly extensions: {ext.hasMetadata && ext.url !== undefined ? ( - Open in Chrome Web Store + {t('openInWebStore')} ) : ( -
Manually installed (no web store link)
+
{t('manuallyInstalled')}
)}
))} @@ -64,15 +65,15 @@ export function showLegacyExtensionDialog(extensionsJson: string): void { function handleDeleteAll(): void { dialog.Close(); showConfirmationModal({ - title: 'Delete All Legacy Extensions?', - description: 'Are you sure you want to delete all legacy extension folders? This action cannot be undone.', - okButtonText: 'Delete All', + title: t('deleteConfirmTitle'), + description: t('deleteConfirmDesc'), + okButtonText: t('deleteAllBtn'), onOK: async () => { await DeleteLegacyExtensions(); showConfirmationModal({ - title: 'Legacy Extensions Deleted', - description: 'All legacy extension folders have been deleted.', - okButtonText: 'OK', + title: t('deletedTitle'), + description: t('deletedDesc'), + okButtonText: t('okBtn'), }); }, bDestructiveWarning: true, @@ -81,11 +82,11 @@ export function showLegacyExtensionDialog(extensionsJson: string): void { dialog = showModal( } - strOKButtonText={hasAnyWebstoreExtensions ? 'Open All in Web Store' : 'OK'} - strMiddleButtonText="Delete All" - strCancelButtonText={hasAnyWebstoreExtensions ? 'Close' : undefined} + strOKButtonText={hasAnyWebstoreExtensions ? t('openAllInWebStore') : t('okBtn')} + strMiddleButtonText={t('deleteAllBtn')} + strCancelButtonText={hasAnyWebstoreExtensions ? t('closeBtn') : undefined} bDisableBackgroundDismiss onOK={() => { if (hasAnyWebstoreExtensions) {