fix(shared): i18n coverage and contract updates
- keyPath field no longer tells users to enter a server-side path - settings.highlight.builtin.* notes, timeout messages in four languages - prototype-safe dictionary lookup; language as a render-time dependency - Partial<AppSettings> saveSettings contract, update:stateGet channel
This commit is contained in:
1 parent
23fa566fa9
commit
c0342db1e8
16 files changed
+100
-9
No files matched your search
@@ -106,7 +106,7 @@ const api: AppApi = {
|
|||||||
ipcRenderer.send(Ipc.HOSTKEY_RESPOND, promptId, action),
|
ipcRenderer.send(Ipc.HOSTKEY_RESPOND, promptId, action),
|
||||||
|
|
||||||
getSettings: () => ipcRenderer.invoke(Ipc.SETTINGS_GET),
|
getSettings: () => ipcRenderer.invoke(Ipc.SETTINGS_GET),
|
||||||
saveSettings: (next: AppSettings) => ipcRenderer.invoke(Ipc.SETTINGS_SET, next),
|
saveSettings: (next: Partial<AppSettings>) => ipcRenderer.invoke(Ipc.SETTINGS_SET, next),
|
||||||
onSettingsChanged: (cb: (s: AppSettings) => void) => {
|
onSettingsChanged: (cb: (s: AppSettings) => void) => {
|
||||||
const listener = (_: unknown, s: AppSettings): void => cb(s)
|
const listener = (_: unknown, s: AppSettings): void => cb(s)
|
||||||
ipcRenderer.on(Ipc.SETTINGS_CHANGED, listener)
|
ipcRenderer.on(Ipc.SETTINGS_CHANGED, listener)
|
||||||
@@ -121,6 +121,7 @@ const api: AppApi = {
|
|||||||
deleteLayout: (id: string) => ipcRenderer.invoke(Ipc.LAYOUTS_DELETE, id),
|
deleteLayout: (id: string) => ipcRenderer.invoke(Ipc.LAYOUTS_DELETE, id),
|
||||||
|
|
||||||
updateCheck: () => ipcRenderer.invoke(Ipc.UPDATE_CHECK),
|
updateCheck: () => ipcRenderer.invoke(Ipc.UPDATE_CHECK),
|
||||||
|
getUpdateState: () => ipcRenderer.invoke(Ipc.UPDATE_STATE_GET),
|
||||||
updateDownload: () => ipcRenderer.invoke(Ipc.UPDATE_DOWNLOAD),
|
updateDownload: () => ipcRenderer.invoke(Ipc.UPDATE_DOWNLOAD),
|
||||||
updateInstall: () => ipcRenderer.invoke(Ipc.UPDATE_INSTALL),
|
updateInstall: () => ipcRenderer.invoke(Ipc.UPDATE_INSTALL),
|
||||||
updateChangelog: () => ipcRenderer.invoke(Ipc.UPDATE_CHANGELOG),
|
updateChangelog: () => ipcRenderer.invoke(Ipc.UPDATE_CHANGELOG),
|
||||||
|
|||||||
+3
-1
@@ -97,7 +97,7 @@ export interface AppApi {
|
|||||||
|
|
||||||
// ---- settings ----
|
// ---- settings ----
|
||||||
getSettings(): Promise<AppSettings>
|
getSettings(): Promise<AppSettings>
|
||||||
saveSettings(next: AppSettings): Promise<AppSettings>
|
saveSettings(next: Partial<AppSettings>): Promise<AppSettings>
|
||||||
onSettingsChanged(cb: (s: AppSettings) => void): () => void
|
onSettingsChanged(cb: (s: AppSettings) => void): () => void
|
||||||
|
|
||||||
// ---- fonts ----
|
// ---- fonts ----
|
||||||
@@ -112,6 +112,8 @@ export interface AppApi {
|
|||||||
|
|
||||||
// ---- updater (domestic feed first, GitHub fallback) ----
|
// ---- updater (domestic feed first, GitHub fallback) ----
|
||||||
updateCheck(): Promise<UpdateState>
|
updateCheck(): Promise<UpdateState>
|
||||||
|
/** read the updater's current state without triggering a network check */
|
||||||
|
getUpdateState(): Promise<UpdateState>
|
||||||
updateDownload(): Promise<void>
|
updateDownload(): Promise<void>
|
||||||
updateInstall(): Promise<void>
|
updateInstall(): Promise<void>
|
||||||
updateChangelog(): Promise<ReleaseNote[]>
|
updateChangelog(): Promise<ReleaseNote[]>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const main: Record<string, string> = {
|
|||||||
'main.tray.closeDetail': 'Minimizing to tray keeps your terminal sessions running.',
|
'main.tray.closeDetail': 'Minimizing to tray keeps your terminal sessions running.',
|
||||||
'main.tray.rememberChoice': 'Remember my choice, never ask again',
|
'main.tray.rememberChoice': 'Remember my choice, never ask again',
|
||||||
|
|
||||||
'main.updater.feedFailed': 'Domestic feed: {gitea}; GitHub: {github}',
|
'main.updater.feedFailed': 'Gitea feed: {gitea}; GitHub: {github}',
|
||||||
|
|
||||||
'main.ssh.connectTimeout': 'Connection timed out ({host}:{port})',
|
'main.ssh.connectTimeout': 'Connection timed out ({host}:{port})',
|
||||||
'main.ssh.saveFingerprintFailed': 'Failed to save the host fingerprint: {detail}',
|
'main.ssh.saveFingerprintFailed': 'Failed to save the host fingerprint: {detail}',
|
||||||
@@ -27,6 +27,7 @@ const main: Record<string, string> = {
|
|||||||
'main.sftp.deleteFailed': 'Delete failed: {detail}',
|
'main.sftp.deleteFailed': 'Delete failed: {detail}',
|
||||||
'main.sftp.invalidMode': 'Invalid permission value: {mode}',
|
'main.sftp.invalidMode': 'Invalid permission value: {mode}',
|
||||||
'main.sftp.invalidUidGid': 'Invalid uid/gid',
|
'main.sftp.invalidUidGid': 'Invalid uid/gid',
|
||||||
|
'main.sftp.commandTimeout': 'Command timed out',
|
||||||
'main.sftp.commandExitCode': 'Command exited with code {code}',
|
'main.sftp.commandExitCode': 'Command exited with code {code}',
|
||||||
'main.sftp.cancelled': 'Cancelled',
|
'main.sftp.cancelled': 'Cancelled',
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ const main: Record<string, string> = {
|
|||||||
|
|
||||||
'main.sysinfo.sessionGone': 'SSH session is missing or disconnected',
|
'main.sysinfo.sessionGone': 'SSH session is missing or disconnected',
|
||||||
'main.sysinfo.execFailed': 'SSH exec failed',
|
'main.sysinfo.execFailed': 'SSH exec failed',
|
||||||
|
'main.sysinfo.pollTimeout': 'Monitoring command timed out',
|
||||||
'main.sysinfo.parseFailed': 'Parse failed: {message}',
|
'main.sysinfo.parseFailed': 'Parse failed: {message}',
|
||||||
'main.pty.serviceNotReady': 'SSH session service is not initialised yet',
|
'main.pty.serviceNotReady': 'SSH session service is not initialised yet',
|
||||||
'main.pty.missingConnectionId': 'SSH session is missing its connectionId',
|
'main.pty.missingConnectionId': 'SSH session is missing its connectionId',
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ const settings: Record<string, string> = {
|
|||||||
'Together with the global key this shows or hides the window from anywhere; if registration fails (a conflict with another app) it simply has no effect and the app reports no error.',
|
'Together with the global key this shows or hides the window from anywhere; if registration fails (a conflict with another app) it simply has no effect and the app reports no error.',
|
||||||
'settings.system.shortcutRecording': 'Press the keys…',
|
'settings.system.shortcutRecording': 'Press the keys…',
|
||||||
'settings.system.shortcutPlaceholder': 'Click and press a shortcut, leave empty to disable',
|
'settings.system.shortcutPlaceholder': 'Click and press a shortcut, leave empty to disable',
|
||||||
|
'settings.system.shortcutConflict':
|
||||||
|
'This shortcut is already used by the app (Ctrl+= / Ctrl+- / Ctrl+0 / Ctrl+PgUp / Ctrl+PgDn). Please choose another.',
|
||||||
|
'settings.resetTerminal': 'Reset terminal settings',
|
||||||
|
'settings.resetTerminalTitle': 'Reset terminal settings?',
|
||||||
|
'settings.resetTerminalDesc': 'All terminal settings — font, cursor, rendering and theme — will be restored to defaults.',
|
||||||
'settings.highlight.alert':
|
'settings.highlight.alert':
|
||||||
'Custom highlighting improves readability at a small performance cost. Rules are applied in priority order. PS: colors are injected as text is written to the terminal, so existing scrollback is unaffected',
|
'Custom highlighting improves readability at a small performance cost. Rules are applied in priority order. PS: colors are injected as text is written to the terminal, so existing scrollback is unaffected',
|
||||||
'settings.highlight.enabled': 'Enabled',
|
'settings.highlight.enabled': 'Enabled',
|
||||||
@@ -121,6 +126,17 @@ const settings: Record<string, string> = {
|
|||||||
'settings.highlight.resetOk': 'Restore',
|
'settings.highlight.resetOk': 'Restore',
|
||||||
'settings.highlight.createTitle': 'New highlight rule',
|
'settings.highlight.createTitle': 'New highlight rule',
|
||||||
'settings.highlight.editTitle': 'Edit highlight rule',
|
'settings.highlight.editTitle': 'Edit highlight rule',
|
||||||
|
'settings.highlight.builtin.perm': 'Linux permissions and user/group',
|
||||||
|
'settings.highlight.builtin.path': 'Linux file paths',
|
||||||
|
'settings.highlight.builtin.shellkw': 'Shell keywords and control flow',
|
||||||
|
'settings.highlight.builtin.okstate': 'Success states',
|
||||||
|
'settings.highlight.builtin.badstate': 'Error/warning states',
|
||||||
|
'settings.highlight.builtin.quoted': 'Strings and quotes',
|
||||||
|
'settings.highlight.builtin.envvar': 'Environment variables and arguments',
|
||||||
|
'settings.highlight.builtin.ipv4': 'Network and IP addresses',
|
||||||
|
'settings.highlight.builtin.datetime': 'Time and date',
|
||||||
|
'settings.highlight.builtin.numbers': 'Numbers and counts',
|
||||||
|
'settings.highlight.builtin.url': 'Web links',
|
||||||
'settings.theme.accent': 'Tab accent color',
|
'settings.theme.accent': 'Tab accent color',
|
||||||
'settings.theme.accentDesc': 'Accent color for the active tab border, the sidebar indicator, and SSH badges',
|
'settings.theme.accentDesc': 'Accent color for the active tab border, the sidebar indicator, and SSH badges',
|
||||||
'settings.theme.customBadge': 'Custom',
|
'settings.theme.customBadge': 'Custom',
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const ssh: Record<string, string> = {
|
|||||||
'ssh.fields.askPasswordHint':
|
'ssh.fields.askPasswordHint':
|
||||||
'Prompts for the password on every connection instead of using the saved one',
|
'Prompts for the password on every connection instead of using the saved one',
|
||||||
'ssh.fields.passwordPlaceholder': 'Leave empty to keep the saved password',
|
'ssh.fields.passwordPlaceholder': 'Leave empty to keep the saved password',
|
||||||
'ssh.fields.keyPath': 'Private key path (path on the server, optional)',
|
'ssh.fields.keyPath': 'Private key file path (on this computer, optional)',
|
||||||
'ssh.fields.keyContent': 'Private key content',
|
'ssh.fields.keyContent': 'Private key content',
|
||||||
'ssh.fields.keyContentPlaceholder':
|
'ssh.fields.keyContentPlaceholder':
|
||||||
'Paste the private key; leave empty to use the path above (leave empty while editing to keep the saved key)',
|
'Paste the private key; leave empty to use the path above (leave empty while editing to keep the saved key)',
|
||||||
@@ -100,6 +100,8 @@ const ssh: Record<string, string> = {
|
|||||||
'ssh.file.up': 'Parent folder',
|
'ssh.file.up': 'Parent folder',
|
||||||
'ssh.file.refresh': 'Refresh',
|
'ssh.file.refresh': 'Refresh',
|
||||||
'ssh.file.uploadFile': 'Upload files',
|
'ssh.file.uploadFile': 'Upload files',
|
||||||
|
'ssh.file.overwriteTitle': 'Overwrite existing file?',
|
||||||
|
'ssh.file.overwriteDesc': 'A file with the same name exists in the target directory; uploading will overwrite its contents.',
|
||||||
'ssh.file.downloadSelected': 'Download selection',
|
'ssh.file.downloadSelected': 'Download selection',
|
||||||
'ssh.file.permOwner': 'Permissions / owner',
|
'ssh.file.permOwner': 'Permissions / owner',
|
||||||
'ssh.file.open': 'Open',
|
'ssh.file.open': 'Open',
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const main: Record<string, string> = {
|
|||||||
'main.tray.closeDetail': 'トレイに最小化すると、ターミナルセッションは実行を続けます。',
|
'main.tray.closeDetail': 'トレイに最小化すると、ターミナルセッションは実行を続けます。',
|
||||||
'main.tray.rememberChoice': '選択を記憶して今後確認しない',
|
'main.tray.rememberChoice': '選択を記憶して今後確認しない',
|
||||||
|
|
||||||
'main.updater.feedFailed': '国内フィード: {gitea};GitHub: {github}',
|
'main.updater.feedFailed': 'Gitea フィード: {gitea};GitHub: {github}',
|
||||||
|
|
||||||
'main.ssh.connectTimeout': '接続がタイムアウトしました ({host}:{port})',
|
'main.ssh.connectTimeout': '接続がタイムアウトしました ({host}:{port})',
|
||||||
'main.ssh.saveFingerprintFailed': 'ホスト鍵のフィンガープリントを保存できませんでした: {detail}',
|
'main.ssh.saveFingerprintFailed': 'ホスト鍵のフィンガープリントを保存できませんでした: {detail}',
|
||||||
@@ -27,6 +27,7 @@ const main: Record<string, string> = {
|
|||||||
'main.sftp.deleteFailed': '削除に失敗しました: {detail}',
|
'main.sftp.deleteFailed': '削除に失敗しました: {detail}',
|
||||||
'main.sftp.invalidMode': '不正なパーミッション値: {mode}',
|
'main.sftp.invalidMode': '不正なパーミッション値: {mode}',
|
||||||
'main.sftp.invalidUidGid': '不正な uid/gid',
|
'main.sftp.invalidUidGid': '不正な uid/gid',
|
||||||
|
'main.sftp.commandTimeout': 'コマンドがタイムアウトしました',
|
||||||
'main.sftp.commandExitCode': 'コマンドの終了コード {code}',
|
'main.sftp.commandExitCode': 'コマンドの終了コード {code}',
|
||||||
'main.sftp.cancelled': 'キャンセルしました',
|
'main.sftp.cancelled': 'キャンセルしました',
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ const main: Record<string, string> = {
|
|||||||
|
|
||||||
'main.sysinfo.sessionGone': 'SSH セッションが存在しないか切断されています',
|
'main.sysinfo.sessionGone': 'SSH セッションが存在しないか切断されています',
|
||||||
'main.sysinfo.execFailed': 'SSH exec に失敗しました',
|
'main.sysinfo.execFailed': 'SSH exec に失敗しました',
|
||||||
|
'main.sysinfo.pollTimeout': '監視コマンドがタイムアウトしました',
|
||||||
'main.sysinfo.parseFailed': '解析に失敗しました: {message}',
|
'main.sysinfo.parseFailed': '解析に失敗しました: {message}',
|
||||||
'main.pty.serviceNotReady': 'SSH セッションサービスが未初期化です',
|
'main.pty.serviceNotReady': 'SSH セッションサービスが未初期化です',
|
||||||
'main.pty.missingConnectionId': 'SSH セッションに connectionId がありません',
|
'main.pty.missingConnectionId': 'SSH セッションに connectionId がありません',
|
||||||
|
|||||||
@@ -95,6 +95,11 @@ const settings: Record<string, string> = {
|
|||||||
'グローバルキーと組み合わせると、どの画面からでもウィンドウを呼び出し/非表示にできます。登録に失敗した場合(他のソフトとの競合)は効果がなく、アプリにエラーは表示されません。',
|
'グローバルキーと組み合わせると、どの画面からでもウィンドウを呼び出し/非表示にできます。登録に失敗した場合(他のソフトとの競合)は効果がなく、アプリにエラーは表示されません。',
|
||||||
'settings.system.shortcutRecording': 'キーを押してください…',
|
'settings.system.shortcutRecording': 'キーを押してください…',
|
||||||
'settings.system.shortcutPlaceholder': 'クリックしてショートカットを押す。空欄で無効',
|
'settings.system.shortcutPlaceholder': 'クリックしてショートカットを押す。空欄で無効',
|
||||||
|
'settings.system.shortcutConflict':
|
||||||
|
'このショートカットはアプリ内で既に使用されています(Ctrl+= / Ctrl+- / Ctrl+0 / Ctrl+PgUp / Ctrl+PgDn)。別のものを選んでください。',
|
||||||
|
'settings.resetTerminal': 'ターミナル設定をリセット',
|
||||||
|
'settings.resetTerminalTitle': 'ターミナル設定をリセットしますか?',
|
||||||
|
'settings.resetTerminalDesc': 'フォント、カーソル、レンダリング、テーマなどすべてのターミナル設定がデフォルトに戻ります。',
|
||||||
'settings.highlight.alert':
|
'settings.highlight.alert':
|
||||||
'独自のハイライトは見やすさを高めますが、わずかに性能を消費します。ルールは優先順に適用されます。PS: ハイライトはターミナルへの書き込み時に色を注入するため、既存のスクロールバックには反映されません',
|
'独自のハイライトは見やすさを高めますが、わずかに性能を消費します。ルールは優先順に適用されます。PS: ハイライトはターミナルへの書き込み時に色を注入するため、既存のスクロールバックには反映されません',
|
||||||
'settings.highlight.enabled': '有効',
|
'settings.highlight.enabled': '有効',
|
||||||
@@ -118,6 +123,17 @@ const settings: Record<string, string> = {
|
|||||||
'settings.highlight.resetOk': '元に戻す',
|
'settings.highlight.resetOk': '元に戻す',
|
||||||
'settings.highlight.createTitle': 'ハイライトルールを作成',
|
'settings.highlight.createTitle': 'ハイライトルールを作成',
|
||||||
'settings.highlight.editTitle': 'ハイライトルールを編集',
|
'settings.highlight.editTitle': 'ハイライトルールを編集',
|
||||||
|
'settings.highlight.builtin.perm': 'Linux のパーミッションとユーザー',
|
||||||
|
'settings.highlight.builtin.path': 'Linux のファイルパス',
|
||||||
|
'settings.highlight.builtin.shellkw': 'Shell のキーワードと制御構文',
|
||||||
|
'settings.highlight.builtin.okstate': '成功ステータス',
|
||||||
|
'settings.highlight.builtin.badstate': 'エラー・警告ステータス',
|
||||||
|
'settings.highlight.builtin.quoted': '文字列と引用符',
|
||||||
|
'settings.highlight.builtin.envvar': '環境変数と引数',
|
||||||
|
'settings.highlight.builtin.ipv4': 'ネットワークと IP アドレス',
|
||||||
|
'settings.highlight.builtin.datetime': '時刻と日付',
|
||||||
|
'settings.highlight.builtin.numbers': '数値とカウント',
|
||||||
|
'settings.highlight.builtin.url': 'ウェブリンク',
|
||||||
'settings.theme.accent': 'タブのアクセントカラー',
|
'settings.theme.accent': 'タブのアクセントカラー',
|
||||||
'settings.theme.accentDesc': 'アクティブなタブの枠線、サイドバーのインジケーター、SSH バッジのアクセントカラー',
|
'settings.theme.accentDesc': 'アクティブなタブの枠線、サイドバーのインジケーター、SSH バッジのアクセントカラー',
|
||||||
'settings.theme.customBadge': 'カスタム',
|
'settings.theme.customBadge': 'カスタム',
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const ssh: Record<string, string> = {
|
|||||||
'ssh.fields.askPasswordHint':
|
'ssh.fields.askPasswordHint':
|
||||||
'オンにすると毎回の接続でパスワード入力ダイアログを表示し、保存済みのパスワードを使いません',
|
'オンにすると毎回の接続でパスワード入力ダイアログを表示し、保存済みのパスワードを使いません',
|
||||||
'ssh.fields.passwordPlaceholder': '編集時に空欄のままにすると保存済みのパスワードを保持します',
|
'ssh.fields.passwordPlaceholder': '編集時に空欄のままにすると保存済みのパスワードを保持します',
|
||||||
'ssh.fields.keyPath': '秘密鍵のパス(サーバー上の秘密鍵のパス、省略可)',
|
'ssh.fields.keyPath': '秘密鍵ファイルのパス(このコンピューター上のパス、省略可)',
|
||||||
'ssh.fields.keyContent': '秘密鍵の内容',
|
'ssh.fields.keyContent': '秘密鍵の内容',
|
||||||
'ssh.fields.keyContentPlaceholder':
|
'ssh.fields.keyContentPlaceholder':
|
||||||
'秘密鍵の内容を貼り付けます。空欄の場合は上のパスを使用します(編集時に空欄のままにすると保存済みの秘密鍵を保持します)',
|
'秘密鍵の内容を貼り付けます。空欄の場合は上のパスを使用します(編集時に空欄のままにすると保存済みの秘密鍵を保持します)',
|
||||||
@@ -102,6 +102,8 @@ const ssh: Record<string, string> = {
|
|||||||
'ssh.file.up': '親フォルダへ',
|
'ssh.file.up': '親フォルダへ',
|
||||||
'ssh.file.refresh': '更新',
|
'ssh.file.refresh': '更新',
|
||||||
'ssh.file.uploadFile': 'ファイルをアップロード',
|
'ssh.file.uploadFile': 'ファイルをアップロード',
|
||||||
|
'ssh.file.overwriteTitle': '既存のファイルを上書きしますか?',
|
||||||
|
'ssh.file.overwriteDesc': '対象ディレクトリに同名のファイルが存在します。アップロードすると内容が上書きされます。',
|
||||||
'ssh.file.downloadSelected': '選択項目をダウンロード',
|
'ssh.file.downloadSelected': '選択項目をダウンロード',
|
||||||
'ssh.file.permOwner': '権限 / 所有者',
|
'ssh.file.permOwner': '権限 / 所有者',
|
||||||
'ssh.file.open': '開く',
|
'ssh.file.open': '開く',
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const main: Record<string, string> = {
|
|||||||
'main.sftp.deleteFailed': '删除失败: {detail}',
|
'main.sftp.deleteFailed': '删除失败: {detail}',
|
||||||
'main.sftp.invalidMode': '非法权限值: {mode}',
|
'main.sftp.invalidMode': '非法权限值: {mode}',
|
||||||
'main.sftp.invalidUidGid': '非法 uid/gid',
|
'main.sftp.invalidUidGid': '非法 uid/gid',
|
||||||
|
'main.sftp.commandTimeout': '命令执行超时',
|
||||||
'main.sftp.commandExitCode': '命令退出码 {code}',
|
'main.sftp.commandExitCode': '命令退出码 {code}',
|
||||||
'main.sftp.cancelled': '已取消',
|
'main.sftp.cancelled': '已取消',
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ const main: Record<string, string> = {
|
|||||||
|
|
||||||
'main.sysinfo.sessionGone': 'SSH 会话不存在或已断开',
|
'main.sysinfo.sessionGone': 'SSH 会话不存在或已断开',
|
||||||
'main.sysinfo.execFailed': 'SSH exec 失败',
|
'main.sysinfo.execFailed': 'SSH exec 失败',
|
||||||
|
'main.sysinfo.pollTimeout': '监控命令响应超时',
|
||||||
'main.sysinfo.parseFailed': '解析失败: {message}',
|
'main.sysinfo.parseFailed': '解析失败: {message}',
|
||||||
'main.pty.serviceNotReady': 'SSH 会话服务尚未初始化',
|
'main.pty.serviceNotReady': 'SSH 会话服务尚未初始化',
|
||||||
'main.pty.missingConnectionId': 'SSH 会话缺少 connectionId',
|
'main.pty.missingConnectionId': 'SSH 会话缺少 connectionId',
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ const settings: Record<string, string> = {
|
|||||||
'配合全局键可在任何界面唤起/隐藏窗口;若注册失败(与其他软件冲突)则不生效,应用不会报错。',
|
'配合全局键可在任何界面唤起/隐藏窗口;若注册失败(与其他软件冲突)则不生效,应用不会报错。',
|
||||||
'settings.system.shortcutRecording': '按下组合键…',
|
'settings.system.shortcutRecording': '按下组合键…',
|
||||||
'settings.system.shortcutPlaceholder': '点击后按下快捷键,留空禁用',
|
'settings.system.shortcutPlaceholder': '点击后按下快捷键,留空禁用',
|
||||||
|
'settings.system.shortcutConflict':
|
||||||
|
'该组合键已被应用内快捷键占用(Ctrl+= / Ctrl+- / Ctrl+0 / Ctrl+PgUp / Ctrl+PgDn),请换一个。',
|
||||||
|
'settings.resetTerminal': '恢复默认终端设置',
|
||||||
|
'settings.resetTerminalTitle': '恢复默认终端设置?',
|
||||||
|
'settings.resetTerminalDesc': '字体、光标、渲染与主题等全部终端设置将恢复为默认值。',
|
||||||
'settings.highlight.alert':
|
'settings.highlight.alert':
|
||||||
'自定义高亮可增强显示效果,但会略微增加性能消耗。规则按优先级顺序应用。PS: 高亮在写入终端时注入颜色,对已有回滚内容不生效',
|
'自定义高亮可增强显示效果,但会略微增加性能消耗。规则按优先级顺序应用。PS: 高亮在写入终端时注入颜色,对已有回滚内容不生效',
|
||||||
'settings.highlight.enabled': '启用',
|
'settings.highlight.enabled': '启用',
|
||||||
@@ -115,6 +120,17 @@ const settings: Record<string, string> = {
|
|||||||
'settings.highlight.resetOk': '恢复',
|
'settings.highlight.resetOk': '恢复',
|
||||||
'settings.highlight.createTitle': '新建高亮规则',
|
'settings.highlight.createTitle': '新建高亮规则',
|
||||||
'settings.highlight.editTitle': '编辑高亮规则',
|
'settings.highlight.editTitle': '编辑高亮规则',
|
||||||
|
'settings.highlight.builtin.perm': 'Linux 权限与用户',
|
||||||
|
'settings.highlight.builtin.path': 'Linux 文件路径',
|
||||||
|
'settings.highlight.builtin.shellkw': 'Shell 关键字与流程',
|
||||||
|
'settings.highlight.builtin.okstate': '成功状态',
|
||||||
|
'settings.highlight.builtin.badstate': '错误/警告状态',
|
||||||
|
'settings.highlight.builtin.quoted': '字符串与引号',
|
||||||
|
'settings.highlight.builtin.envvar': '环境变量与参数',
|
||||||
|
'settings.highlight.builtin.ipv4': '网络与 IP 地址',
|
||||||
|
'settings.highlight.builtin.datetime': '时间与日期',
|
||||||
|
'settings.highlight.builtin.numbers': '数字与计数',
|
||||||
|
'settings.highlight.builtin.url': '网址链接',
|
||||||
'settings.theme.accent': '标签强调色',
|
'settings.theme.accent': '标签强调色',
|
||||||
'settings.theme.accentDesc': '活动标签边框、侧栏指示条与 SSH 徽章的强调颜色',
|
'settings.theme.accentDesc': '活动标签边框、侧栏指示条与 SSH 徽章的强调颜色',
|
||||||
'settings.theme.customBadge': '自定义',
|
'settings.theme.customBadge': '自定义',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const ssh: Record<string, string> = {
|
|||||||
'ssh.fields.askPasswordLabel': '连接时询问密码',
|
'ssh.fields.askPasswordLabel': '连接时询问密码',
|
||||||
'ssh.fields.askPasswordHint': '开启后每次连接弹出对话框输入密码,不再使用已保存的密码',
|
'ssh.fields.askPasswordHint': '开启后每次连接弹出对话框输入密码,不再使用已保存的密码',
|
||||||
'ssh.fields.passwordPlaceholder': '编辑时留空表示保留已保存的密码',
|
'ssh.fields.passwordPlaceholder': '编辑时留空表示保留已保存的密码',
|
||||||
'ssh.fields.keyPath': '私钥路径(服务器上的本地私钥路径,可留空)',
|
'ssh.fields.keyPath': '私钥文件路径(本机路径,可留空)',
|
||||||
'ssh.fields.keyContent': '私钥内容',
|
'ssh.fields.keyContent': '私钥内容',
|
||||||
'ssh.fields.keyContentPlaceholder':
|
'ssh.fields.keyContentPlaceholder':
|
||||||
'粘贴私钥内容;留空则使用上面的路径(编辑时留空表示保留已保存的私钥)',
|
'粘贴私钥内容;留空则使用上面的路径(编辑时留空表示保留已保存的私钥)',
|
||||||
@@ -94,6 +94,8 @@ const ssh: Record<string, string> = {
|
|||||||
'ssh.file.up': '上一级',
|
'ssh.file.up': '上一级',
|
||||||
'ssh.file.refresh': '刷新',
|
'ssh.file.refresh': '刷新',
|
||||||
'ssh.file.uploadFile': '上传文件',
|
'ssh.file.uploadFile': '上传文件',
|
||||||
|
'ssh.file.overwriteTitle': '覆盖已存在的文件?',
|
||||||
|
'ssh.file.overwriteDesc': '目标目录已存在同名文件,上传将覆盖其内容。',
|
||||||
'ssh.file.downloadSelected': '下载选中项',
|
'ssh.file.downloadSelected': '下载选中项',
|
||||||
'ssh.file.permOwner': '权限 / 属主',
|
'ssh.file.permOwner': '权限 / 属主',
|
||||||
'ssh.file.open': '打开',
|
'ssh.file.open': '打开',
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const main: Record<string, string> = {
|
|||||||
'main.sftp.deleteFailed': '刪除失敗: {detail}',
|
'main.sftp.deleteFailed': '刪除失敗: {detail}',
|
||||||
'main.sftp.invalidMode': '權限值無效: {mode}',
|
'main.sftp.invalidMode': '權限值無效: {mode}',
|
||||||
'main.sftp.invalidUidGid': 'uid/gid 無效',
|
'main.sftp.invalidUidGid': 'uid/gid 無效',
|
||||||
|
'main.sftp.commandTimeout': '命令執行逾時',
|
||||||
'main.sftp.commandExitCode': '指令結束碼 {code}',
|
'main.sftp.commandExitCode': '指令結束碼 {code}',
|
||||||
'main.sftp.cancelled': '已取消',
|
'main.sftp.cancelled': '已取消',
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ const main: Record<string, string> = {
|
|||||||
|
|
||||||
'main.sysinfo.sessionGone': 'SSH 工作階段不存在或已中斷',
|
'main.sysinfo.sessionGone': 'SSH 工作階段不存在或已中斷',
|
||||||
'main.sysinfo.execFailed': 'SSH exec 失敗',
|
'main.sysinfo.execFailed': 'SSH exec 失敗',
|
||||||
|
'main.sysinfo.pollTimeout': '監控命令回應逾時',
|
||||||
'main.sysinfo.parseFailed': '解析失敗: {message}',
|
'main.sysinfo.parseFailed': '解析失敗: {message}',
|
||||||
'main.pty.serviceNotReady': 'SSH 工作階段服務尚未初始化',
|
'main.pty.serviceNotReady': 'SSH 工作階段服務尚未初始化',
|
||||||
'main.pty.missingConnectionId': 'SSH 工作階段缺少 connectionId',
|
'main.pty.missingConnectionId': 'SSH 工作階段缺少 connectionId',
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ const settings: Record<string, string> = {
|
|||||||
'搭配全域鍵可在任何畫面喚出/隱藏視窗;若註冊失敗(與其他軟體衝突)則不會生效,應用程式也不會報錯。',
|
'搭配全域鍵可在任何畫面喚出/隱藏視窗;若註冊失敗(與其他軟體衝突)則不會生效,應用程式也不會報錯。',
|
||||||
'settings.system.shortcutRecording': '請按下組合鍵…',
|
'settings.system.shortcutRecording': '請按下組合鍵…',
|
||||||
'settings.system.shortcutPlaceholder': '點擊後按下快速鍵,留空為停用',
|
'settings.system.shortcutPlaceholder': '點擊後按下快速鍵,留空為停用',
|
||||||
|
'settings.system.shortcutConflict':
|
||||||
|
'此組合鍵已被應用內快捷鍵佔用(Ctrl+= / Ctrl+- / Ctrl+0 / Ctrl+PgUp / Ctrl+PgDn),請換一個。',
|
||||||
|
'settings.resetTerminal': '恢復預設終端設定',
|
||||||
|
'settings.resetTerminalTitle': '恢復預設終端設定?',
|
||||||
|
'settings.resetTerminalDesc': '字體、游標、渲染與主題等全部終端設定將恢復為預設值。',
|
||||||
'settings.highlight.alert':
|
'settings.highlight.alert':
|
||||||
'自訂高亮可強化顯示效果,但會略微增加效能負擔。規則依優先順序套用。PS:高亮是在寫入終端時注入顏色,對既有的回捲內容不生效',
|
'自訂高亮可強化顯示效果,但會略微增加效能負擔。規則依優先順序套用。PS:高亮是在寫入終端時注入顏色,對既有的回捲內容不生效',
|
||||||
'settings.highlight.enabled': '啟用',
|
'settings.highlight.enabled': '啟用',
|
||||||
@@ -115,6 +120,17 @@ const settings: Record<string, string> = {
|
|||||||
'settings.highlight.resetOk': '還原',
|
'settings.highlight.resetOk': '還原',
|
||||||
'settings.highlight.createTitle': '新增高亮規則',
|
'settings.highlight.createTitle': '新增高亮規則',
|
||||||
'settings.highlight.editTitle': '編輯高亮規則',
|
'settings.highlight.editTitle': '編輯高亮規則',
|
||||||
|
'settings.highlight.builtin.perm': 'Linux 權限與使用者',
|
||||||
|
'settings.highlight.builtin.path': 'Linux 檔案路徑',
|
||||||
|
'settings.highlight.builtin.shellkw': 'Shell 關鍵字與流程',
|
||||||
|
'settings.highlight.builtin.okstate': '成功狀態',
|
||||||
|
'settings.highlight.builtin.badstate': '錯誤/警告狀態',
|
||||||
|
'settings.highlight.builtin.quoted': '字串與引號',
|
||||||
|
'settings.highlight.builtin.envvar': '環境變數與參數',
|
||||||
|
'settings.highlight.builtin.ipv4': '網路與 IP 位址',
|
||||||
|
'settings.highlight.builtin.datetime': '時間與日期',
|
||||||
|
'settings.highlight.builtin.numbers': '數字與計數',
|
||||||
|
'settings.highlight.builtin.url': '網址連結',
|
||||||
'settings.theme.accent': '標籤強調色',
|
'settings.theme.accent': '標籤強調色',
|
||||||
'settings.theme.accentDesc': '作用中標籤的邊框、側邊欄指示條與 SSH 徽章的強調顏色',
|
'settings.theme.accentDesc': '作用中標籤的邊框、側邊欄指示條與 SSH 徽章的強調顏色',
|
||||||
'settings.theme.customBadge': '自訂',
|
'settings.theme.customBadge': '自訂',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const ssh: Record<string, string> = {
|
|||||||
'ssh.fields.askPasswordLabel': '連線時詢問密碼',
|
'ssh.fields.askPasswordLabel': '連線時詢問密碼',
|
||||||
'ssh.fields.askPasswordHint': '開啟後每次連線彈出對話框輸入密碼,不再使用已儲存的密碼',
|
'ssh.fields.askPasswordHint': '開啟後每次連線彈出對話框輸入密碼,不再使用已儲存的密碼',
|
||||||
'ssh.fields.passwordPlaceholder': '編輯時留空表示保留已儲存的密碼',
|
'ssh.fields.passwordPlaceholder': '編輯時留空表示保留已儲存的密碼',
|
||||||
'ssh.fields.keyPath': '私鑰路徑(伺服器上的本機私鑰路徑,可留空)',
|
'ssh.fields.keyPath': '私鑰檔案路徑(本機路徑,可留空)',
|
||||||
'ssh.fields.keyContent': '私鑰內容',
|
'ssh.fields.keyContent': '私鑰內容',
|
||||||
'ssh.fields.keyContentPlaceholder':
|
'ssh.fields.keyContentPlaceholder':
|
||||||
'貼上私鑰內容;留空則使用上面的路徑(編輯時留空表示保留已儲存的私鑰)',
|
'貼上私鑰內容;留空則使用上面的路徑(編輯時留空表示保留已儲存的私鑰)',
|
||||||
@@ -94,6 +94,8 @@ const ssh: Record<string, string> = {
|
|||||||
'ssh.file.up': '上一層',
|
'ssh.file.up': '上一層',
|
||||||
'ssh.file.refresh': '重新整理',
|
'ssh.file.refresh': '重新整理',
|
||||||
'ssh.file.uploadFile': '上傳檔案',
|
'ssh.file.uploadFile': '上傳檔案',
|
||||||
|
'ssh.file.overwriteTitle': '覆蓋已存在的檔案?',
|
||||||
|
'ssh.file.overwriteDesc': '目標目錄已存在同名檔案,上傳將覆蓋其內容。',
|
||||||
'ssh.file.downloadSelected': '下載選取項目',
|
'ssh.file.downloadSelected': '下載選取項目',
|
||||||
'ssh.file.permOwner': '權限 / 擁有者',
|
'ssh.file.permOwner': '權限 / 擁有者',
|
||||||
'ssh.file.open': '開啟',
|
'ssh.file.open': '開啟',
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ const DICTS: Record<Language, Dict> = {
|
|||||||
ja
|
ja
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Own-property read: dictionary literals would otherwise answer `constructor`,
|
||||||
|
* `toString`, … straight out of Object.prototype and then throw in replace(). */
|
||||||
|
function lookup(dict: Dict, key: string): string | undefined {
|
||||||
|
return Object.prototype.hasOwnProperty.call(dict, key) ? dict[key] : undefined
|
||||||
|
}
|
||||||
|
|
||||||
let current: Language = DEFAULT_LANGUAGE
|
let current: Language = DEFAULT_LANGUAGE
|
||||||
const listeners = new Set<(lang: Language) => void>()
|
const listeners = new Set<(lang: Language) => void>()
|
||||||
|
|
||||||
@@ -75,7 +81,7 @@ export function onLanguageChange(cb: (lang: Language) => void): () => void {
|
|||||||
|
|
||||||
/** Translate `key`; `{name}` placeholders are filled from `vars`. */
|
/** Translate `key`; `{name}` placeholders are filled from `vars`. */
|
||||||
export function t(key: string, vars?: Record<string, string | number>): string {
|
export function t(key: string, vars?: Record<string, string | number>): string {
|
||||||
const raw = DICTS[current][key] ?? DICTS[DEFAULT_LANGUAGE][key] ?? key
|
const raw = lookup(DICTS[current], key) ?? lookup(DICTS[DEFAULT_LANGUAGE], key) ?? key
|
||||||
if (!vars) return raw
|
if (!vars) return raw
|
||||||
return raw.replace(/\{(\w+)\}/g, (match, name: string) =>
|
return raw.replace(/\{(\w+)\}/g, (match, name: string) =>
|
||||||
vars[name] === undefined ? match : String(vars[name])
|
vars[name] === undefined ? match : String(vars[name])
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ export const Ipc = {
|
|||||||
UPDATE_DOWNLOAD: 'update:download',
|
UPDATE_DOWNLOAD: 'update:download',
|
||||||
UPDATE_INSTALL: 'update:install',
|
UPDATE_INSTALL: 'update:install',
|
||||||
UPDATE_CHANGELOG: 'update:changelog',
|
UPDATE_CHANGELOG: 'update:changelog',
|
||||||
|
/** renderer pulls the current updater state without triggering a check */
|
||||||
|
UPDATE_STATE_GET: 'update:stateGet',
|
||||||
/** main -> renderer broadcast: UpdateState */
|
/** main -> renderer broadcast: UpdateState */
|
||||||
UPDATE_STATE: 'update:state',
|
UPDATE_STATE: 'update:state',
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user