Skip to content

Commit e747eb7

Browse files
committed
feat(settings): make fetch interval user configurable
Signed-off-by: Adam Setch <[email protected]>
1 parent 56b98ec commit e747eb7

File tree

7 files changed

+95
-11
lines changed

7 files changed

+95
-11
lines changed

src/renderer/__mocks__/state-mocks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ const mockAppearanceSettings: AppearanceSettingsState = {
8989
const mockNotificationSettings: NotificationSettingsState = {
9090
groupBy: GroupBy.REPOSITORY,
9191
fetchType: FetchType.INTERVAL,
92+
fetchInterval: Constants.DEFAULT_FETCH_NOTIFICATIONS_INTERVAL_MS,
9293
fetchAllNotifications: true,
9394
detailedNotifications: true,
9495
showPills: true,

src/renderer/components/settings/NotificationSettings.tsx

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,26 @@ import {
44
BellIcon,
55
CheckIcon,
66
CommentIcon,
7+
DashIcon,
78
GitPullRequestIcon,
89
IssueOpenedIcon,
910
MilestoneIcon,
11+
PlusIcon,
12+
SyncIcon,
1013
TagIcon,
1114
} from '@primer/octicons-react';
12-
import { Stack, Text } from '@primer/react';
15+
import { Button, ButtonGroup, IconButton, Stack, Text } from '@primer/react';
16+
17+
import { formatDuration, millisecondsToMinutes } from 'date-fns';
1318

1419
import { APPLICATION } from '../../../shared/constants';
1520

21+
import { Constants } from '../../constants';
1622
import { AppContext } from '../../context/App';
1723
import { FetchType, GroupBy, Size } from '../../types';
1824
import { openGitHubParticipatingDocs } from '../../utils/links';
1925
import { Checkbox } from '../fields/Checkbox';
26+
import { FieldLabel } from '../fields/FieldLabel';
2027
import { RadioGroup } from '../fields/RadioGroup';
2128
import { Title } from '../primitives/Title';
2229

@@ -68,6 +75,74 @@ export const NotificationSettings: FC = () => {
6875
value={settings.fetchType}
6976
/>
7077

78+
<Stack
79+
align="center"
80+
className="text-sm"
81+
direction="horizontal"
82+
gap="condensed"
83+
>
84+
<FieldLabel label="Fetch interval:" name="fetchInterval" />
85+
86+
<ButtonGroup className="ml-2">
87+
<IconButton
88+
aria-label="Decrease fetch interval"
89+
data-testid="settings-decrease-fetch-interval"
90+
icon={DashIcon}
91+
onClick={() => {
92+
updateSetting(
93+
'fetchInterval',
94+
Math.max(
95+
settings.fetchInterval -
96+
Constants.FETCH_NOTIFICATIONS_INTERVAL_STEP_MS,
97+
Constants.MIN_FETCH_NOTIFICATIONS_INTERVAL_MS,
98+
),
99+
);
100+
}}
101+
size="small"
102+
unsafeDisableTooltip={true}
103+
/>
104+
105+
<Button aria-label="Fetch interval" disabled size="small">
106+
{formatDuration({
107+
minutes: millisecondsToMinutes(settings.fetchInterval),
108+
})}
109+
</Button>
110+
111+
<IconButton
112+
aria-label="Increase fetch interval"
113+
data-testid="settings-increase-fetch-interval"
114+
icon={PlusIcon}
115+
onClick={() => {
116+
updateSetting(
117+
'fetchInterval',
118+
Math.min(
119+
settings.fetchInterval +
120+
Constants.FETCH_NOTIFICATIONS_INTERVAL_STEP_MS,
121+
Constants.MAX_FETCH_NOTIFICATIONS_INTERVAL_MS,
122+
),
123+
);
124+
}}
125+
size="small"
126+
unsafeDisableTooltip={true}
127+
/>
128+
129+
<IconButton
130+
aria-label="Reset zoom"
131+
data-testid="settings-zoom-reset"
132+
icon={SyncIcon}
133+
onClick={() => {
134+
updateSetting(
135+
'fetchInterval',
136+
Constants.DEFAULT_FETCH_NOTIFICATIONS_INTERVAL_MS,
137+
);
138+
}}
139+
size="small"
140+
unsafeDisableTooltip={true}
141+
variant="danger"
142+
/>
143+
</ButtonGroup>
144+
</Stack>
145+
71146
<Checkbox
72147
checked={settings.fetchAllNotifications}
73148
label="Fetch all notifications"

src/renderer/constants.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ export const Constants = {
2020

2121
ALL_READ_EMOJIS: ['🎉', '🎊', '🥳', '👏', '🙌', '😎', '🏖️', '🚀', '✨', '🏆'],
2222

23-
FETCH_NOTIFICATIONS_INTERVAL_MS: 60 * 1000, // 1 minute
23+
DEFAULT_FETCH_NOTIFICATIONS_INTERVAL_MS: 60 * 1000, // 1 minute
24+
MIN_FETCH_NOTIFICATIONS_INTERVAL_MS: 60 * 1000, // 1 minute
25+
MAX_FETCH_NOTIFICATIONS_INTERVAL_MS: 60 * 60 * 1000, // 1 hour
26+
FETCH_NOTIFICATIONS_INTERVAL_STEP_MS: 60 * 1000, // 1 minute
2427

2528
REFRESH_ACCOUNTS_INTERVAL_MS: 60 * 60 * 1000, // 1 hour
2629

src/renderer/context/App.test.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,25 @@ describe('renderer/context/App.tsx', () => {
7777
);
7878

7979
act(() => {
80-
jest.advanceTimersByTime(Constants.FETCH_NOTIFICATIONS_INTERVAL_MS);
80+
jest.advanceTimersByTime(
81+
Constants.DEFAULT_FETCH_NOTIFICATIONS_INTERVAL_MS,
82+
);
8183
return;
8284
});
8385
expect(fetchNotificationsMock).toHaveBeenCalledTimes(2);
8486

8587
act(() => {
86-
jest.advanceTimersByTime(Constants.FETCH_NOTIFICATIONS_INTERVAL_MS);
88+
jest.advanceTimersByTime(
89+
Constants.DEFAULT_FETCH_NOTIFICATIONS_INTERVAL_MS,
90+
);
8791
return;
8892
});
8993
expect(fetchNotificationsMock).toHaveBeenCalledTimes(3);
9094

9195
act(() => {
92-
jest.advanceTimersByTime(Constants.FETCH_NOTIFICATIONS_INTERVAL_MS);
96+
jest.advanceTimersByTime(
97+
Constants.DEFAULT_FETCH_NOTIFICATIONS_INTERVAL_MS,
98+
);
9399
return;
94100
});
95101
expect(fetchNotificationsMock).toHaveBeenCalledTimes(4);

src/renderer/context/App.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,18 +148,14 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
148148
() => {
149149
fetchNotifications({ auth, settings });
150150
},
151-
settings.fetchType === FetchType.INTERVAL
152-
? Constants.FETCH_NOTIFICATIONS_INTERVAL_MS
153-
: null,
151+
settings.fetchType === FetchType.INTERVAL ? settings.fetchInterval : null,
154152
);
155153

156154
useInactivityTimer(
157155
() => {
158156
fetchNotifications({ auth, settings });
159157
},
160-
settings.fetchType === FetchType.INACTIVITY
161-
? Constants.FETCH_NOTIFICATIONS_INTERVAL_MS
162-
: null,
158+
settings.fetchType === FetchType.INACTIVITY ? settings.fetchInterval : null,
163159
);
164160

165161
useIntervalTimer(() => {

src/renderer/context/defaults.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Constants } from '../constants';
12
import {
23
type AppearanceSettingsState,
34
type AuthState,
@@ -27,6 +28,7 @@ const defaultAppearanceSettings: AppearanceSettingsState = {
2728
const defaultNotificationSettings: NotificationSettingsState = {
2829
groupBy: GroupBy.REPOSITORY,
2930
fetchType: FetchType.INTERVAL,
31+
fetchInterval: Constants.DEFAULT_FETCH_NOTIFICATIONS_INTERVAL_MS,
3032
fetchAllNotifications: true,
3133
detailedNotifications: true,
3234
showPills: true,

src/renderer/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export interface AppearanceSettingsState {
7979
export interface NotificationSettingsState {
8080
groupBy: GroupBy;
8181
fetchType: FetchType;
82+
fetchInterval: number;
8283
fetchAllNotifications: boolean;
8384
detailedNotifications: boolean;
8485
showPills: boolean;

0 commit comments

Comments
 (0)