Skip to content

Commit 5c01b5d

Browse files
committed
feat: add 'Show read notifications' setting (#708)
1 parent da0729e commit 5c01b5d

8 files changed

Lines changed: 128 additions & 6 deletions

File tree

src/renderer/__mocks__/state-mocks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const mockNotificationSettings: NotificationSettingsState = {
4343
showPills: true,
4444
showNumber: true,
4545
participating: false,
46+
showReadNotifications: true,
4647
markAsDoneOnOpen: false,
4748
markAsDoneOnUnsubscribe: false,
4849
delayNotificationState: false,

src/renderer/components/settings/NotificationSettings.test.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,22 @@ describe('renderer/components/settings/NotificationSettings.tsx', () => {
271271
);
272272
});
273273

274+
it('should toggle the showReadNotifications checkbox', async () => {
275+
await act(async () => {
276+
renderWithAppContext(<NotificationSettings />, {
277+
updateSetting: updateSettingMock,
278+
});
279+
});
280+
281+
await userEvent.click(screen.getByTestId('checkbox-showReadNotifications'));
282+
283+
expect(updateSettingMock).toHaveBeenCalledTimes(1);
284+
expect(updateSettingMock).toHaveBeenCalledWith(
285+
'showReadNotifications',
286+
false,
287+
);
288+
});
289+
274290
it('should toggle the markAsDoneOnOpen checkbox', async () => {
275291
await act(async () => {
276292
renderWithAppContext(<NotificationSettings />, {

src/renderer/components/settings/NotificationSettings.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,27 @@ export const NotificationSettings: FC = () => {
328328
}
329329
/>
330330

331+
<Checkbox
332+
checked={settings.showReadNotifications}
333+
label="Show read notifications"
334+
name="showReadNotifications"
335+
onChange={(evt) =>
336+
updateSetting('showReadNotifications', evt.target.checked)
337+
}
338+
tooltip={
339+
<Stack direction="vertical" gap="condensed">
340+
<Text>
341+
When <Text as="u">checked</Text>, {APPLICATION.NAME} will
342+
display both read and unread notifications.
343+
</Text>
344+
<Text>
345+
When <Text as="u">unchecked</Text>, {APPLICATION.NAME} will only
346+
display unread notifications.
347+
</Text>
348+
</Stack>
349+
}
350+
/>
351+
331352
<Checkbox
332353
checked={settings.markAsDoneOnOpen}
333354
label="Mark as done on open"

src/renderer/context/defaults.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const defaultNotificationSettings: NotificationSettingsState = {
3636
showPills: true,
3737
showNumber: true,
3838
participating: false,
39+
showReadNotifications: true,
3940
markAsDoneOnOpen: false,
4041
markAsDoneOnUnsubscribe: false,
4142
delayNotificationState: false,

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

Lines changed: 55 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/renderer/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export interface NotificationSettingsState {
109109
showPills: boolean;
110110
showNumber: boolean;
111111
participating: boolean;
112+
showReadNotifications: boolean;
112113
markAsDoneOnOpen: boolean;
113114
markAsDoneOnUnsubscribe: boolean;
114115
delayNotificationState: boolean;

src/renderer/utils/notifications/filters/filter.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,34 @@ describe('renderer/utils/notifications/filters/filter.ts', () => {
6363
];
6464

6565
describe('filterBaseNotifications', () => {
66+
it('should show all notifications when showReadNotifications is enabled', () => {
67+
const notifications = [
68+
{ ...mockNotifications[0], unread: true },
69+
{ ...mockNotifications[1], unread: false },
70+
];
71+
const result = filterBaseNotifications(notifications, {
72+
...mockSettings,
73+
showReadNotifications: true,
74+
});
75+
76+
expect(result.length).toBe(2);
77+
expect(result).toEqual(notifications);
78+
});
79+
80+
it('should filter out read notifications when showReadNotifications is disabled', () => {
81+
const notifications = [
82+
{ ...mockNotifications[0], unread: true },
83+
{ ...mockNotifications[1], unread: false },
84+
];
85+
const result = filterBaseNotifications(notifications, {
86+
...mockSettings,
87+
showReadNotifications: false,
88+
});
89+
90+
expect(result.length).toBe(1);
91+
expect(result[0].unread).toBe(true);
92+
});
93+
6694
it('should filter notifications by subject type when provided', async () => {
6795
mockNotifications[0].subject.type = 'Issue';
6896
mockNotifications[1].subject.type = 'PullRequest';

src/renderer/utils/notifications/filters/filter.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ export function filterBaseNotifications(
2424
return notifications.filter((notification) => {
2525
let passesFilters = true;
2626

27+
// Filter out read notifications if showReadNotifications is disabled
28+
if (!settings.showReadNotifications && !notification.unread) {
29+
return false;
30+
}
31+
2732
// Apply base qualifier include/exclude filters (org, repo, etc.)
2833
for (const qualifier of BASE_SEARCH_QUALIFIERS) {
2934
if (!passesFilters) {

0 commit comments

Comments
 (0)