feat(desktop): add macOS dock badge for chats with unseen activity

Show a count of chats (root sessions) with unseen activity on the macOS
dock icon. The count is computed in the existing tray snapshot (full
cross-project list, not the capped tray view; a subtask's unseen rolls up
to its root only when subtask notifications are enabled) and pushed to the
main process over the existing desktop_tray_update IPC, which calls
app.setBadgeCount (0 clears it). The badge clears as sessions are marked
seen on window focus.

Add a Dock badge toggle in Appearance settings (default on, persisted,
darwin desktop only), localized across all dictionaries, with a matching
settings-search entry whose availability mirrors the render guard exactly.
This commit is contained in:
Bohdan Triapitsyn
2026-06-28 01:07:52 +03:00
parent 00efd8cc4b
commit 84d7303346
16 changed files with 129 additions and 3 deletions
@@ -1606,6 +1606,8 @@ export const settingsDict = {
'settings.openchamber.visual.actions.reloadingThemes': 'Reloading themes...',
'settings.openchamber.visual.field.macVibrancy': 'Window transparency',
'settings.openchamber.visual.field.macVibrancyHint': 'Use the native macOS blur (vibrancy) behind the sidebar. Turn off for fully solid, opaque surfaces.',
'settings.openchamber.visual.field.dockBadge': 'Dock badge',
'settings.openchamber.visual.field.dockBadgeHint': 'Show a count of chats with unseen activity on the macOS dock icon.',
'settings.openchamber.visual.actions.saveAndRestart': 'Save & restart',
'settings.openchamber.visual.actions.restarting': 'Restarting…',
'settings.openchamber.visual.field.themeImportInfoAria': 'Theme import info',
@@ -1572,6 +1572,8 @@ export const settingsDict = {
"settings.openchamber.visual.actions.reloadThemes": "Recargar temas",
"settings.openchamber.visual.field.macVibrancy": "Transparencia de la ventana",
"settings.openchamber.visual.field.macVibrancyHint": "Usa el desenfoque nativo de macOS (vibrancy) detrás de la barra lateral. Desactívalo para superficies totalmente sólidas y opacas.",
"settings.openchamber.visual.field.dockBadge": "Insignia en el Dock",
"settings.openchamber.visual.field.dockBadgeHint": "Muestra en el icono del Dock de macOS el número de chats con actividad sin ver.",
"settings.openchamber.visual.actions.saveAndRestart": "Guardar y reiniciar",
"settings.openchamber.visual.actions.restarting": "Reiniciando…",
"settings.openchamber.visual.actions.reloadingThemes": "Recargando temas...",
@@ -1762,6 +1762,8 @@ export const settingsDict = {
'settings.openchamber.visual.option.mobileLayout.new': 'Nouvelle',
'settings.openchamber.visual.field.macVibrancy': 'Transparence de la fenêtre',
'settings.openchamber.visual.field.macVibrancyHint': 'Utiliser le flou macOS natif (vibrancy) derrière la barre latérale. Désactivez cette option pour des surfaces entièrement opaques.',
'settings.openchamber.visual.field.dockBadge': 'Badge du Dock',
'settings.openchamber.visual.field.dockBadgeHint': 'Afficher sur licône du Dock de macOS le nombre de discussions avec une activité non vue.',
'settings.openchamber.visual.actions.saveAndRestart': 'Enregistrer et redémarrer',
'settings.openchamber.visual.actions.restarting': 'Redémarrage…',
'settings.openchamber.visual.field.fileEditorKeymap': 'Keymap de l’éditeur de fichiers',
@@ -1606,6 +1606,8 @@ export const settingsDict = {
'settings.openchamber.visual.actions.reloadingThemes': 'テーマを再読み込み中...',
'settings.openchamber.visual.field.macVibrancy': 'ウィンドウ透過',
'settings.openchamber.visual.field.macVibrancyHint': 'サイドバーの背後に macOS ネイティブのぼかし(Vibrancy)を使用します。完全に不透明なサーフェスにする場合はオフにします。',
'settings.openchamber.visual.field.dockBadge': 'Dock バッジ',
'settings.openchamber.visual.field.dockBadgeHint': '未読のアクティビティがあるチャットの数を macOS の Dock アイコンに表示します。',
'settings.openchamber.visual.actions.saveAndRestart': '保存して再起動',
'settings.openchamber.visual.actions.restarting': '再起動中...',
'settings.openchamber.visual.field.themeImportInfoAria': 'テーマインポート情報',
@@ -1572,6 +1572,8 @@ export const settingsDict = {
'settings.openchamber.visual.actions.reloadThemes': '테마 다시 로드',
'settings.openchamber.visual.field.macVibrancy': '창 투명도',
'settings.openchamber.visual.field.macVibrancyHint': '사이드바 뒤에 macOS 기본 블러(vibrancy)를 사용합니다. 완전히 불투명한 표면을 원하면 끄세요.',
'settings.openchamber.visual.field.dockBadge': 'Dock 배지',
'settings.openchamber.visual.field.dockBadgeHint': '확인하지 않은 활동이 있는 채팅 수를 macOS Dock 아이콘에 표시합니다.',
'settings.openchamber.visual.actions.saveAndRestart': '저장 후 재시작',
'settings.openchamber.visual.actions.restarting': '재시작 중…',
'settings.openchamber.visual.actions.reloadingThemes': '테마 다시 로드 중...',
@@ -907,6 +907,8 @@ export const settingsDict = {
'settings.openchamber.visual.actions.reloadThemes': 'Przeładuj motywy',
'settings.openchamber.visual.field.macVibrancy': 'Przezroczystość okna',
'settings.openchamber.visual.field.macVibrancyHint': 'Używaj natywnego rozmycia macOS (vibrancy) za panelem bocznym. Wyłącz, aby uzyskać w pełni nieprzezroczyste powierzchnie.',
'settings.openchamber.visual.field.dockBadge': 'Plakietka w Docku',
'settings.openchamber.visual.field.dockBadgeHint': 'Pokazuj na ikonie w Docku macOS liczbę czatów z nieprzeczytaną aktywnością.',
'settings.openchamber.visual.actions.saveAndRestart': 'Zapisz i uruchom ponownie',
'settings.openchamber.visual.actions.restarting': 'Ponowne uruchamianie…',
'settings.openchamber.visual.actions.reloadingThemes': 'Przeładowywanie motywów...',
@@ -1572,6 +1572,8 @@ export const settingsDict = {
"settings.openchamber.visual.actions.reloadThemes": "Recarregar temas",
"settings.openchamber.visual.field.macVibrancy": "Transparência da janela",
"settings.openchamber.visual.field.macVibrancyHint": "Usa o desfoque nativo do macOS (vibrancy) atrás da barra lateral. Desative para superfícies totalmente sólidas e opacas.",
"settings.openchamber.visual.field.dockBadge": "Selo no Dock",
"settings.openchamber.visual.field.dockBadgeHint": "Mostra no ícone do Dock do macOS o número de conversas com atividade não vista.",
"settings.openchamber.visual.actions.saveAndRestart": "Salvar e reiniciar",
"settings.openchamber.visual.actions.restarting": "Reiniciando…",
"settings.openchamber.visual.actions.reloadingThemes": "Recarregando temas...",
@@ -1572,6 +1572,8 @@ export const settingsDict = {
"settings.openchamber.visual.actions.reloadThemes": "Перезавантажити теми",
"settings.openchamber.visual.field.macVibrancy": "Прозорість вікна",
"settings.openchamber.visual.field.macVibrancyHint": "Використовувати нативне розмиття macOS (vibrancy) під сайдбаром. Вимкніть для повністю непрозорих поверхонь.",
"settings.openchamber.visual.field.dockBadge": "Лічильник у доку",
"settings.openchamber.visual.field.dockBadgeHint": "Показувати на іконці в доку кількість чатів із непрочитаною активністю.",
"settings.openchamber.visual.actions.saveAndRestart": "Зберегти та перезапустити",
"settings.openchamber.visual.actions.restarting": "Перезапуск…",
"settings.openchamber.visual.actions.reloadingThemes": "Перезавантаження тем...",
@@ -1572,6 +1572,8 @@ export const settingsDict = {
'settings.openchamber.visual.actions.reloadThemes': '重新加载主题',
'settings.openchamber.visual.field.macVibrancy': '窗口透明度',
'settings.openchamber.visual.field.macVibrancyHint': '在侧边栏后使用 macOS 原生模糊(vibrancy)。关闭以获得完全不透明的界面。',
'settings.openchamber.visual.field.dockBadge': 'Dock 角标',
'settings.openchamber.visual.field.dockBadgeHint': '在 macOS Dock 图标上显示有未读动态的会话数量。',
'settings.openchamber.visual.actions.saveAndRestart': '保存并重启',
'settings.openchamber.visual.actions.restarting': '正在重启…',
'settings.openchamber.visual.actions.reloadingThemes': '正在重新加载主题...',
@@ -1491,6 +1491,8 @@
'settings.openchamber.visual.actions.reloadThemes': '重新載入主題',
'settings.openchamber.visual.field.macVibrancy': '視窗透明度',
'settings.openchamber.visual.field.macVibrancyHint': '在側邊欄後使用 macOS 原生模糊(vibrancy)。關閉以獲得完全不透明的介面。',
'settings.openchamber.visual.field.dockBadge': 'Dock 標記',
'settings.openchamber.visual.field.dockBadgeHint': '在 macOS Dock 圖示上顯示有未讀動態的對話數量。',
'settings.openchamber.visual.actions.saveAndRestart': '儲存並重新啟動',
'settings.openchamber.visual.actions.restarting': '正在重新啟動…',
'settings.openchamber.visual.actions.reloadingThemes': '正在重新載入主題...',
+12
View File
@@ -20,6 +20,8 @@ export interface SettingsSearchResult extends SettingsSearchItem {
interface SettingsSearchAvailabilityContext extends SettingsRuntimeContext {
isMobile: boolean;
isDesktopLocalOrigin: boolean;
// macOS desktop shell — for controls that only render on darwin (e.g. dock badge).
isMac: boolean;
}
const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
@@ -65,6 +67,16 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
keywords: ['transparent', 'transparency', 'vibrancy', 'blur', 'macos', 'opaque'],
isAvailable: (ctx) => ctx.isDesktopLocalOrigin,
},
{
id: 'appearance.dock-badge',
page: 'appearance',
titleKey: 'settings.openchamber.visual.field.dockBadge',
descriptionKey: 'settings.openchamber.visual.field.dockBadgeHint',
keywords: ['dock', 'badge', 'unread', 'unseen', 'counter', 'count', 'notification', 'macos'],
// Exactly matches the render guard in OpenChamberVisualSettings: any darwin
// Electron shell (isMac already implies isDesktopShell), local or remote host.
isAvailable: (ctx) => ctx.isMac,
},
{
id: 'appearance.pwa-install-name',
page: 'appearance',