From 3dfd692d755ed64ac43251ab13c240f8bfa9d34a Mon Sep 17 00:00:00 2001 From: Frank Song Date: Sat, 9 May 2026 10:03:27 +0800 Subject: [PATCH] Localize session jump controls --- CHANGELOG.md | 10 +++ static/i18n.js | 104 ++++++++++++++--------------- tests/test_session_jump_buttons.py | 19 +++--- 3 files changed, 73 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eeaa0e04..fe333df1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Hermes Web UI -- Changelog +## Unreleased + +### Fixed + +- **Session jump button locale parity** — localized the opt-in Start/End + session jump labels, aria labels, and Appearance setting copy for + ja/ru/es/de/zh/zh-Hant/pt/ko instead of leaving English fallbacks in + otherwise localized UIs. (`static/i18n.js`, + `tests/test_session_jump_buttons.py`) Closes #1938. + ## [v0.51.30] — 2026-05-08 — 3-PR contributor batch (Release G: offline recovery + PWA hardening + opt-in session jump buttons + opt-in endless-scroll) ### Added (3 PRs, all from @ai-ag2026) diff --git a/static/i18n.js b/static/i18n.js index 8b86a209..16a3b33e 100644 --- a/static/i18n.js +++ b/static/i18n.js @@ -1170,10 +1170,10 @@ const LOCALES = { untitled: '無題', n_messages: (n) => `${n} 件のメッセージ`, load_older_messages: '↑ 上にスクロール、またはクリックして過去のメッセージを読み込む', - session_jump_start: 'Start', - session_jump_start_label: 'Jump to beginning of session', - session_jump_end: 'End', - session_jump_end_label: 'Jump to end of session', + session_jump_start: '開始', + session_jump_start_label: 'セッションの先頭へ移動', + session_jump_end: '末尾', + session_jump_end_label: 'セッションの末尾へ移動', queued_label: '応答後に送信', queued_count: (n) => `${n} 件キュー中`, queued_cancel: 'キューに入れたメッセージをキャンセル', @@ -1470,8 +1470,8 @@ const LOCALES = { settings_updates_disabled: 'アップデート確認は無効です', settings_label_workspace_panel_open: 'ワークスペースパネルをデフォルトで開いておく', settings_desc_workspace_panel_open: '有効にすると、新しいセッションごとにワークスペース/ファイルブラウザパネルが自動で開きます。手動でいつでも閉じられます。', - settings_label_session_jump_buttons: 'Show session jump buttons', - settings_desc_session_jump_buttons: 'Show floating Start and End buttons while reading long session histories.', + settings_label_session_jump_buttons: 'セッションジャンプボタンを表示', + settings_desc_session_jump_buttons: '長いセッション履歴を読むときに、浮動表示の「開始」と「末尾」ボタンを表示します。', settings_label_session_endless_scroll: '上スクロールで古いメッセージを読み込む', @@ -2186,10 +2186,10 @@ const LOCALES = { untitled: 'Без названия', n_messages: (n) => `${n} сообщений`, load_older_messages: '↑ Прокрутите вверх или нажмите, чтобы загрузить ранние сообщения', - session_jump_start: 'Start', - session_jump_start_label: 'Jump to beginning of session', - session_jump_end: 'End', - session_jump_end_label: 'Jump to end of session', + session_jump_start: 'Начало', + session_jump_start_label: 'Перейти к началу сессии', + session_jump_end: 'Конец', + session_jump_end_label: 'Перейти к концу сессии', queued_label: 'Отправить после ответа', queued_count: (n) => n === 1 ? '1 в очереди' : `${n} в очереди`, queued_cancel: 'Отменить сообщение', @@ -2925,8 +2925,8 @@ const LOCALES = { settings_update_check_failed: 'Ошибка проверки обновлений', settings_label_workspace_panel_open: 'Открывать панель рабочей области по умолчанию', settings_desc_workspace_panel_open: 'При включении панель файлов будет открываться автоматически в каждой новой сессии.', - settings_label_session_jump_buttons: 'Show session jump buttons', - settings_desc_session_jump_buttons: 'Show floating Start and End buttons while reading long session histories.', + settings_label_session_jump_buttons: 'Показывать кнопки перехода по сессии', + settings_desc_session_jump_buttons: 'Показывать плавающие кнопки «Начало» и «Конец» при чтении длинных историй сессий.', settings_label_session_endless_scroll: 'Загружать старые сообщения при прокрутке вверх', @@ -3160,10 +3160,10 @@ const LOCALES = { untitled: 'Sin título', n_messages: (n) => `${n} mensajes`, load_older_messages: '↑ Desplázate hacia arriba o haz clic para cargar mensajes anteriores', - session_jump_start: 'Start', - session_jump_start_label: 'Jump to beginning of session', - session_jump_end: 'End', - session_jump_end_label: 'Jump to end of session', + session_jump_start: 'Inicio', + session_jump_start_label: 'Saltar al inicio de la sesión', + session_jump_end: 'Fin', + session_jump_end_label: 'Saltar al final de la sesión', queued_label: 'Enviar después de la respuesta', queued_count: (n) => n === 1 ? '1 en cola' : `${n} en cola`, queued_cancel: 'Cancelar mensaje en cola', @@ -3885,8 +3885,8 @@ const LOCALES = { settings_update_check_failed: 'Error al comprobar actualizaciones', settings_label_workspace_panel_open: 'Mantener panel de espacio abierto', settings_desc_workspace_panel_open: 'Al activar, el panel de archivos se abre automáticamente en cada nueva sesión. Aún puedes cerrarlo manualmente.', - settings_label_session_jump_buttons: 'Show session jump buttons', - settings_desc_session_jump_buttons: 'Show floating Start and End buttons while reading long session histories.', + settings_label_session_jump_buttons: 'Mostrar botones de salto de sesión', + settings_desc_session_jump_buttons: 'Muestra botones flotantes de Inicio y Fin al leer historiales de sesión largos.', settings_label_session_endless_scroll: 'Cargar mensajes antiguos al desplazarse hacia arriba', @@ -4130,10 +4130,10 @@ const LOCALES = { untitled: 'Unbenannt', n_messages: (n) => `${n} Nachrichten`, load_older_messages: '↑ Nach oben scrollen oder klicken, um ältere Nachrichten zu laden', - session_jump_start: 'Start', - session_jump_start_label: 'Jump to beginning of session', - session_jump_end: 'End', - session_jump_end_label: 'Jump to end of session', + session_jump_start: 'Anfang', + session_jump_start_label: 'Zum Anfang der Sitzung springen', + session_jump_end: 'Ende', + session_jump_end_label: 'Zum Ende der Sitzung springen', queued_label: 'Wird nach Antwort gesendet', queued_count: (n) => n === 1 ? '1 in Warteschlange' : `${n} in Warteschlange`, queued_cancel: 'Nachricht abbrechen', @@ -4590,8 +4590,8 @@ const LOCALES = { settings_update_check_failed: 'Update-Prüfung fehlgeschlagen', settings_label_workspace_panel_open: 'Arbeitsbereich-Panel standardmäßig öffnen', settings_desc_workspace_panel_open: 'Wenn aktiviert, wird der Datei-Browser bei jeder neuen Sitzung automatisch geöffnet. Er kann jederzeit manuell geschlossen werden.', - settings_label_session_jump_buttons: 'Show session jump buttons', - settings_desc_session_jump_buttons: 'Show floating Start and End buttons while reading long session histories.', + settings_label_session_jump_buttons: 'Sitzungs-Sprungtasten anzeigen', + settings_desc_session_jump_buttons: 'Zeigt beim Lesen langer Sitzungsverläufe schwebende Anfang- und Ende-Tasten an.', settings_label_session_endless_scroll: 'Ältere Nachrichten beim Hochscrollen laden', @@ -5104,10 +5104,10 @@ const LOCALES = { untitled: '\u672a\u547d\u540d', n_messages: (n) => `${n} \u6761\u6d88\u606f`, load_older_messages: '↑ 向上滚动或点击加载更早的消息', - session_jump_start: 'Start', - session_jump_start_label: 'Jump to beginning of session', - session_jump_end: 'End', - session_jump_end_label: 'Jump to end of session', + session_jump_start: '开头', + session_jump_start_label: '跳转到会话开头', + session_jump_end: '结尾', + session_jump_end_label: '跳转到会话结尾', queued_label: '响应后发送', queued_count: (n) => n === 1 ? '1 条排队' : `${n} 条排队`, queued_cancel: '取消排队消息', @@ -5826,8 +5826,8 @@ const LOCALES = { settings_update_check_failed: '更新检查失败', settings_label_workspace_panel_open: '默认保持工作区面板打开', settings_desc_workspace_panel_open: '启用后,工作区/文件浏览器面板会在每次新会话时自动打开。您仍可随时手动关闭。', - settings_label_session_jump_buttons: 'Show session jump buttons', - settings_desc_session_jump_buttons: 'Show floating Start and End buttons while reading long session histories.', + settings_label_session_jump_buttons: '显示会话跳转按钮', + settings_desc_session_jump_buttons: '阅读较长会话历史时显示悬浮的开头和结尾按钮。', settings_label_session_endless_scroll: '向上滚动时加载更早的消息', @@ -6066,10 +6066,10 @@ const LOCALES = { untitled: '\u672a\u547d\u540d', n_messages: (n) => `${n} \u689d\u8a0a\u606f`, load_older_messages: '↑ 向上捲動或點擊以載入較早的訊息', - session_jump_start: 'Start', - session_jump_start_label: 'Jump to beginning of session', - session_jump_end: 'End', - session_jump_end_label: 'Jump to end of session', + session_jump_start: '開頭', + session_jump_start_label: '跳至會話開頭', + session_jump_end: '結尾', + session_jump_end_label: '跳至會話結尾', model_unavailable: '\uff08\u4e0d\u53ef\u7528\uff09', model_unavailable_title: '\u6b64\u6a21\u578b\u5df2\u7d93\u4e0d\u5728\u7576\u524d provider \u5217\u8868\u4e2d', provider_mismatch_warning: (m,p)=>`\"${m}\" \u53ef\u80fd\u7121\u6cd5\u5728\u7576\u524d\u914d\u7f6e\u7684\u63d0\u4f9b\u8005 (${p}) \u4e0b\u904b\u4f5c\u3002\u5c1a\u9001\uff0c\u6216\u5728\u7d42\u7aef\u57f7\u884c \`hermes model\` \u5207\u63db\u3002`, @@ -6242,8 +6242,8 @@ const LOCALES = { settings_update_check_failed: '更新檢查失敗', settings_label_workspace_panel_open: '預設保持工作區面板開啓', settings_desc_workspace_panel_open: '啟用後,工作區/檔案瀏覽器面板會在每次新會話時自動開啓。您仍可隨時手動關閉。', - settings_label_session_jump_buttons: 'Show session jump buttons', - settings_desc_session_jump_buttons: 'Show floating Start and End buttons while reading long session histories.', + settings_label_session_jump_buttons: '顯示會話跳轉按鈕', + settings_desc_session_jump_buttons: '閱讀較長會話歷史時顯示浮動的開頭與結尾按鈕。', settings_label_session_endless_scroll: '向上捲動時載入較早訊息', @@ -6400,10 +6400,10 @@ const LOCALES = { downloading: (filename) => `正在下載 ${filename}…`, n_messages: (n) => `${n} 則訊息`, load_older_messages: '↑ 向上捲動或點擊以載入較早的訊息', - session_jump_start: 'Start', - session_jump_start_label: 'Jump to beginning of session', - session_jump_end: 'End', - session_jump_end_label: 'Jump to end of session', + session_jump_start: '開頭', + session_jump_start_label: '跳至會話開頭', + session_jump_end: '結尾', + session_jump_end_label: '跳至會話結尾', onboarding_api_key_help_prefix: '\u900f\u904e\u4ee5\u4e0b\u65b9\u5f0f\u5132\u5b58\u70ba Hermes .env \u6a94\u6848\u4e2d\u7684\u6a5f\u5bc6', onboarding_api_key_label: 'API \u91d1\u9470', onboarding_api_key_placeholder: '\u7559\u7a7a\u4ee5\u4fdd\u7559\u5df2\u5132\u5b58\u7684\u91d1\u9470', @@ -7029,10 +7029,10 @@ const LOCALES = { untitled: 'Sem título', n_messages: (n) => `${n} mensagens`, load_older_messages: '↑ Role para cima ou clique para carregar mensagens mais antigas', - session_jump_start: 'Start', - session_jump_start_label: 'Jump to beginning of session', - session_jump_end: 'End', - session_jump_end_label: 'Jump to end of session', + session_jump_start: 'Início', + session_jump_start_label: 'Ir para o início da sessão', + session_jump_end: 'Fim', + session_jump_end_label: 'Ir para o fim da sessão', queued_label: 'Envia após a resposta', queued_count: (n) => n === 1 ? '1 na fila' : `${n} na fila`, queued_cancel: 'Cancelar mensagem na fila', @@ -7297,8 +7297,8 @@ const LOCALES = { settings_update_check_failed: 'Falha ao verificar updates', settings_label_workspace_panel_open: 'Manter painel workspace aberto por padrão', settings_desc_workspace_panel_open: 'Quando ativo, o painel workspace abre automaticamente com cada nova sessão.', - settings_label_session_jump_buttons: 'Show session jump buttons', - settings_desc_session_jump_buttons: 'Show floating Start and End buttons while reading long session histories.', + settings_label_session_jump_buttons: 'Mostrar botões de salto da sessão', + settings_desc_session_jump_buttons: 'Mostra botões flutuantes Início e Fim ao ler históricos longos de sessão.', settings_label_session_endless_scroll: 'Carregar mensagens antigas ao rolar para cima', @@ -7942,10 +7942,10 @@ const LOCALES = { untitled: '제목 없음', n_messages: (n) => `${n}개 메시지`, load_older_messages: '↑ 위로 스크롤하거나 클릭하여 이전 메시지 불러오기', - session_jump_start: 'Start', - session_jump_start_label: 'Jump to beginning of session', - session_jump_end: 'End', - session_jump_end_label: 'Jump to end of session', + session_jump_start: '시작', + session_jump_start_label: '세션 시작으로 이동', + session_jump_end: '끝', + session_jump_end_label: '세션 끝으로 이동', queued_label: 'Sends after response', queued_count: (n) => n === 1 ? '1 queued' : `${n} queued`, queued_cancel: 'Cancel queued message', @@ -8233,8 +8233,8 @@ const LOCALES = { settings_update_check_failed: 'Update check failed', settings_label_workspace_panel_open: '기본으로 워크스페이스 패널 열기', settings_desc_workspace_panel_open: '활성화하면 새 세션마다 워크스페이스/파일 브라우저 패널이 자동으로 열립니다. 언제든지 수동으로 닫을 수 있습니다.', - settings_label_session_jump_buttons: 'Show session jump buttons', - settings_desc_session_jump_buttons: 'Show floating Start and End buttons while reading long session histories.', + settings_label_session_jump_buttons: '세션 이동 버튼 표시', + settings_desc_session_jump_buttons: '긴 세션 기록을 읽을 때 떠 있는 시작 및 끝 버튼을 표시합니다.', settings_label_session_endless_scroll: '위로 스크롤할 때 이전 메시지 불러오기', diff --git a/tests/test_session_jump_buttons.py b/tests/test_session_jump_buttons.py index 48461eea..a0dd85d4 100644 --- a/tests/test_session_jump_buttons.py +++ b/tests/test_session_jump_buttons.py @@ -64,14 +64,17 @@ def test_session_jump_buttons_match_pill_layout_without_regressing_default_arrow def test_session_jump_buttons_are_i18n_localized_in_text_tooltip_and_aria(): - for key in [ - "session_jump_start", - "session_jump_start_label", - "session_jump_end", - "session_jump_end_label", - "settings_label_session_jump_buttons", - "settings_desc_session_jump_buttons", - ]: + english_literals = { + "session_jump_start": "Start", + "session_jump_start_label": "Jump to beginning of session", + "session_jump_end": "End", + "session_jump_end_label": "Jump to end of session", + "settings_label_session_jump_buttons": "Show session jump buttons", + "settings_desc_session_jump_buttons": "Show floating Start and End buttons while reading long session histories.", + } + for key in english_literals: assert I18N_JS.count(f"{key}:") >= 8, f"missing locale entries for {key}" + for key, value in english_literals.items(): + assert I18N_JS.count(f"{key}: '{value}'") == 1, f"non-English locale still uses English literal for {key}" assert "document.querySelectorAll('[data-i18n-aria-label]')" in I18N_JS assert "el.setAttribute('aria-label', val)" in I18N_JS