Skip to content

Commit 56b98ec

Browse files
authored
feat: ability to set fetch type (interval or inactivity) (#2301)
* feat: ability to set fetch type (interval or inactivity) Signed-off-by: Adam Setch <adam.setch@outlook.com> * feat: ability to set fetch type (interval or inactivity) Signed-off-by: Adam Setch <adam.setch@outlook.com> * feat: ability to set fetch type (interval or inactivity) Signed-off-by: Adam Setch <adam.setch@outlook.com> --------- Signed-off-by: Adam Setch <adam.setch@outlook.com>
1 parent 27caa0c commit 56b98ec

File tree

13 files changed

+287
-57
lines changed

13 files changed

+287
-57
lines changed

src/renderer/__mocks__/state-mocks.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
type Account,
44
type AppearanceSettingsState,
55
type AuthState,
6+
FetchType,
67
type FilterSettingsState,
78
type GitifyState,
89
type GitifyUser,
@@ -87,6 +88,7 @@ const mockAppearanceSettings: AppearanceSettingsState = {
8788

8889
const mockNotificationSettings: NotificationSettingsState = {
8990
groupBy: GroupBy.REPOSITORY,
91+
fetchType: FetchType.INTERVAL,
9092
fetchAllNotifications: true,
9193
detailedNotifications: true,
9294
showPills: true,

src/renderer/components/fields/FieldLabel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export interface IFieldLabel {
77

88
export const FieldLabel: FC<IFieldLabel> = (props: IFieldLabel) => {
99
return (
10-
<label className="mr-3 font-medium cursor-pointer" htmlFor={props.name}>
10+
<label className={'mr-1 font-medium cursor-pointer'} htmlFor={props.name}>
1111
{props.label}
1212
</label>
1313
);

src/renderer/components/fields/RadioGroup.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import type { ChangeEvent, FC } from 'react';
1+
import type { ChangeEvent, FC, ReactNode } from 'react';
22

33
import { Stack } from '@primer/react';
44

55
import type { RadioGroupItem } from '../../types';
66
import { FieldLabel } from './FieldLabel';
7+
import { Tooltip } from './Tooltip';
78

89
export interface IRadioGroup {
910
name: string;
1011
label: string;
1112
options: RadioGroupItem[];
1213
value: string;
1314
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
15+
tooltip?: ReactNode | string;
1416
}
1517

1618
export const RadioGroup: FC<IRadioGroup> = (props: IRadioGroup) => {
@@ -47,6 +49,10 @@ export const RadioGroup: FC<IRadioGroup> = (props: IRadioGroup) => {
4749
</Stack>
4850
);
4951
})}
52+
53+
{props.tooltip && (
54+
<Tooltip name={`tooltip-${props.name}`} tooltip={props.tooltip} />
55+
)}
5056
</Stack>
5157
);
5258
};

src/renderer/components/fields/__snapshots__/FieldLabel.test.tsx.snap

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

src/renderer/components/fields/__snapshots__/RadioGroup.test.tsx.snap

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

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,27 @@ describe('renderer/components/settings/NotificationSettings.tsx', () => {
3434
expect(updateSetting).toHaveBeenCalledWith('groupBy', 'DATE');
3535
});
3636

37+
it('should change the fetchType radio group', async () => {
38+
await act(async () => {
39+
render(
40+
<AppContext.Provider
41+
value={{
42+
auth: mockAuth,
43+
settings: mockSettings,
44+
updateSetting,
45+
}}
46+
>
47+
<NotificationSettings />
48+
</AppContext.Provider>,
49+
);
50+
});
51+
52+
await userEvent.click(screen.getByTestId('radio-fetchType-inactivity'));
53+
54+
expect(updateSetting).toHaveBeenCalledTimes(1);
55+
expect(updateSetting).toHaveBeenCalledWith('fetchType', 'INACTIVITY');
56+
});
57+
3758
it('should toggle the fetchAllNotifications checkbox', async () => {
3859
await act(async () => {
3960
render(

src/renderer/components/settings/NotificationSettings.tsx

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { Stack, Text } from '@primer/react';
1414
import { APPLICATION } from '../../../shared/constants';
1515

1616
import { AppContext } from '../../context/App';
17-
import { GroupBy, Size } from '../../types';
17+
import { FetchType, GroupBy, Size } from '../../types';
1818
import { openGitHubParticipatingDocs } from '../../utils/links';
1919
import { Checkbox } from '../fields/Checkbox';
2020
import { RadioGroup } from '../fields/RadioGroup';
@@ -41,6 +41,33 @@ export const NotificationSettings: FC = () => {
4141
value={settings.groupBy}
4242
/>
4343

44+
<RadioGroup
45+
label="Fetch type:"
46+
name="fetchType"
47+
onChange={(evt) => {
48+
updateSetting('fetchType', evt.target.value as FetchType);
49+
}}
50+
options={[
51+
{ label: 'Interval', value: FetchType.INTERVAL },
52+
{ label: 'Inactivity', value: FetchType.INACTIVITY },
53+
]}
54+
tooltip={
55+
<Stack direction="vertical" gap="condensed">
56+
<Text>Controls how new notifications are fetched.</Text>
57+
<Text>
58+
<Text as="strong">Interval</Text> will check for new
59+
notifications on a regular scheduled interval.
60+
</Text>
61+
<Text>
62+
<Text as="strong">Inactivity</Text> will check for new
63+
notifications only when there has been no user activity within{' '}
64+
{APPLICATION.NAME} for a specified period of time.
65+
</Text>
66+
</Stack>
67+
}
68+
value={settings.fetchType}
69+
/>
70+
4471
<Checkbox
4572
checked={settings.fetchAllNotifications}
4673
label="Fetch all notifications"
@@ -102,7 +129,7 @@ export const NotificationSettings: FC = () => {
102129
tooltip={
103130
<Stack direction="vertical" gap="condensed">
104131
<Text>Show notification metric pills for:</Text>
105-
<div className="pl-4">
132+
<div className="pl-2">
106133
<Stack direction="vertical" gap="none">
107134
<Stack direction="horizontal" gap="condensed">
108135
<IssueOpenedIcon size={Size.SMALL} />
@@ -140,27 +167,23 @@ export const NotificationSettings: FC = () => {
140167
tooltip={
141168
<Stack direction="vertical" gap="condensed">
142169
<Text>Show GitHub number for:</Text>
143-
<div className="pl-4">
144-
<ul>
145-
<li>
146-
<Stack direction="horizontal" gap="condensed">
147-
<CommentIcon size={Size.SMALL} />
148-
Discussion
149-
</Stack>
150-
</li>
151-
<li>
152-
<Stack direction="horizontal" gap="condensed">
153-
<IssueOpenedIcon size={Size.SMALL} />
154-
Issue
155-
</Stack>
156-
</li>
157-
<li>
158-
<Stack direction="horizontal" gap="condensed">
159-
<GitPullRequestIcon size={Size.SMALL} />
160-
Pull Request
161-
</Stack>
162-
</li>
163-
</ul>
170+
<div className="pl-2">
171+
<Stack direction="vertical" gap="none">
172+
<Stack direction="horizontal" gap="condensed">
173+
<CommentIcon size={Size.SMALL} />
174+
Discussion
175+
</Stack>
176+
177+
<Stack direction="horizontal" gap="condensed">
178+
<IssueOpenedIcon size={Size.SMALL} />
179+
Issue
180+
</Stack>
181+
182+
<Stack direction="horizontal" gap="condensed">
183+
<GitPullRequestIcon size={Size.SMALL} />
184+
Pull Request
185+
</Stack>
186+
</Stack>
164187
</div>
165188
</Stack>
166189
}

src/renderer/context/App.tsx

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
import { useTheme } from '@primer/react';
1111

1212
import { Constants } from '../constants';
13-
import { useInterval } from '../hooks/useInterval';
13+
import { useInactivityTimer } from '../hooks/timers/useInactivityTimer';
14+
import { useIntervalTimer } from '../hooks/timers/useIntervalTimer';
1415
import { useNotifications } from '../hooks/useNotifications';
1516
import type {
1617
Account,
@@ -24,6 +25,7 @@ import type {
2425
Status,
2526
Token,
2627
} from '../types';
28+
import { FetchType } from '../types';
2729
import type { Notification } from '../typesGitHub';
2830
import { headNotifications } from '../utils/api/client';
2931
import type {
@@ -142,11 +144,25 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
142144
settings.filterReasons,
143145
]);
144146

145-
useInterval(() => {
146-
fetchNotifications({ auth, settings });
147-
}, Constants.FETCH_NOTIFICATIONS_INTERVAL_MS);
147+
useIntervalTimer(
148+
() => {
149+
fetchNotifications({ auth, settings });
150+
},
151+
settings.fetchType === FetchType.INTERVAL
152+
? Constants.FETCH_NOTIFICATIONS_INTERVAL_MS
153+
: null,
154+
);
155+
156+
useInactivityTimer(
157+
() => {
158+
fetchNotifications({ auth, settings });
159+
},
160+
settings.fetchType === FetchType.INACTIVITY
161+
? Constants.FETCH_NOTIFICATIONS_INTERVAL_MS
162+
: null,
163+
);
148164

149-
useInterval(() => {
165+
useIntervalTimer(() => {
150166
for (const account of auth.accounts) {
151167
refreshAccount(account);
152168
}

src/renderer/context/defaults.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
type AppearanceSettingsState,
33
type AuthState,
4+
FetchType,
45
type FilterSettingsState,
56
GroupBy,
67
type NotificationSettingsState,
@@ -25,6 +26,7 @@ const defaultAppearanceSettings: AppearanceSettingsState = {
2526

2627
const defaultNotificationSettings: NotificationSettingsState = {
2728
groupBy: GroupBy.REPOSITORY,
29+
fetchType: FetchType.INTERVAL,
2830
fetchAllNotifications: true,
2931
detailedNotifications: true,
3032
showPills: true,

0 commit comments

Comments
 (0)