Skip to content

Commit 5b349b2

Browse files
committed
feat: filter by handles
Signed-off-by: Adam Setch <[email protected]>
1 parent 43e7faf commit 5b349b2

File tree

22 files changed

+777
-283
lines changed

22 files changed

+777
-283
lines changed

src/renderer/__mocks__/state-mocks.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ const mockSystemSettings: SystemSettingsState = {
106106
};
107107

108108
const mockFilters: FilterSettingsState = {
109-
hideBots: false,
109+
filterUserTypes: [],
110+
filterIncludeHandles: [],
111+
filterExcludeHandles: [],
110112
filterReasons: [],
111113
};
112114

src/renderer/components/AllRead.test.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ describe('renderer/components/AllRead.tsx', () => {
3535
settings: {
3636
...mockSettings,
3737
filterReasons: ['author'],
38-
hideBots: true,
3938
},
4039
}}
4140
>

src/renderer/components/AllRead.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { type FC, useContext, useMemo } from 'react';
22

33
import { AppContext } from '../context/App';
44
import { Constants } from '../utils/constants';
5-
import { hasAnyFiltersSet } from '../utils/filters';
5+
import { hasAnyFiltersSet } from '../utils/notifications/filters/filter';
66
import { EmojiSplash } from './layout/EmojiSplash';
77

88
interface IAllRead {

src/renderer/components/Sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ import { APPLICATION } from '../../shared/constants';
1616
import { AppContext } from '../context/App';
1717
import { quitApp } from '../utils/comms';
1818
import { Constants } from '../utils/constants';
19-
import { hasAnyFiltersSet } from '../utils/filters';
2019
import {
2120
openGitHubIssues,
2221
openGitHubNotifications,
2322
openGitHubPulls,
2423
} from '../utils/links';
24+
import { hasAnyFiltersSet } from '../utils/notifications/filters/filter';
2525
import { getNotificationCount } from '../utils/notifications/notifications';
2626
import { LogoIcon } from './icons/LogoIcon';
2727

src/renderer/components/notifications/NotificationFooter.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Opacity, Size } from '../../types';
66
import type { Notification } from '../../typesGitHub';
77
import { cn } from '../../utils/cn';
88
import { openUserProfile } from '../../utils/links';
9-
import { formatReason } from '../../utils/reason';
9+
import { getReasonDetails } from '../../utils/reason';
1010
import { AvatarWithFallback } from '../avatars/AvatarWithFallback';
1111
import { MetricGroup } from '../metrics/MetricGroup';
1212

@@ -17,7 +17,7 @@ interface INotificationFooter {
1717
export const NotificationFooter: FC<INotificationFooter> = ({
1818
notification,
1919
}: INotificationFooter) => {
20-
const reason = formatReason(notification.reason);
20+
const reason = getReasonDetails(notification.reason);
2121

2222
return (
2323
<Stack

src/renderer/context/App.test.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,9 @@ describe('renderer/context/App.tsx', () => {
351351
} as AuthState,
352352
settings: {
353353
...mockSettings,
354-
hideBots: defaultSettings.hideBots,
354+
filterUserTypes: defaultSettings.filterUserTypes,
355+
filterIncludeHandles: defaultSettings.filterIncludeHandles,
356+
filterExcludeHandles: defaultSettings.filterExcludeHandles,
355357
filterReasons: defaultSettings.filterReasons,
356358
},
357359
});

src/renderer/context/App.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
type AppearanceSettingsState,
2020
type AuthState,
2121
type FilterSettingsState,
22+
type FilterValue,
2223
type GitifyError,
2324
GroupBy,
2425
type NotificationSettingsState,
@@ -97,7 +98,9 @@ const defaultSystemSettings: SystemSettingsState = {
9798
};
9899

99100
export const defaultFilters: FilterSettingsState = {
100-
hideBots: false,
101+
filterUserTypes: [],
102+
filterIncludeHandles: [],
103+
filterExcludeHandles: [],
101104
filterReasons: [],
102105
};
103106

@@ -129,6 +132,11 @@ interface AppContextState {
129132
clearFilters: () => void;
130133
resetSettings: () => void;
131134
updateSetting: (name: keyof SettingsState, value: SettingsValue) => void;
135+
updateFilter: (
136+
name: keyof FilterSettingsState,
137+
value: FilterValue,
138+
checked: boolean,
139+
) => void;
132140
}
133141

134142
export const AppContext = createContext<Partial<AppContextState>>({});
@@ -164,7 +172,13 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
164172
// biome-ignore lint/correctness/useExhaustiveDependencies: We only want fetchNotifications to be called for particular state changes
165173
useEffect(() => {
166174
fetchNotifications({ auth, settings });
167-
}, [auth.accounts, settings.filterReasons, settings.hideBots]);
175+
}, [
176+
auth.accounts,
177+
settings.filterUserTypes,
178+
settings.filterIncludeHandles,
179+
settings.filterExcludeHandles,
180+
settings.filterReasons,
181+
]);
168182

169183
useInterval(() => {
170184
fetchNotifications({ auth, settings });
@@ -225,6 +239,17 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
225239
[auth, settings],
226240
);
227241

242+
const updateFilter = useCallback(
243+
(name: keyof FilterSettingsState, value: FilterValue, checked: boolean) => {
244+
const updatedFilters = checked
245+
? [...settings[name], value]
246+
: settings[name].filter((item) => item !== value);
247+
248+
updateSetting(name, updatedFilters);
249+
},
250+
[updateSetting, settings],
251+
);
252+
228253
const isLoggedIn = useMemo(() => {
229254
return hasAccounts(auth);
230255
}, [auth]);
@@ -356,6 +381,7 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
356381
clearFilters,
357382
resetSettings,
358383
updateSetting,
384+
updateFilter,
359385
}}
360386
>
361387
{children}

