Skip to content

Commit fdfc589

Browse files
authored
feat(settings): alternate idle tray icon (#1501)
* fix: alternate idle images for linux Signed-off-by: Adam Setch <[email protected]> * fix: alternate idle images for linux Signed-off-by: Adam Setch <[email protected]> * fix: use user setting to control alternate idle icon Signed-off-by: Adam Setch <[email protected]> --------- Signed-off-by: Adam Setch <[email protected]>
1 parent 960d162 commit fdfc589

15 files changed

+134
-43
lines changed
595 Bytes
Loading

assets/images/[email protected]

1.31 KB
Loading

assets/images/tray-idle-white.png

490 Bytes
Loading

assets/images/[email protected]

996 Bytes
Loading

assets/images/tray-idleTemplate.png

631 Bytes
Loading

src/__mocks__/state-mocks.ts

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ const mockSystemSettings = {
9797
showNotificationsCountInTray: false,
9898
showNotifications: true,
9999
playSound: true,
100+
useAlternateIdleIcon: false,
100101
openAtStartup: false,
101102
};
102103

src/components/settings/SystemSettings.test.tsx

+25
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,31 @@ describe('routes/components/settings/SystemSettings.tsx', () => {
137137
expect(updateSetting).toHaveBeenCalledWith('playSound', false);
138138
});
139139

140+
it('should toggle the useAlternateIdleIcon checkbox', async () => {
141+
await act(async () => {
142+
render(
143+
<AppContext.Provider
144+
value={{
145+
auth: mockAuth,
146+
settings: mockSettings,
147+
updateSetting,
148+
}}
149+
>
150+
<MemoryRouter>
151+
<SystemSettings />
152+
</MemoryRouter>
153+
</AppContext.Provider>,
154+
);
155+
});
156+
157+
fireEvent.click(screen.getByLabelText('Use alternate idle icon'), {
158+
target: { checked: true },
159+
});
160+
161+
expect(updateSetting).toHaveBeenCalledTimes(1);
162+
expect(updateSetting).toHaveBeenCalledWith('useAlternateIdleIcon', false);
163+
});
164+
140165
it('should toggle the openAtStartup checkbox', async () => {
141166
await act(async () => {
142167
render(

src/components/settings/SystemSettings.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ export const SystemSettings: FC = () => {
6767
checked={settings.playSound}
6868
onChange={(evt) => updateSetting('playSound', evt.target.checked)}
6969
/>
70+
<Checkbox
71+
name="useAlternateIdleIcon"
72+
label="Use alternate idle icon"
73+
checked={settings.useAlternateIdleIcon}
74+
onChange={(evt) =>
75+
updateSetting('useAlternateIdleIcon', evt.target.checked)
76+
}
77+
tooltip={
78+
<div>
79+
Use a white Gitify logo (instead of the default black logo) when all
80+
notifications are read. Particularly useful for devices which have a
81+
dark-themed menubar or taskbar.
82+
</div>
83+
}
84+
/>
7085
{!isLinux() && (
7186
<Checkbox
7287
name="openAtStartUp"

src/context/App.test.tsx

+2-36
Original file line numberDiff line numberDiff line change
@@ -345,25 +345,8 @@ describe('context/App.tsx', () => {
345345
user: null,
346346
} as AuthState,
347347
settings: {
348+
...defaultSettings,
348349
participating: true,
349-
playSound: true,
350-
showNotifications: true,
351-
hideBots: false,
352-
showNotificationsCountInTray: false,
353-
openAtStartup: false,
354-
theme: 'SYSTEM',
355-
detailedNotifications: true,
356-
markAsDoneOnOpen: false,
357-
markAsDoneOnUnsubscribe: false,
358-
showAccountHeader: false,
359-
delayNotificationState: false,
360-
showPills: true,
361-
showNumber: true,
362-
keyboardShortcut: true,
363-
groupBy: 'REPOSITORY',
364-
filterReasons: [],
365-
zoomPercentage: 100,
366-
openLinks: 'FOREGROUND',
367350
} as SettingsState,
368351
});
369352
});
@@ -403,25 +386,8 @@ describe('context/App.tsx', () => {
403386
user: null,
404387
} as AuthState,
405388
settings: {
406-
participating: false,
407-
playSound: true,
408-
showNotifications: true,
409-
hideBots: false,
410-
showNotificationsCountInTray: false,
389+
...defaultSettings,
411390
openAtStartup: true,
412-
theme: 'SYSTEM',
413-
detailedNotifications: true,
414-
markAsDoneOnOpen: false,
415-
markAsDoneOnUnsubscribe: false,
416-
showAccountHeader: false,
417-
delayNotificationState: false,
418-
showPills: true,
419-
showNumber: true,
420-
keyboardShortcut: true,
421-
groupBy: 'REPOSITORY',
422-
filterReasons: [],
423-
zoomPercentage: 100,
424-
openLinks: 'FOREGROUND',
425391
} as SettingsState,
426392
});
427393
});

src/context/App.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
removeAccount,
3838
} from '../utils/auth/utils';
3939
import {
40+
setAlternateIdleIcon,
4041
setAutoLaunch,
4142
setKeyboardShortcut,
4243
updateTrayTitle,
@@ -77,6 +78,7 @@ const defaultSystemSettings = {
7778
showNotificationsCountInTray: false,
7879
showNotifications: true,
7980
playSound: true,
81+
useAlternateIdleIcon: false,
8082
openAtStartup: false,
8183
};
8284

@@ -196,6 +198,9 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
196198
if (name === 'openAtStartup') {
197199
setAutoLaunch(value as boolean);
198200
}
201+
if (name === 'useAlternateIdleIcon') {
202+
setAlternateIdleIcon(value as boolean);
203+
}
199204

200205
const newSettings = { ...settings, [name]: value };
201206
setSettings(newSettings);
@@ -271,6 +276,7 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
271276

272277
if (existing.settings) {
273278
setKeyboardShortcut(existing.settings.keyboardShortcut);
279+
setAlternateIdleIcon(existing.settings.useAlternateIdleIcon);
274280
setSettings({ ...defaultSettings, ...existing.settings });
275281
webFrame.setZoomLevel(
276282
zoomPercentageToLevel(existing.settings.zoomPercentage),

src/electron/main.js

+23-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@ log.initialize();
2121
const idleIcon = path.resolve(
2222
`${__dirname}/../../assets/images/tray-idleTemplate.png`,
2323
);
24+
const idleAlternateIcon = path.resolve(
25+
`${__dirname}/../../assets/images/tray-idle-white.png`,
26+
);
2427
const idleUpdateAvailableIcon = path.resolve(
2528
`${__dirname}/../../assets/images/tray-idle-update.png`,
2629
);
30+
const idleAlternateUpdateAvailableIcon = path.resolve(
31+
`${__dirname}/../../assets/images/tray-idle-white-update.png`,
32+
);
2733
const activeIcon = path.resolve(
2834
`${__dirname}/../../assets/images/tray-active.png`,
2935
);
@@ -114,6 +120,8 @@ const mb = menubar({
114120
showDockIcon: false,
115121
});
116122

123+
let shouldUseAlternateIdleIcon = false;
124+
117125
app.whenReady().then(async () => {
118126
await onFirstRunMaybe();
119127

@@ -177,6 +185,10 @@ app.whenReady().then(async () => {
177185

178186
ipc.on('gitify:quit', () => mb.app.quit());
179187

188+
ipc.on('gitify:use-alternate-idle-icon', (_, useAlternateIdleIcon) => {
189+
shouldUseAlternateIdleIcon = useAlternateIdleIcon;
190+
});
191+
180192
ipc.on('gitify:icon-active', () => {
181193
if (!mb.tray.isDestroyed()) {
182194
mb.tray.setImage(
@@ -189,9 +201,17 @@ app.whenReady().then(async () => {
189201

190202
ipc.on('gitify:icon-idle', () => {
191203
if (!mb.tray.isDestroyed()) {
192-
mb.tray.setImage(
193-
updateAvailableMenuItem.visible ? idleUpdateAvailableIcon : idleIcon,
194-
);
204+
if (shouldUseAlternateIdleIcon) {
205+
mb.tray.setImage(
206+
updateAvailableMenuItem.visible
207+
? idleAlternateUpdateAvailableIcon
208+
: idleAlternateIcon,
209+
);
210+
} else {
211+
mb.tray.setImage(
212+
updateAvailableMenuItem.visible ? idleUpdateAvailableIcon : idleIcon,
213+
);
214+
}
195215
}
196216
});
197217

src/routes/__snapshots__/Settings.test.tsx.snap

+43
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/types.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,21 @@ interface AppearanceSettingsState {
7575
}
7676

7777
interface NotificationSettingsState {
78+
groupBy: GroupBy;
7879
participating: boolean;
79-
showNotifications: boolean;
8080
markAsDoneOnOpen: boolean;
8181
markAsDoneOnUnsubscribe: boolean;
8282
delayNotificationState: boolean;
83-
groupBy: GroupBy;
8483
}
8584

8685
interface SystemSettingsState {
8786
openLinks: OpenPreference;
87+
keyboardShortcut: boolean;
88+
showNotificationsCountInTray: boolean;
89+
showNotifications: boolean;
90+
useAlternateIdleIcon: boolean;
8891
playSound: boolean;
8992
openAtStartup: boolean;
90-
showNotificationsCountInTray: boolean;
91-
keyboardShortcut: boolean;
9293
}
9394

9495
interface FilterSettingsState {

src/utils/comms.test.ts

+10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
hideWindow,
77
openExternalLink,
88
quitApp,
9+
setAlternateIdleIcon,
910
setAutoLaunch,
1011
showWindow,
1112
updateTrayIcon,
@@ -104,4 +105,13 @@ describe('utils/comms.ts', () => {
104105
openAtLogin: false,
105106
});
106107
});
108+
109+
it('should setAlternateIdleIcon', () => {
110+
setAlternateIdleIcon(true);
111+
112+
expect(ipcRenderer.send).toHaveBeenCalledWith(
113+
'gitify:use-alternate-idle-icon',
114+
true,
115+
);
116+
});
107117
});

src/utils/comms.ts

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ export function setAutoLaunch(value: boolean): void {
4242
});
4343
}
4444

45+
export function setAlternateIdleIcon(value: boolean): void {
46+
ipcRenderer.send('gitify:use-alternate-idle-icon', value);
47+
}
48+
4549
export function setKeyboardShortcut(keyboardShortcut: boolean): void {
4650
ipcRenderer.send('gitify:update-keyboard-shortcut', {
4751
enabled: keyboardShortcut,

0 commit comments

Comments
 (0)