Skip to content

Commit

Permalink
feat(settings): show notification count in tray (#945)
Browse files Browse the repository at this point in the history
* feat: show notification count in tray

* feat: update title

* feat: update title

* test: update snapshots

* fix test

* fix test

* fix test

* test: add coverage

---------

Co-authored-by: Afonso Jorge Ramos <afonsojorgeramos@gmail.com>
  • Loading branch information
setchy and afonsojramos authored Apr 2, 2024
1 parent 20ad533 commit 37d3bef
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 7 deletions.
5 changes: 5 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ menubarApp.on('ready', () => {
}
}
});
ipcMain.on('update-title', (_, title) => {
if (!menubarApp.tray.isDestroyed()) {
menubarApp.tray.setTitle(title);
}
});
ipcMain.on('set-login-item-settings', (event, settings) => {
app.setLoginItemSettings(settings);
});
Expand Down
1 change: 1 addition & 0 deletions src/__mocks__/mock-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const mockSettings: SettingsState = {
playSound: true,
showNotifications: true,
showBots: true,
showNotificationsCountInTray: false,
openAtStartup: false,
theme: Theme.SYSTEM,
colors: false,
Expand Down
16 changes: 12 additions & 4 deletions src/context/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useNotifications } from '../hooks/useNotifications';
import * as apiRequests from '../utils/api-requests';
import * as comms from '../utils/comms';
import * as storage from '../utils/storage';
import * as notifications from '../utils/notifications';

jest.mock('../hooks/useNotifications');