src/renderer/routes/Filters.test.tsx

Lines changed: 73 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -65,89 +65,79 @@ describe('renderer/routes/Filters.tsx', () => {
6565
});
6666

6767
describe('Users section', () => {
68-
it('should not be able to toggle the hideBots checkbox when detailedNotifications is disabled', async () => {
69-
await act(async () => {
70-
render(
71-
<AppContext.Provider
72-
value={{
73-
auth: mockAuth,
74-
settings: {
75-
...mockSettings,
76-
detailedNotifications: false,
77-
hideBots: false,
78-
},
79-
notifications: [],
80-
updateSetting,
81-
}}
82-
>
83-
<MemoryRouter>
84-
<FiltersRoute />
85-
</MemoryRouter>
86-
</AppContext.Provider>,
87-
);
88-
});
89-
90-
expect(
91-
screen
92-
.getByLabelText('Hide notifications from Bot accounts')
93-
.closest('input'),
94-
).toHaveProperty('disabled', true);
95-
96-
// click the checkbox
97-
fireEvent.click(
98-
screen.getByLabelText('Hide notifications from Bot accounts'),
99-
);
100-
101-
// check if the checkbox is still unchecked
102-
expect(updateSetting).not.toHaveBeenCalled();
103-
104-
expect(
105-
screen.getByLabelText('Hide notifications from Bot accounts').parentNode
106-
.parentNode,
107-
).toMatchSnapshot();
108-
});
109-
110-
it('should be able to toggle the hideBots checkbox when detailedNotifications is enabled', async () => {
111-
await act(async () => {
112-
render(
113-
<AppContext.Provider
114-
value={{
115-
auth: mockAuth,
116-
settings: {
117-
...mockSettings,
118-
detailedNotifications: true,
119-
hideBots: false,
120-
},
121-
notifications: [],
122-
updateSetting,
123-
}}
124-
>
125-
<MemoryRouter>
126-
<FiltersRoute />
127-
</MemoryRouter>
128-
</AppContext.Provider>,
129-
);
130-
});
131-
132-
expect(
133-
screen
134-
.getByLabelText('Hide notifications from Bot accounts')
135-
.closest('input'),
136-
).toHaveProperty('disabled', false);
137-
138-
// click the checkbox
139-
fireEvent.click(
140-
screen.getByLabelText('Hide notifications from Bot accounts'),
141-
);
142-
143-
// check if the checkbox is still unchecked
144-
expect(updateSetting).toHaveBeenCalledWith('hideBots', true);
145-
146-
expect(
147-
screen.getByLabelText('Hide notifications from Bot accounts').parentNode
148-
.parentNode,
149-
).toMatchSnapshot();
150-
});
68+
// it('should not be able to toggle the hideBots checkbox when detailedNotifications is disabled', async () => {
69+
// await act(async () => {
70+
// render(
71+
// <AppContext.Provider
72+
// value={{
73+
// auth: mockAuth,
74+
// settings: {
75+
// ...mockSettings,
76+
// detailedNotifications: false,
77+
// },
78+
// notifications: [],
79+
// updateSetting,
80+
// }}
81+
// >
82+
// <MemoryRouter>
83+
// <FiltersRoute />
84+
// </MemoryRouter>
85+
// </AppContext.Provider>,
86+
// );
87+
// });
88+
// expect(
89+
// screen
90+
// .getByLabelText('Hide notifications from Bot accounts')
91+
// .closest('input'),
92+
// ).toHaveProperty('disabled', true);
93+
// // click the checkbox
94+
// fireEvent.click(
95+
// screen.getByLabelText('Hide notifications from Bot accounts'),
96+
// );
97+
// // check if the checkbox is still unchecked
98+
// expect(updateSetting).not.toHaveBeenCalled();
99+
// expect(
100+
// screen.getByLabelText('Hide notifications from Bot accounts').parentNode
101+
// .parentNode,
102+
// ).toMatchSnapshot();
103+
// });
104+
// it('should be able to toggle the hideBots checkbox when detailedNotifications is enabled', async () => {
105+
// await act(async () => {
106+
// render(
107+
// <AppContext.Provider
108+
// value={{
109+
// auth: mockAuth,
110+
// settings: {
111+
// ...mockSettings,
112+
// detailedNotifications: true,
113+
// hideBots: false,
114+
// },
115+
// notifications: [],
116+
// updateSetting,
117+
// }}
118+
// >
119+
// <MemoryRouter>
120+
// <FiltersRoute />
121+
// </MemoryRouter>
122+
// </AppContext.Provider>,
123+
// );
124+
// });
125+
// expect(
126+
// screen
127+
// .getByLabelText('Hide notifications from Bot accounts')
128+
// .closest('input'),
129+
// ).toHaveProperty('disabled', false);
130+
// // click the checkbox
131+
// fireEvent.click(
132+
// screen.getByLabelText('Hide notifications from Bot accounts'),
133+
// );
134+
// // check if the checkbox is still unchecked
135+
// expect(updateSetting).toHaveBeenCalledWith('hideBots', true);
136+
// expect(
137+
// screen.getByLabelText('Hide notifications from Bot accounts').parentNode
138+
// .parentNode,
139+
// ).toMatchSnapshot();
140+
// });
151141
});
152142

153143
describe('Reasons section', () => {

0 commit comments

Comments
 (0)