Skip to content

Commit de2e372

Browse files
committed
Implement bounce dock icon notification setting
1 parent fc4a0db commit de2e372

File tree

5 files changed

+41
-0
lines changed

5 files changed

+41
-0
lines changed

apps/twig/src/main/services/notification/service.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ export class NotificationService {
3535
log.info("Dock badge shown");
3636
}
3737

38+
bounceDock(): void {
39+
if (process.platform === "darwin") {
40+
app.dock?.bounce("informational");
41+
log.info("Dock bounce triggered");
42+
}
43+
}
44+
3845
private clearDockBadge(): void {
3946
if (!this.hasBadge) return;
4047

apps/twig/src/main/trpc/routers/notification.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ export const notificationRouter = router({
2020
getService().send(input.title, input.body, input.silent),
2121
),
2222
showDockBadge: publicProcedure.mutation(() => getService().showDockBadge()),
23+
bounceDock: publicProcedure.mutation(() => getService().bounceDock()),
2324
});

apps/twig/src/renderer/features/settings/components/sections/ChatSettings.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ export function ChatSettings() {
1414
const {
1515
desktopNotifications,
1616
dockBadgeNotifications,
17+
dockBounceNotifications,
1718
completionSound,
1819
completionVolume,
1920
autoConvertLongText,
2021
sendMessagesWith,
2122
setDesktopNotifications,
2223
setDockBadgeNotifications,
24+
setDockBounceNotifications,
2325
setCompletionSound,
2426
setCompletionVolume,
2527
setAutoConvertLongText,
@@ -90,6 +92,17 @@ export function ChatSettings() {
9092
/>
9193
</SettingRow>
9294

95+
<SettingRow
96+
label="Bounce dock icon"
97+
description="Bounce the dock icon when the agent finishes a task or needs your input"
98+
>
99+
<Switch
100+
checked={dockBounceNotifications}
101+
onCheckedChange={setDockBounceNotifications}
102+
size="1"
103+
/>
104+
</SettingRow>
105+
93106
<SettingRow
94107
label="Sound effect"
95108
description="Play a sound when the agent finishes a task or needs your input"

apps/twig/src/renderer/features/settings/stores/settingsStore.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ interface SettingsStore {
1818
lastUsedModel: string | null;
1919
desktopNotifications: boolean;
2020
dockBadgeNotifications: boolean;
21+
dockBounceNotifications: boolean;
2122
cursorGlow: boolean;
2223
autoConvertLongText: boolean;
2324
completionSound: CompletionSound;
@@ -36,6 +37,7 @@ interface SettingsStore {
3637
setLastUsedModel: (model: string) => void;
3738
setDesktopNotifications: (enabled: boolean) => void;
3839
setDockBadgeNotifications: (enabled: boolean) => void;
40+
setDockBounceNotifications: (enabled: boolean) => void;
3941
setCursorGlow: (enabled: boolean) => void;
4042
setAutoConvertLongText: (enabled: boolean) => void;
4143
setSendMessagesWith: (mode: SendMessagesWith) => void;
@@ -54,6 +56,7 @@ export const useSettingsStore = create<SettingsStore>()(
5456
lastUsedModel: null,
5557
desktopNotifications: true,
5658
dockBadgeNotifications: true,
59+
dockBounceNotifications: false,
5760
completionSound: "none",
5861
completionVolume: 80,
5962
cursorGlow: false,
@@ -75,6 +78,8 @@ export const useSettingsStore = create<SettingsStore>()(
7578
set({ desktopNotifications: enabled }),
7679
setDockBadgeNotifications: (enabled) =>
7780
set({ dockBadgeNotifications: enabled }),
81+
setDockBounceNotifications: (enabled) =>
82+
set({ dockBounceNotifications: enabled }),
7883
setCursorGlow: (enabled) => set({ cursorGlow: enabled }),
7984
setAutoConvertLongText: (enabled) =>
8085
set({ autoConvertLongText: enabled }),
@@ -96,6 +101,7 @@ export const useSettingsStore = create<SettingsStore>()(
96101
lastUsedModel: state.lastUsedModel,
97102
desktopNotifications: state.desktopNotifications,
98103
dockBadgeNotifications: state.dockBadgeNotifications,
104+
dockBounceNotifications: state.dockBounceNotifications,
99105
cursorGlow: state.cursorGlow,
100106
autoConvertLongText: state.autoConvertLongText,
101107
completionSound: state.completionSound,

apps/twig/src/renderer/lib/notifications.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ function showDockBadge(): void {
2828
});
2929
}
3030

31+
function bounceDock(): void {
32+
trpcVanilla.notification.bounceDock.mutate().catch((err) => {
33+
log.error("Failed to bounce dock", err);
34+
});
35+
}
36+
3137
export function notifyPromptComplete(
3238
taskTitle: string,
3339
stopReason: string,
@@ -39,6 +45,7 @@ export function notifyPromptComplete(
3945
completionVolume,
4046
desktopNotifications,
4147
dockBadgeNotifications,
48+
dockBounceNotifications,
4249
} = useSettingsStore.getState();
4350

4451
const isWindowFocused = document.hasFocus();
@@ -57,6 +64,9 @@ export function notifyPromptComplete(
5764
if (dockBadgeNotifications) {
5865
showDockBadge();
5966
}
67+
if (dockBounceNotifications) {
68+
bounceDock();
69+
}
6070
}
6171

6272
export function notifyPermissionRequest(taskTitle: string): void {
@@ -65,6 +75,7 @@ export function notifyPermissionRequest(taskTitle: string): void {
6575
completionVolume,
6676
desktopNotifications,
6777
dockBadgeNotifications,
78+
dockBounceNotifications,
6879
} = useSettingsStore.getState();
6980
const isWindowFocused = document.hasFocus();
7081

@@ -82,5 +93,8 @@ export function notifyPermissionRequest(taskTitle: string): void {
8293
if (dockBadgeNotifications) {
8394
showDockBadge();
8495
}
96+
if (dockBounceNotifications) {
97+
bounceDock();
98+
}
8599
}
86100
}

0 commit comments

Comments
 (0)