diff --git a/src/renderer/__mocks__/state-mocks.ts b/src/renderer/__mocks__/state-mocks.ts index 63ad1f1c0..529aa94c5 100644 --- a/src/renderer/__mocks__/state-mocks.ts +++ b/src/renderer/__mocks__/state-mocks.ts @@ -43,6 +43,7 @@ const mockNotificationSettings: NotificationSettingsState = { showPills: true, showNumber: true, participating: false, + fetchReadNotifications: false, markAsDoneOnOpen: false, markAsDoneOnUnsubscribe: false, delayNotificationState: false, diff --git a/src/renderer/components/Sidebar.tsx b/src/renderer/components/Sidebar.tsx index f4c7ae55c..2925ddee8 100644 --- a/src/renderer/components/Sidebar.tsx +++ b/src/renderer/components/Sidebar.tsx @@ -35,7 +35,7 @@ export const Sidebar: FC = () => { status, settings, auth, - unreadNotificationCount, + notificationCount, hasUnreadNotifications, } = useAppContext(); @@ -91,7 +91,7 @@ export const Sidebar: FC = () => { openGitHubNotifications(primaryAccountHostname)} size="small" diff --git a/src/renderer/components/notifications/NotificationRow.test.tsx b/src/renderer/components/notifications/NotificationRow.test.tsx index 14ed55fc6..58e22aadc 100644 --- a/src/renderer/components/notifications/NotificationRow.test.tsx +++ b/src/renderer/components/notifications/NotificationRow.test.tsx @@ -154,6 +154,24 @@ describe('renderer/components/notifications/NotificationRow.tsx', () => { expect(markNotificationsAsReadMock).toHaveBeenCalledTimes(1); }); + it('should hide mark as read button when notification is already read', async () => { + const readNotification = { + ...mockSingleNotification, + unread: false, + }; + + const props = { + notification: readNotification, + account: mockGitHubCloudAccount, + }; + + renderWithAppContext(); + + expect( + screen.queryByTestId('notification-mark-as-read'), + ).not.toBeInTheDocument(); + }); + it('should mark notifications as done', async () => { const markNotificationsAsDoneMock = jest.fn(); diff --git a/src/renderer/components/notifications/NotificationRow.tsx b/src/renderer/components/notifications/NotificationRow.tsx index c158689c6..560fe1bed 100644 --- a/src/renderer/components/notifications/NotificationRow.tsx +++ b/src/renderer/components/notifications/NotificationRow.tsx @@ -138,6 +138,14 @@ export const NotificationRow: FC = ({ {!animateExit && ( + + = ({ testid="notification-mark-as-done" /> - - repoNotifications: mockGitHubNotifications, }; + beforeEach(() => { + // Reset mock notification state between tests since it's mutated + for (const n of mockGitHubNotifications) { + n.unread = true; + } + }); + afterEach(() => { jest.clearAllMocks(); }); diff --git a/src/renderer/components/notifications/RepositoryNotifications.tsx b/src/renderer/components/notifications/RepositoryNotifications.tsx index 7f2f3ce0d..a0e2a363f 100644 --- a/src/renderer/components/notifications/RepositoryNotifications.tsx +++ b/src/renderer/components/notifications/RepositoryNotifications.tsx @@ -91,6 +91,14 @@ export const RepositoryNotifications: FC = ({ {!animateExit && ( + + = ({ testid="repository-mark-as-done" /> - - @@ -1878,20 +1878,20 @@ exports[`renderer/components/notifications/AccountNotifications.tsx should rende data-wrap="nowrap" > @@ -2468,20 +2468,20 @@ exports[`renderer/components/notifications/AccountNotifications.tsx should rende data-wrap="nowrap" > @@ -2758,20 +2758,20 @@ exports[`renderer/components/notifications/AccountNotifications.tsx should rende data-wrap="nowrap" > diff --git a/src/renderer/components/notifications/__snapshots__/NotificationRow.test.tsx.snap b/src/renderer/components/notifications/__snapshots__/NotificationRow.test.tsx.snap index 8227203cc..cf0f804e6 100644 --- a/src/renderer/components/notifications/__snapshots__/NotificationRow.test.tsx.snap +++ b/src/renderer/components/notifications/__snapshots__/NotificationRow.test.tsx.snap @@ -322,20 +322,20 @@ exports[`renderer/components/notifications/NotificationRow.tsx should render its data-wrap="nowrap" > @@ -732,20 +732,20 @@ exports[`renderer/components/notifications/NotificationRow.tsx should render its data-wrap="nowrap" > @@ -1147,20 +1147,20 @@ exports[`renderer/components/notifications/NotificationRow.tsx should render its data-wrap="nowrap" > @@ -1505,20 +1505,20 @@ exports[`renderer/components/notifications/NotificationRow.tsx should render its data-wrap="nowrap" > @@ -1920,20 +1920,20 @@ exports[`renderer/components/notifications/NotificationRow.tsx should render its data-wrap="nowrap" > @@ -2278,20 +2278,20 @@ exports[`renderer/components/notifications/NotificationRow.tsx should render its data-wrap="nowrap" > @@ -2721,35 +2721,6 @@ exports[`renderer/components/notifications/NotificationRow.tsx should render its /> - - - - @@ -751,20 +693,20 @@ exports[`renderer/components/notifications/RepositoryNotifications.tsx should re data-wrap="nowrap" > @@ -917,7 +859,7 @@ exports[`renderer/components/notifications/RepositoryNotifications.tsx should to data-portal-root="true" >
@@ -1114,7 +1056,7 @@ exports[`renderer/components/notifications/RepositoryNotifications.tsx should to data-portal-root="true" >
@@ -1318,7 +1260,7 @@ exports[`renderer/components/notifications/RepositoryNotifications.tsx should to data-portal-root="true" >
@@ -1579,7 +1521,7 @@ exports[`renderer/components/notifications/RepositoryNotifications.tsx should us data-portal-root="true" >
@@ -1783,7 +1725,7 @@ exports[`renderer/components/notifications/RepositoryNotifications.tsx should us data-portal-root="true" >
diff --git a/src/renderer/components/settings/NotificationSettings.test.tsx b/src/renderer/components/settings/NotificationSettings.test.tsx index 648bf8c76..630988cb1 100644 --- a/src/renderer/components/settings/NotificationSettings.test.tsx +++ b/src/renderer/components/settings/NotificationSettings.test.tsx @@ -271,6 +271,24 @@ describe('renderer/components/settings/NotificationSettings.tsx', () => { ); }); + it('should toggle the fetchReadNotifications checkbox', async () => { + await act(async () => { + renderWithAppContext(, { + updateSetting: updateSettingMock, + }); + }); + + await userEvent.click( + screen.getByTestId('checkbox-fetchReadNotifications'), + ); + + expect(updateSettingMock).toHaveBeenCalledTimes(1); + expect(updateSettingMock).toHaveBeenCalledWith( + 'fetchReadNotifications', + true, + ); + }); + it('should toggle the markAsDoneOnOpen checkbox', async () => { await act(async () => { renderWithAppContext(, { diff --git a/src/renderer/components/settings/NotificationSettings.tsx b/src/renderer/components/settings/NotificationSettings.tsx index 66bb02de7..102e53843 100644 --- a/src/renderer/components/settings/NotificationSettings.tsx +++ b/src/renderer/components/settings/NotificationSettings.tsx @@ -328,6 +328,31 @@ export const NotificationSettings: FC = () => { } /> + + updateSetting('fetchReadNotifications', evt.target.checked) + } + tooltip={ + + + When checked, {APPLICATION.NAME} will fetch + and display both read and unread notifications. + + + When unchecked, {APPLICATION.NAME} will only + fetch and display unread notifications. + + + ⚠️ Enabling this setting will increase API usage and may cause + rate limiting for users with many notifications. + + + } + /> + { setUseUnreadActiveIcon(settings.useUnreadActiveIcon); setUseAlternateIdleIcon(settings.useAlternateIdleIcon); - const trayCount = status === 'error' ? -1 : unreadNotificationCount; + const trayCount = status === 'error' ? -1 : notificationCount; setTrayIconColorAndTitle(trayCount, settings); }, [ settings.showNotificationsCountInTray, diff --git a/src/renderer/context/defaults.ts b/src/renderer/context/defaults.ts index b37fc260a..e26199f98 100644 --- a/src/renderer/context/defaults.ts +++ b/src/renderer/context/defaults.ts @@ -36,6 +36,7 @@ const defaultNotificationSettings: NotificationSettingsState = { showPills: true, showNumber: true, participating: false, + fetchReadNotifications: false, markAsDoneOnOpen: false, markAsDoneOnUnsubscribe: false, delayNotificationState: false, diff --git a/src/renderer/hooks/useNotifications.test.ts b/src/renderer/hooks/useNotifications.test.ts index e99f84bdc..8b7cb706f 100644 --- a/src/renderer/hooks/useNotifications.test.ts +++ b/src/renderer/hooks/useNotifications.test.ts @@ -88,11 +88,11 @@ describe('renderer/hooks/useNotifications.ts', () => { ]; nock('https://api.github.com') - .get('/notifications?participating=false') + .get('/notifications?participating=false&all=false') .reply(200, notifications); nock('https://github.gitify.io/api/v3') - .get('/notifications?participating=false') + .get('/notifications?participating=false&all=false') .reply(200, notifications); const { result } = renderHook(() => useNotifications()); @@ -214,7 +214,7 @@ describe('renderer/hooks/useNotifications.ts', () => { ]; nock('https://api.github.com') - .get('/notifications?participating=false') + .get('/notifications?participating=false&all=false') .reply(200, mockNotifications); nock('https://api.github.com') @@ -322,7 +322,7 @@ describe('renderer/hooks/useNotifications.ts', () => { const message = 'Bad credentials'; nock('https://api.github.com/') - .get('/notifications?participating=false') + .get('/notifications?participating=false&all=false') .replyWithError({ code, response: { @@ -334,7 +334,7 @@ describe('renderer/hooks/useNotifications.ts', () => { }); nock('https://github.gitify.io/api/v3/') - .get('/notifications?participating=false') + .get('/notifications?participating=false&all=false') .replyWithError({ code, response: { @@ -365,7 +365,7 @@ describe('renderer/hooks/useNotifications.ts', () => { const code = AxiosError.ERR_BAD_REQUEST; nock('https://api.github.com/') - .get('/notifications?participating=false') + .get('/notifications?participating=false&all=false') .replyWithError({ code, response: { @@ -377,7 +377,7 @@ describe('renderer/hooks/useNotifications.ts', () => { }); nock('https://github.gitify.io/api/v3/') - .get('/notifications?participating=false') + .get('/notifications?participating=false&all=false') .replyWithError({ code, response: { diff --git a/src/renderer/routes/__snapshots__/Settings.test.tsx.snap b/src/renderer/routes/__snapshots__/Settings.test.tsx.snap index a49af8031..f0f90e965 100644 --- a/src/renderer/routes/__snapshots__/Settings.test.tsx.snap +++ b/src/renderer/routes/__snapshots__/Settings.test.tsx.snap @@ -1098,6 +1098,54 @@ exports[`renderer/routes/Settings.tsx should render itself & its children 1`] =
+
+ + + +