Skip to content

Commit 6131e57

Browse files
authored
fix: remove notification from state on open (#789)
* fix: remove notification from state on open * tests: add test for `removeNotificationFromState`
1 parent 1c3c248 commit 6131e57

File tree

5 files changed

+62
-2
lines changed

5 files changed

+62
-2
lines changed

src/components/NotificationRow.test.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ describe('components/Notification.js', () => {
3131
});
3232

3333
it('should open a notification in the browser', () => {
34-
const markNotification = jest.fn();
34+
const removeNotificationFromState = jest.fn();
3535

3636
const props = {
3737
notification: mockedSingleNotification,
@@ -42,7 +42,7 @@ describe('components/Notification.js', () => {
4242
<AppContext.Provider
4343
value={{
4444
settings: { ...mockSettings, markAsDoneOnOpen: false },
45-
markNotification,
45+
removeNotificationFromState,
4646
accounts: mockAccounts,
4747
}}
4848
>
@@ -52,6 +52,7 @@ describe('components/Notification.js', () => {
5252

5353
fireEvent.click(getByRole('main'));
5454
expect(shell.openExternal).toHaveBeenCalledTimes(1);
55+
expect(removeNotificationFromState).toHaveBeenCalledTimes(1);
5556
});
5657

5758
it('should open a notification in browser & mark it as done', () => {

src/components/NotificationRow.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export const NotificationRow: React.FC<IProps> = ({
2323
const {
2424
settings,
2525
accounts,
26+
removeNotificationFromState,
2627
markNotification,
2728
markNotificationDone,
2829
unsubscribeNotification,
@@ -33,6 +34,9 @@ export const NotificationRow: React.FC<IProps> = ({
3334

3435
if (settings.markAsDoneOnOpen) {
3536
markNotificationDone(notification.id, hostname);
37+
} else {
38+
// no need to mark as read, github does it by default when opening it
39+
removeNotificationFromState(notification.id, hostname);
3640
}
3741
}, [settings]);
3842

src/context/App.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ interface AppContextState {
5151
notifications: AccountNotifications[];
5252
isFetching: boolean;
5353
requestFailed: boolean;
54+
removeNotificationFromState: (id: string, hostname: string) => void;
5455
fetchNotifications: () => Promise<void>;
5556
markNotification: (id: string, hostname: string) => Promise<void>;
5657
markNotificationDone: (id: string, hostname: string) => Promise<void>;
@@ -71,6 +72,7 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
7172
notifications,
7273
requestFailed,
7374
isFetching,
75+
removeNotificationFromState,
7476
markNotification,
7577
markNotificationDone,
7678
unsubscribeNotification,
@@ -210,6 +212,7 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
210212
notifications,
211213
isFetching,
212214
requestFailed,
215+
removeNotificationFromState,
213216
fetchNotifications: fetchNotificationsWithAccounts,
214217
markNotification: markNotificationWithAccounts,
215218
markNotificationDone: markNotificationDoneWithAccounts,

src/hooks/useNotifications.test.ts

+36
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,42 @@ describe('hooks/useNotifications.ts', () => {
269269
});
270270
});
271271

272+
describe('removeNotificationFromState', () => {
273+
it('should remove a notification from state', async () => {
274+
const notifications = [
275+
{ id: 1, title: 'This is a notification.' },
276+
{ id: 2, title: 'This is another one.' },
277+
];
278+
279+
nock('https://api.github.com')
280+
.get('/notifications?participating=false')
281+
.reply(200, notifications);
282+
283+
nock('https://github.gitify.io/api/v3')
284+
.get('/notifications?participating=false')
285+
.reply(200, notifications);
286+
287+
const { result } = renderHook(() => useNotifications(false));
288+
289+
act(() => {
290+
result.current.fetchNotifications(mockAccounts, mockSettings);
291+
});
292+
293+
await waitFor(() => {
294+
expect(result.current.isFetching).toBe(false);
295+
});
296+
297+
act(() => {
298+
result.current.removeNotificationFromState(
299+
result.current.notifications[0].notifications[0].id,
300+
result.current.notifications[0].hostname,
301+
);
302+
});
303+
304+
expect(result.current.notifications[0].notifications.length).toBe(1);
305+
});
306+
});
307+
272308
describe('markNotification', () => {
273309
const id = 'notification-123';
274310

src/hooks/useNotifications.ts

+16
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { removeNotifications } from '../utils/remove-notifications';
1919

2020
interface NotificationsState {
2121
notifications: AccountNotifications[];
22+
removeNotificationFromState: (id: string, hostname: string) => void;
2223
fetchNotifications: (
2324
accounts: AuthState,
2425
settings: SettingsState,
@@ -312,11 +313,26 @@ export const useNotifications = (colors: boolean): NotificationsState => {
312313
[notifications],
313314
);
314315

316+
const removeNotificationFromState = useCallback(
317+
(id, hostname) => {
318+
const updatedNotifications = removeNotification(
319+
id,
320+
notifications,
321+
hostname,
322+
);
323+
324+
setNotifications(updatedNotifications);
325+
setTrayIconColor(updatedNotifications);
326+
},
327+
[notifications],
328+
);
329+
315330
return {
316331
isFetching,
317332
requestFailed,
318333
notifications,
319334

335+
removeNotificationFromState,
320336
fetchNotifications,
321337
markNotification,
322338
markNotificationDone,

0 commit comments

Comments
 (0)