Skip to content

Commit 287f48b

Browse files
authored
fix: icon color when idle (#2266)
* fix: icon color when idle Signed-off-by: Adam Setch <[email protected]> * fix: icon color when idle Signed-off-by: Adam Setch <[email protected]> --------- Signed-off-by: Adam Setch <[email protected]>
1 parent 66cd5ae commit 287f48b

File tree

15 files changed

+88
-89
lines changed

15 files changed

+88
-89
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
"webpack-cli": "6.0.1",
126126
"webpack-merge": "6.0.1"
127127
},
128-
"packageManager": "pnpm@10.18.0",
128+
"packageManager": "pnpm@10.17.0",
129129
"pnpm": {
130130
"onlyBuiltDependencies": [
131131
"@biomejs/biome",

src/main/events.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,12 @@ describe('main/events', () => {
4545
it('sendRendererEvent forwards event to webContents with data', () => {
4646
const send = jest.fn();
4747
const mb: MockMenubar = { window: { webContents: { send } } };
48-
sendRendererEvent(mb as unknown as Menubar, EVENTS.UPDATE_TITLE, 'title');
49-
expect(send).toHaveBeenCalledWith(EVENTS.UPDATE_TITLE, 'title');
48+
sendRendererEvent(
49+
mb as unknown as Menubar,
50+
EVENTS.UPDATE_ICON_TITLE,
51+
'title',
52+
);
53+
expect(send).toHaveBeenCalledWith(EVENTS.UPDATE_ICON_TITLE, 'title');
5054
});
5155

5256
it('sendRendererEvent forwards event without data', () => {

src/main/index.ts

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -165,33 +165,26 @@ app.whenReady().then(async () => {
165165
EVENTS.USE_UNREAD_ACTIVE_ICON,
166166
(_, useUnreadActiveIcon: boolean) => {
167167
shouldUseUnreadActiveIcon = useUnreadActiveIcon;
168-
169-
if (shouldUseUnreadActiveIcon) {
170-
setActiveIcon();
171-
} else {
172-
setIdleIcon();
173-
}
174168
},
175169
);
176170

177-
onMainEvent(EVENTS.ICON_ERROR, () => {
171+
onMainEvent(EVENTS.UPDATE_ICON_COLOR, (_, notificationsCount: number) => {
178172
if (!mb.tray.isDestroyed()) {
179-
mb.tray.setImage(TrayIcons.error);
180-
}
181-
});
173+
if (notificationsCount < 0) {
174+
setErrorIcon();
175+
return;
176+
}
182177

183-
onMainEvent(EVENTS.ICON_ACTIVE, () => {
184-
if (!mb.tray.isDestroyed() && shouldUseUnreadActiveIcon) {
185-
}
186-
});
178+
if (notificationsCount > 0) {
179+
setActiveIcon();
180+
return;
181+
}
187182

188-
onMainEvent(EVENTS.ICON_IDLE, () => {
189-
if (!mb.tray.isDestroyed()) {
190183
setIdleIcon();
191184
}
192185
});
193186

194-
onMainEvent(EVENTS.UPDATE_TITLE, (_, title: string) => {
187+
onMainEvent(EVENTS.UPDATE_ICON_TITLE, (_, title: string) => {
195188
if (!mb.tray.isDestroyed()) {
196189
mb.tray.setTitle(title);
197190
}
@@ -256,14 +249,6 @@ const handleURL = (url: string) => {
256249
}
257250
};
258251

259-
function setActiveIcon() {
260-
mb.tray.setImage(
261-
menuBuilder.isUpdateAvailable()
262-
? TrayIcons.activeWithUpdate
263-
: TrayIcons.active,
264-
);
265-
}
266-
267252
function setIdleIcon() {
268253
if (shouldUseAlternateIdleIcon) {
269254
mb.tray.setImage(
@@ -279,3 +264,19 @@ function setIdleIcon() {
279264
);
280265
}
281266
}
267+
268+
function setActiveIcon() {
269+
if (shouldUseUnreadActiveIcon) {
270+
mb.tray.setImage(
271+
menuBuilder.isUpdateAvailable()
272+
? TrayIcons.activeWithUpdate
273+
: TrayIcons.active,
274+
);
275+
} else {
276+
setIdleIcon();
277+
}
278+
}
279+
280+
function setErrorIcon() {
281+
mb.tray.setImage(TrayIcons.error);
282+
}

src/preload/index.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class MockNotification {
5252
MockNotification;
5353

5454
interface TestApi {
55-
tray: { updateIcon: (n?: number) => void };
55+
tray: { updateColor: (n?: number) => void };
5656
openExternalLink: (u: string, f: boolean) => void;
5757
app: { version: () => Promise<string>; show?: () => void; hide?: () => void };
5858
onSystemThemeUpdate: (cb: (t: string) => void) => void;
@@ -90,15 +90,15 @@ describe('preload/index', () => {
9090
expect(api).toHaveProperty('openExternalLink');
9191
});
9292

93-
it('tray.updateIcon sends correct events', async () => {
93+
it('tray.updateColor sends correct events', async () => {
9494
await importPreload();
9595
const api = (window as unknown as { gitify: TestApi }).gitify; // casting only in test boundary
96-
api.tray.updateIcon(-1);
97-
api.tray.updateIcon(5);
98-
api.tray.updateIcon(0);
99-
expect(sendMainEvent).toHaveBeenNthCalledWith(1, EVENTS.ICON_ERROR);
100-
expect(sendMainEvent).toHaveBeenNthCalledWith(2, EVENTS.ICON_ACTIVE);
101-
expect(sendMainEvent).toHaveBeenNthCalledWith(3, EVENTS.ICON_IDLE);
96+
api.tray.updateColor(-1);
97+
expect(sendMainEvent).toHaveBeenNthCalledWith(
98+
1,
99+
EVENTS.UPDATE_ICON_COLOR,
100+
-1,
101+
);
102102
});
103103

104104
it('openExternalLink sends event with payload', async () => {

src/preload/index.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,11 @@ export const api = {
3535
},
3636

3737
tray: {
38-
updateIcon: (notificationsLength = 0) => {
39-
if (notificationsLength < 0) {
40-
sendMainEvent(EVENTS.ICON_ERROR);
41-
return;
42-
}
43-
44-
if (notificationsLength > 0) {
45-
sendMainEvent(EVENTS.ICON_ACTIVE);
46-
return;
47-
}
48-
49-
sendMainEvent(EVENTS.ICON_IDLE);
38+
updateColor: (notificationsCount = 0) => {
39+
sendMainEvent(EVENTS.UPDATE_ICON_COLOR, notificationsCount);
5040
},
5141

52-
updateTitle: (title = '') => sendMainEvent(EVENTS.UPDATE_TITLE, title),
42+
updateTitle: (title = '') => sendMainEvent(EVENTS.UPDATE_ICON_TITLE, title),
5343

5444
useAlternateIdleIcon: (value: boolean) =>
5545
sendMainEvent(EVENTS.USE_ALTERNATE_IDLE_ICON, value),

src/preload/utils.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe('preload/utils', () => {
5252
it('onRendererEvent registers listener and receives emitted data', () => {
5353
const handler = jest.fn();
5454
onRendererEvent(
55-
EVENTS.UPDATE_TITLE,
55+
EVENTS.UPDATE_ICON_TITLE,
5656
handler as unknown as (
5757
e: Electron.IpcRendererEvent,
5858
args: string,
@@ -62,8 +62,11 @@ describe('preload/utils', () => {
6262
ipcRenderer as unknown as {
6363
__emit: (channel: string, ...a: unknown[]) => void;
6464
}
65-
).__emit(EVENTS.UPDATE_TITLE, 'payload');
66-
expect(ipcRenderer.on).toHaveBeenCalledWith(EVENTS.UPDATE_TITLE, handler);
65+
).__emit(EVENTS.UPDATE_ICON_TITLE, 'payload');
66+
expect(ipcRenderer.on).toHaveBeenCalledWith(
67+
EVENTS.UPDATE_ICON_TITLE,
68+
handler,
69+
);
6770
expect(handler).toHaveBeenCalledWith({}, 'payload');
6871
});
6972
});

src/renderer/__helpers__/jest.setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ window.gitify = {
2626
setLevel: jest.fn(),
2727
},
2828
tray: {
29-
updateIcon: jest.fn(),
29+
updateColor: jest.fn(),
3030
updateTitle: jest.fn(),
3131
useAlternateIdleIcon: jest.fn(),
3232
useUnreadActiveIcon: jest.fn(),

src/renderer/context/App.tsx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
setKeyboardShortcut,
4646
setUseAlternateIdleIcon,
4747
setUseUnreadActiveIcon,
48+
updateTrayColor,
4849
updateTrayTitle,
4950
} from '../utils/comms';
5051
import { getNotificationCount } from '../utils/notifications/notifications';
@@ -154,24 +155,22 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
154155
useEffect(() => {
155156
const count = getNotificationCount(notifications);
156157

158+
let title = '';
157159
if (settings.showNotificationsCountInTray && count > 0) {
158-
updateTrayTitle(count.toString());
159-
} else {
160-
updateTrayTitle();
160+
title = count.toString();
161161
}
162-
}, [settings.showNotificationsCountInTray, notifications]);
163-
164-
useEffect(() => {
165-
const count = getNotificationCount(notifications);
166162

167163
setUseUnreadActiveIcon(settings.useUnreadActiveIcon);
168-
169-
updateTrayTitle(count.toString());
170-
}, [settings.useUnreadActiveIcon, notifications]);
171-
172-
useEffect(() => {
173164
setUseAlternateIdleIcon(settings.useAlternateIdleIcon);
174-
}, [settings.useAlternateIdleIcon]);
165+
166+
updateTrayColor(count);
167+
updateTrayTitle(title);
168+
}, [
169+
settings.showNotificationsCountInTray,
170+
settings.useUnreadActiveIcon,
171+
settings.useAlternateIdleIcon,
172+
notifications,
173+
]);
175174

176175
useEffect(() => {
177176
setKeyboardShortcut(settings.keyboardShortcut);

src/renderer/hooks/useNotifications.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
markNotificationThreadAsDone,
1414
markNotificationThreadAsRead,
1515
} from '../utils/api/client';
16-
import { updateTrayIcon } from '../utils/comms';
16+
import { updateTrayColor } from '../utils/comms';
1717
import { isMarkAsDoneFeatureSupported } from '../utils/features';
1818
import { rendererLogError } from '../utils/logger';
1919
import { triggerNativeNotifications } from '../utils/notifications/native';
@@ -93,7 +93,7 @@ export const useNotifications = (): NotificationsState => {
9393
if (allAccountsHaveErrors) {
9494
setStatus('error');
9595
setGlobalError(accountErrorsAreAllSame ? accountError : null);
96-
updateTrayIcon(-1);
96+
updateTrayColor(-1);
9797
return;
9898
}
9999

src/renderer/routes/Accounts.test.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ describe('renderer/routes/Accounts.tsx', () => {
258258

259259
it('should logout', async () => {
260260
const logoutFromAccountMock = jest.fn();
261-
const updateTrayIconMock = jest.spyOn(comms, 'updateTrayIcon');
261+
const updateTrayColorMock = jest.spyOn(comms, 'updateTrayColor');
262262
const updateTrayTitleMock = jest.spyOn(comms, 'updateTrayTitle');
263263

264264
await act(async () => {
@@ -280,10 +280,11 @@ describe('renderer/routes/Accounts.tsx', () => {
280280
await userEvent.click(screen.getByTestId('account-logout'));
281281

282282
expect(logoutFromAccountMock).toHaveBeenCalledTimes(1);
283-
expect(updateTrayIconMock).toHaveBeenCalledTimes(1);
284-
expect(updateTrayIconMock).toHaveBeenCalledWith();
283+
expect(updateTrayColorMock).toHaveBeenCalledTimes(1);
284+
expect(updateTrayColorMock).toHaveBeenCalledWith();
285285
expect(updateTrayTitleMock).toHaveBeenCalledTimes(1);
286286
expect(updateTrayTitleMock).toHaveBeenCalledWith();
287+
287288
expect(mockNavigate).toHaveBeenNthCalledWith(1, -1);
288289
});
289290
});

0 commit comments

Comments
 (0)