Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

### Added
- **Windows tray popover, settings and Capacity Dock follow the shared language.** The surfaces #1608 left in English (the popover, General settings, and the Capacity Dock window) use the macOS menu bar catalogs, including Traditional Chinese. Settings → General → Language writes the same `language` key in `~/.config/codeburn/config.json` that the desktop app writes, and a change made in either app is picked up while the tray is running. (#1646)

## 0.9.27 - 2026-10-11

### Added
Expand Down
46 changes: 46 additions & 0 deletions tests/menubar-i18n.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { readFileSync } from 'node:fs'
import { describe, expect, it } from 'vitest'

import { applyLanguage, formatTemplate, normalizeLocale, t } from '../windows/src/i18n/index'

function parseStrings(file: string): Record<string, string> {
const text = readFileSync(file, 'utf8')
const map: Record<string, string> = {}
const re = /"((?:\\.|[^"\\])*)"\s*=\s*"((?:\\.|[^"\\])*)"\s*;/g
const unescape = (s: string) => s.replace(/\\n/g, '\n').replace(/\\"/g, '"').replace(/\\\\/g, '\\')
let match: RegExpExecArray | null
while ((match = re.exec(text))) map[unescape(match[1]!)] = unescape(match[2]!)
return map
}

describe('menubar locale', () => {
it('maps Chinese OS tags the way the macOS app does', () => {
expect(normalizeLocale('zh-CN')).toBe('zh-Hans')
expect(normalizeLocale('zh_TW.UTF-8')).toBe('zh-Hant')
expect(normalizeLocale('zh-HK')).toBe('zh-Hant')
expect(normalizeLocale('fr-CA')).toBe('fr')
expect(normalizeLocale('de-DE')).toBeNull()
})

it('fills positional and sequential placeholders', () => {
expect(formatTemplate('%1$@ · %2$lld', ['今天', 2])).toBe('今天 · 2')
expect(formatTemplate('%lld sessions', [3])).toBe('3 sessions')
expect(formatTemplate('100%%', [])).toBe('100%')
})

it('renders the popover in simplified Chinese', () => {
applyLanguage('zh-Hans', 'en-US')
expect(t('Your AI Bill, Itemized')).toBe('你的 AI 账单,逐项明细')
expect(t('Open Full Report')).toBe('打开完整报告')
expect(t('Today')).toBe('今天')
expect(t('%lld sessions', 3)).toBe('3 个会话')
applyLanguage('en', 'en-US')
expect(t('Open Full Report')).toBe('Open Full Report')
})

it('keeps the generated mac catalog in step with Localizable.strings', () => {
const generated = JSON.parse(readFileSync('windows/src/i18n/mac-catalog.json', 'utf8')) as Record<string, Record<string, string>>
const zh = parseStrings('mac/Sources/CodeBurnMenubar/Resources/zh-Hans.lproj/Localizable.strings')
expect(generated['zh-Hans']).toEqual(zh)
})
})
1 change: 1 addition & 0 deletions windows/src-tauri/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"Today · no usage yet": "Today · no usage yet",
"Top": "Top",
"Week": "Week",
"Show today's cost in tray": "Show today's cost in tray",
"Updating the CLI...": "Updating the CLI...",
"CLI updated to %@.": "CLI updated to %@.",
"The CLI is up to date.": "The CLI is up to date.",
Expand Down
47 changes: 47 additions & 0 deletions windows/src-tauri/locales/fr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"%@ · no usage yet": "%@ · pas encore d'utilisation",
"%1$lld of %2$lld devices": "%1$lld appareil(s) sur %2$lld",
"%lld calls": "%lld appels",
"1 call": "1 appel",
"6 Months": "6 mois",
"About CodeBurn": "À propos de CodeBurn",
"Bottom": "Bas",
"Capacity Dock Settings…": "Réglages du Capacity Dock…",
"Check for Updates": "Rechercher des mises à jour",
"CodeBurn %1$@ · %2$lld of %3$lld devices reporting": "CodeBurn %1$@ · %2$lld appareil(s) sur %3$lld actif(s)",
"Dock to Edge": "Ancrer au bord",
"Hide Capacity Dock": "Masquer le Capacity Dock",
"Language": "Langue",
"Left": "Gauche",
"Month": "Mois",
"Open CodeBurn": "Ouvrir CodeBurn",
"Open Full Report": "Ouvrir le rapport complet",
"Quit CodeBurn": "Quitter CodeBurn",
"Refresh": "Actualiser",
"Right": "Droite",
"Settings…": "Réglages…",
"Show Capacity Dock": "Afficher le Capacity Dock",
"Switch to Dark Theme": "Passer au thème sombre",
"Switch to Light Theme": "Passer au thème clair",
"Switch to System Theme": "Passer au thème du système",
"System": "Système",
"Today": "Aujourd'hui",
"Today · %1$@ · %2$@": "Aujourd'hui · %1$@ · %2$@",
"Today · no usage yet": "Aujourd'hui · aucun usage",
"Top": "Haut",
"Week": "Semaine",
"Show today's cost in tray": "Afficher le coût du jour dans la zone de notification",
"Updating the CLI...": "Mise à jour de la CLI...",
"CLI updated to %@.": "CLI mise à jour vers %@.",
"The CLI is up to date.": "La CLI est à jour.",
"No global CLI found.": "Aucune CLI globale trouvée.",
"Another CodeBurn update is already running.": "Une autre mise à jour de CodeBurn est déjà en cours.",
"CLI %@ is not on npm yet. Try again in a few minutes.": "La CLI %@ n'est pas encore sur npm. Réessayez dans quelques minutes.",
"CodeBurn is not allowed to change the CLI folder. Run this in a terminal:": "CodeBurn n'est pas autorisé à modifier le dossier de la CLI. Exécutez ceci dans un terminal :",
"CodeBurn could not tell how the CLI was installed. Run this in a terminal:": "CodeBurn n'a pas pu déterminer comment la CLI a été installée. Exécutez ceci dans un terminal :",
"The CLI update failed. Run this in a terminal:": "La mise à jour de la CLI a échoué. Exécutez ceci dans un terminal :",
"The CLI update did not run. Run this in a terminal:": "La mise à jour de la CLI ne s'est pas exécutée. Exécutez ceci dans un terminal :",
"Your package manager updates this CLI.": "Votre gestionnaire de paquets met à jour cette CLI.",
"Opening CodeBurn to update the desktop app.": "Ouverture de CodeBurn pour mettre à jour l'application de bureau.",
"Update CLI": "Mettre à jour la CLI"
}
47 changes: 47 additions & 0 deletions windows/src-tauri/locales/ja.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"%@ · no usage yet": "%@ · まだ使用量がありません",
"%1$lld of %2$lld devices": "%1$lld/%2$lld台のデバイス",
"%lld calls": "%lld回の呼び出し",
"1 call": "1回の呼び出し",
"6 Months": "6か月間",
"About CodeBurn": "CodeBurnについて",
"Bottom": "下",
"Capacity Dock Settings…": "容量ドック設定…",
"Check for Updates": "更新を確認",
"CodeBurn %1$@ · %2$lld of %3$lld devices reporting": "CodeBurn %1$@ · %2$lld/%3$lld台のデバイスが報告中",
"Dock to Edge": "画面端にドッキング",
"Hide Capacity Dock": "容量ドックを隠す",
"Language": "言語",
"Left": "左",
"Month": "今月",
"Open CodeBurn": "CodeBurn を開く",
"Open Full Report": "完全なレポートを開く",
"Quit CodeBurn": "CodeBurnを終了",
"Refresh": "更新",
"Right": "右",
"Settings…": "設定…",
"Show Capacity Dock": "容量ドックを表示",
"Switch to Dark Theme": "ダークテーマに切り替える",
"Switch to Light Theme": "ライトテーマに切り替える",
"Switch to System Theme": "システムテーマに切り替える",
"System": "システムに従う",
"Today": "今日",
"Today · %1$@ · %2$@": "今日 · %1$@ · %2$@",
"Today · no usage yet": "今日 · 使用量なし",
"Top": "上",
"Week": "今週",
"Show today's cost in tray": "今日の費用をトレイに表示",
"Updating the CLI...": "CLI を更新しています...",
"CLI updated to %@.": "CLI を %@ に更新しました。",
"The CLI is up to date.": "CLI は最新です。",
"No global CLI found.": "グローバル CLI が見つかりません。",
"Another CodeBurn update is already running.": "別の CodeBurn 更新がすでに実行中です。",
"CLI %@ is not on npm yet. Try again in a few minutes.": "CLI %@ はまだ npm にありません。数分後にもう一度お試しください。",
"CodeBurn is not allowed to change the CLI folder. Run this in a terminal:": "CodeBurn には CLI フォルダーを変更する権限がありません。ターミナルでこれを実行してください:",
"CodeBurn could not tell how the CLI was installed. Run this in a terminal:": "CodeBurn は CLI のインストール方法を判別できませんでした。ターミナルでこれを実行してください:",
"The CLI update failed. Run this in a terminal:": "CLI の更新に失敗しました。ターミナルでこれを実行してください:",
"The CLI update did not run. Run this in a terminal:": "CLI の更新は実行されませんでした。ターミナルでこれを実行してください:",
"Your package manager updates this CLI.": "この CLI はパッケージマネージャーが更新します。",
"Opening CodeBurn to update the desktop app.": "デスクトップアプリを更新するため CodeBurn を開いています。",
"Update CLI": "CLI を更新"
}
47 changes: 47 additions & 0 deletions windows/src-tauri/locales/ko.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"%@ · no usage yet": "%@ · 아직 사용량 없음",
"%1$lld of %2$lld devices": "%1$lld/%2$lld대 기기",
"%lld calls": "%lld회 호출",
"1 call": "1회 호출",
"6 Months": "6개월",
"About CodeBurn": "CodeBurn 정보",
"Bottom": "아래쪽",
"Capacity Dock Settings…": "캐퍼시티 독 설정…",
"Check for Updates": "업데이트 확인",
"CodeBurn %1$@ · %2$lld of %3$lld devices reporting": "CodeBurn %1$@ · %2$lld/%3$lld대 기기 보고 중",
"Dock to Edge": "화면 가장자리에 고정",
"Hide Capacity Dock": "캐퍼시티 독 숨기기",
"Language": "언어",
"Left": "왼쪽",
"Month": "이번 달",
"Open CodeBurn": "CodeBurn 열기",
"Open Full Report": "전체 보고서 열기",
"Quit CodeBurn": "CodeBurn 종료",
"Refresh": "새로고침",
"Right": "오른쪽",
"Settings…": "설정…",
"Show Capacity Dock": "캐퍼시티 독 표시",
"Switch to Dark Theme": "어두운 테마로 전환",
"Switch to Light Theme": "밝은 테마로 전환",
"Switch to System Theme": "시스템 테마로 전환",
"System": "시스템 설정 따름",
"Today": "오늘",
"Today · %1$@ · %2$@": "오늘 · %1$@ · %2$@",
"Today · no usage yet": "오늘 · 아직 사용량 없음",
"Top": "위쪽",
"Week": "이번 주",
"Show today's cost in tray": "오늘 비용을 트레이에 표시",
"Updating the CLI...": "CLI 업데이트 중...",
"CLI updated to %@.": "CLI가 %@로 업데이트되었습니다.",
"The CLI is up to date.": "CLI가 최신 버전입니다.",
"No global CLI found.": "전역 CLI를 찾을 수 없습니다.",
"Another CodeBurn update is already running.": "다른 CodeBurn 업데이트가 이미 실행 중입니다.",
"CLI %@ is not on npm yet. Try again in a few minutes.": "CLI %@이(가) 아직 npm에 없습니다. 몇 분 후에 다시 시도하세요.",
"CodeBurn is not allowed to change the CLI folder. Run this in a terminal:": "CodeBurn이 CLI 폴더를 변경할 수 없습니다. 터미널에서 다음을 실행하세요:",
"CodeBurn could not tell how the CLI was installed. Run this in a terminal:": "CodeBurn이 CLI 설치 방법을 알 수 없습니다. 터미널에서 다음을 실행하세요:",
"The CLI update failed. Run this in a terminal:": "CLI 업데이트에 실패했습니다. 터미널에서 다음을 실행하세요:",
"The CLI update did not run. Run this in a terminal:": "CLI 업데이트가 실행되지 않았습니다. 터미널에서 다음을 실행하세요:",
"Your package manager updates this CLI.": "이 CLI는 패키지 관리자가 업데이트합니다.",
"Opening CodeBurn to update the desktop app.": "데스크톱 앱을 업데이트하기 위해 CodeBurn을 여는 중입니다.",
"Update CLI": "CLI 업데이트"
}
1 change: 1 addition & 0 deletions windows/src-tauri/locales/zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"Today · no usage yet": "今天 · 暂无用量",
"Top": "顶部",
"Week": "本周",
"Show today's cost in tray": "在托盘显示今日花费",
"Updating the CLI...": "正在更新 CLI...",
"CLI updated to %@.": "CLI 已更新到 %@。",
"The CLI is up to date.": "CLI 已是最新版本。",
Expand Down
47 changes: 47 additions & 0 deletions windows/src-tauri/locales/zh-Hant.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"%@ · no usage yet": "%@ · 暫無用量",
"%1$lld of %2$lld devices": "%1$lld/%2$lld 臺裝置",
"%lld calls": "%lld 次呼叫",
"1 call": "1 次呼叫",
"6 Months": "6 個月",
"About CodeBurn": "關於 CodeBurn",
"Bottom": "底部",
"Capacity Dock Settings…": "容量 Dock 設定…",
"Check for Updates": "檢查更新",
"CodeBurn %1$@ · %2$lld of %3$lld devices reporting": "CodeBurn %1$@ · %2$lld/%3$lld 臺裝置已上報",
"Dock to Edge": "停靠到邊緣",
"Hide Capacity Dock": "隱藏容量 Dock",
"Language": "語言",
"Left": "左側",
"Month": "本月",
"Open CodeBurn": "開啟 CodeBurn",
"Open Full Report": "開啟完整報告",
"Quit CodeBurn": "退出 CodeBurn",
"Refresh": "重新整理",
"Right": "右側",
"Settings…": "設定…",
"Show Capacity Dock": "顯示容量 Dock",
"Switch to Dark Theme": "切換到深色主題",
"Switch to Light Theme": "切換到淺色主題",
"Switch to System Theme": "切換到系統主題",
"System": "跟隨系統",
"Today": "今天",
"Today · %1$@ · %2$@": "今天 · %1$@ · %2$@",
"Today · no usage yet": "今天 · 暫無用量",
"Top": "頂部",
"Week": "本週",
"Show today's cost in tray": "在托盤顯示今日花費",
"Updating the CLI...": "正在更新 CLI...",
"CLI updated to %@.": "CLI 已更新到 %@。",
"The CLI is up to date.": "CLI 已是最新版本。",
"No global CLI found.": "未找到全域 CLI。",
"Another CodeBurn update is already running.": "另一個 CodeBurn 更新正在執行。",
"CLI %@ is not on npm yet. Try again in a few minutes.": "CLI %@ 尚未發佈到 npm。請幾分鐘後重試。",
"CodeBurn is not allowed to change the CLI folder. Run this in a terminal:": "CodeBurn 無權變更 CLI 所在資料夾。請在終端機中執行:",
"CodeBurn could not tell how the CLI was installed. Run this in a terminal:": "CodeBurn 無法判斷 CLI 的安裝方式。請在終端機中執行:",
"The CLI update failed. Run this in a terminal:": "CLI 更新失敗。請在終端機中執行:",
"The CLI update did not run. Run this in a terminal:": "CLI 更新未能執行。請在終端機中執行:",
"Your package manager updates this CLI.": "此 CLI 由你的套件管理器更新。",
"Opening CodeBurn to update the desktop app.": "正在開啟 CodeBurn 以更新桌面應用程式。",
"Update CLI": "更新 CLI"
}
Loading