Expand Down Expand Up @@ -35,6 +36,11 @@ describe('context/App.tsx', () => {

describe('api methods', () => {
const apiRequestAuthMock = jest.spyOn(apiRequests, 'apiRequestAuth');
const getNotificationCountMock = jest.spyOn(
notifications,
'getNotificationCount',
);
getNotificationCountMock.mockReturnValue(1);

const fetchNotificationsMock = jest.fn();
const markNotificationMock = jest.fn();
Expand Down Expand Up @@ -285,12 +291,13 @@ describe('context/App.tsx', () => {
expect(saveStateMock).toHaveBeenCalledWith(
{ enterpriseAccounts: [], token: null, user: null },
{
theme: 'SYSTEM',
openAtStartup: false,
participating: true,
playSound: true,
showNotifications: true,
showBots: true,
showNotificationsCountInTray: false,
openAtStartup: false,
theme: 'SYSTEM',
colors: null,
markAsDoneOnOpen: false,
},
Expand Down Expand Up @@ -324,12 +331,13 @@ describe('context/App.tsx', () => {
expect(saveStateMock).toHaveBeenCalledWith(
{ enterpriseAccounts: [], token: null, user: null },
{
theme: 'SYSTEM',
openAtStartup: true,
participating: false,
playSound: true,
showNotifications: true,
showBots: true,
showNotificationsCountInTray: false,
openAtStartup: true,
theme: 'SYSTEM',
colors: null,
markAsDoneOnOpen: false,
},
Expand Down
14 changes: 13 additions & 1 deletion src/context/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ import {
import { apiRequestAuth } from '../utils/api-requests';
import { setTheme } from '../utils/theme';
import { addAccount, authGitHub, getToken, getUserData } from '../utils/auth';
import { setAutoLaunch } from '../utils/comms';
import { setAutoLaunch, updateTrayTitle } from '../utils/comms';
import Constants from '../utils/constants';
import { generateGitHubAPIUrl } from '../utils/helpers';
import { clearState, loadState, saveState } from '../utils/storage';
import { getNotificationCount } from '../utils/notifications';

const defaultAccounts: AuthState = {
token: null,
Expand All @@ -35,6 +36,7 @@ export const defaultSettings: SettingsState = {
playSound: true,
showNotifications: true,
showBots: true,
showNotificationsCountInTray: false,
openAtStartup: false,
theme: Theme.SYSTEM,
colors: null,
Expand Down Expand Up @@ -98,6 +100,16 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
fetchNotifications(accounts, settings);
}, [accounts.token, accounts.enterpriseAccounts.length]);

useEffect(() => {
const count = getNotificationCount(notifications);

if (settings.showNotificationsCountInTray && count > 0) {
updateTrayTitle(count.toString());
} else {
updateTrayTitle();
}
}, [settings.showNotificationsCountInTray, notifications]);

useInterval(() => {
fetchNotifications(accounts, settings);
}, 60000);
Expand Down
34 changes: 33 additions & 1 deletion src/routes/Settings.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ describe('routes/Settings.tsx', () => {

expect(logoutMock).toHaveBeenCalledTimes(1);

expect(ipcRenderer.send).toHaveBeenCalledTimes(1);
expect(ipcRenderer.send).toHaveBeenCalledTimes(2);
expect(ipcRenderer.send).toHaveBeenCalledWith('update-icon');
expect(ipcRenderer.send).toHaveBeenCalledWith('update-title', '');
expect(mockNavigate).toHaveBeenNthCalledWith(1, -1);
});

Expand Down Expand Up @@ -155,6 +156,37 @@ describe('routes/Settings.tsx', () => {
expect(updateSetting).toHaveBeenCalledWith('showBots', false);
});

it('should toggle the showNotificationsCountInTray checkbox', async () => {
let getByLabelText;

await act(async () => {
const { getByLabelText: getByLabelTextLocal } = render(
<AppContext.Provider
value={{
settings: mockSettings,
accounts: mockAccounts,
updateSetting,
}}
>
<MemoryRouter>
<SettingsRoute />
</MemoryRouter>
</AppContext.Provider>,
);
getByLabelText = getByLabelTextLocal;
});

fireEvent.click(getByLabelText('Show notifications count in tray'), {
target: { checked: true },
});

expect(updateSetting).toHaveBeenCalledTimes(1);
expect(updateSetting).toHaveBeenCalledWith(
'showNotificationsCountInTray',
false,
);
});

it('should toggle the playSound checkbox', async () => {
let getByLabelText;

Expand Down
15 changes: 14 additions & 1 deletion src/routes/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import { AppContext } from '../context/App';
import { Theme } from '../types';
import { apiRequestAuth } from '../utils/api-requests';
import { setTheme } from '../utils/theme';
import { openExternalLink, updateTrayIcon } from '../utils/comms';
import {
openExternalLink,
updateTrayIcon,
updateTrayTitle,
} from '../utils/comms';
import Constants from '../utils/constants';
import { generateGitHubAPIUrl } from '../utils/helpers';

Expand Down Expand Up @@ -71,6 +75,7 @@ export const SettingsRoute: React.FC = () => {
logout();
navigate(-1);
updateTrayIcon();
updateTrayTitle();
}, []);

const quitApp = useCallback(() => {
Expand Down Expand Up @@ -168,6 +173,14 @@ export const SettingsRoute: React.FC = () => {
<legend id="system" className="font-semibold mt-2 mb-1">
System
</legend>
<FieldCheckbox
name="showNotificationsCountInTray"
label="Show notifications count in tray"
checked={settings.showNotificationsCountInTray}
onChange={(evt) =>
updateSetting('showNotificationsCountInTray', evt.target.checked)
}
/>
<FieldCheckbox
name="showNotifications"
label="Show system notifications"
Expand Down
23 changes: 23 additions & 0 deletions src/routes/__snapshots__/Settings.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,29 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
>
System
</legend>
<div
class="flex items-start mt-1 mb-3"
>
<div
class="flex items-center h-5"
>
<input
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
id="showNotificationsCountInTray"
type="checkbox"
/>
</div>
<div
class="ml-3 text-sm"
>
<label
class="font-medium text-gray-700 dark:text-gray-200"
for="showNotificationsCountInTray"
>
Show notifications count in tray
</label>
</div>
</div>
<div
class="flex items-start mt-1 mb-3"
>
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface NotificationSettingsState {
interface SystemSettingsState {
playSound: boolean;
openAtStartup: boolean;
showNotificationsCountInTray: boolean;
}

export enum Theme {
Expand Down
4 changes: 4 additions & 0 deletions src/utils/comms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export function updateTrayIcon(notificationsLength = 0): void {
}
}

export function updateTrayTitle(title: string = ''): void {
ipcRenderer.send('update-title', title);
}

export function restoreSetting(setting, value): void {
ipcRenderer.send(setting, value);
}

0 comments on commit 37d3bef

Please sign in to comment.