• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gitify-app / gitify / 12533105650

29 Dec 2024 06:18AM UTC coverage: 87.192% (-0.1%) from 87.298%
12533105650

Pull #1694

github

web-flow
Merge 3123e819c into ba4ce9ebe
Pull Request #1694: feat: limit auto updater

587 of 652 branches covered (90.03%)

Branch coverage included in aggregate %.

0 of 2 new or added lines in 1 file covered. (0.0%)

1571 of 1823 relevant lines covered (86.18%)

24.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.81
/src/renderer/hooks/useNotifications.ts
1
import log from 'electron-log';
70✔
2
import { useCallback, useState } from 'react';
70✔
3
import type {
4
  Account,
5
  AccountNotifications,
6
  GitifyError,
7
  GitifyState,
8
  Status,
9
} from '../types';
10
import type { Notification } from '../typesGitHub';
11
import {
70✔
12
  ignoreNotificationThreadSubscription,
13
  markNotificationThreadAsDone,
14
  markNotificationThreadAsRead,
15
} from '../utils/api/client';
16
import { isMarkAsDoneFeatureSupported } from '../utils/features';
70✔
17
import {
70✔
18
  getAllNotifications,
19
  setTrayIconColor,
20
  triggerNativeNotifications,
21
} from '../utils/notifications';
22
import { removeNotifications } from '../utils/notifications/remove';
70✔
23

24
interface NotificationsState {
25
  notifications: AccountNotifications[];
26
  removeAccountNotifications: (account: Account) => Promise<void>;
27
  fetchNotifications: (state: GitifyState) => Promise<void>;
28
  markNotificationsAsRead: (
29
    state: GitifyState,
30
    notifications: Notification[],
31
  ) => Promise<void>;
32
  markNotificationsAsDone: (
33
    state: GitifyState,
34
    notifications: Notification[],
35
  ) => Promise<void>;
36
  unsubscribeNotification: (
37
    state: GitifyState,
38
    notification: Notification,
39
  ) => Promise<void>;
40
  status: Status;
41
  globalError: GitifyError;
42
}
43

44
export const useNotifications = (): NotificationsState => {
70✔
45
  const [status, setStatus] = useState<Status>('success');
66✔
46
  const [globalError, setGlobalError] = useState<GitifyError>();
66✔
47

48
  const [notifications, setNotifications] = useState<AccountNotifications[]>(
66✔
49
    [],
50
  );
51

52
  const removeAccountNotifications = useCallback(
66✔
53
    async (account: Account) => {
54
      setStatus('loading');
×
55

56
      const updatedNotifications = notifications.filter(
×
57
        (notification) => notification.account !== account,
×
58
      );
59

60
      setNotifications(updatedNotifications);
×
61
      setTrayIconColor(updatedNotifications);
×
62
      setStatus('success');
×
63
    },
64
    [notifications],
65
  );
66

67
  const fetchNotifications = useCallback(
66✔
68
    async (state: GitifyState) => {
69
      setStatus('loading');
8✔
70
      setGlobalError(null);
8✔
71

72
      const fetchedNotifications = await getAllNotifications(state);
8✔
73

74
      // Set Global Error if all accounts have the same error
75
      const allAccountsHaveErrors = fetchedNotifications.every((account) => {
8✔
76
        return account.error !== null;
12✔
77
      });
78
      let accountErrorsAreAllSame = true;
8✔
79
      const accountError = fetchedNotifications[0]?.error;
8✔
80
      for (const fetchedNotification of fetchedNotifications) {
8✔
81
        if (accountError !== fetchedNotification.error) {
14✔
82
          accountErrorsAreAllSame = false;
2✔
83
          break;
2✔
84
        }
85
      }
86

87
      if (allAccountsHaveErrors) {
8✔
88
        setStatus('error');
4✔
89
        setGlobalError(accountErrorsAreAllSame ? accountError : null);
4✔
90
        return;
4✔
91
      }
92

93
      setNotifications(fetchedNotifications);
4✔
94
      triggerNativeNotifications(notifications, fetchedNotifications, state);
4✔
95
      setStatus('success');
4✔
96
    },
97
    [notifications],
98
  );
99

100
  const markNotificationsAsRead = useCallback(
66✔
101
    async (state: GitifyState, readNotifications: Notification[]) => {
102
      setStatus('loading');
4✔
103

104
      try {
4✔
105
        await Promise.all(
4✔
106
          readNotifications.map((notification) =>
107
            markNotificationThreadAsRead(
4✔
108
              notification.id,
109
              notification.account.hostname,
110
              notification.account.token,
111
            ),
112
          ),
113
        );
114

115
        const updatedNotifications = removeNotifications(
2✔
116
          state.settings,
117
          readNotifications,
118
          notifications,
119
        );
120

121
        setNotifications(updatedNotifications);
2✔
122
        setTrayIconColor(updatedNotifications);
2✔
123
      } catch (err) {
124
        log.error(
2✔
125
          '[markNotificationsAsRead]: Error occurred while marking notifications as read',
126
          err,
127
        );
128
      }
129

130
      setStatus('success');
4✔
131
    },
132
    [notifications],
133
  );
134

135
  const markNotificationsAsDone = useCallback(
66✔
136
    async (state: GitifyState, doneNotifications: Notification[]) => {
137
      setStatus('loading');
4✔
138

139
      try {
4✔
140
        if (isMarkAsDoneFeatureSupported(doneNotifications[0].account)) {
4✔
141
          await Promise.all(
4✔
142
            doneNotifications.map((notification) =>
143
              markNotificationThreadAsDone(
4✔
144
                notification.id,
145
                notification.account.hostname,
146
                notification.account.token,
147
              ),
148
            ),
149
          );
150
        }
151

152
        const updatedNotifications = removeNotifications(
2✔
153
          state.settings,
154
          doneNotifications,
155
          notifications,
156
        );
157

158
        setNotifications(updatedNotifications);
2✔
159
        setTrayIconColor(updatedNotifications);
2✔
160
      } catch (err) {
161
        log.error(
2✔
162
          '[markNotificationsAsDone]: error occurred while marking notifications as done',
163
          err,
164
        );
165
      }
166

167
      setStatus('success');
4✔
168
    },
169
    [notifications],
170
  );
171

172
  const unsubscribeNotification = useCallback(
66✔
173
    async (state: GitifyState, notification: Notification) => {
174
      setStatus('loading');
6✔
175

176
      try {
6✔
177
        await ignoreNotificationThreadSubscription(
6✔
178
          notification.id,
179
          notification.account.hostname,
180
          notification.account.token,
181
        );
182

183
        if (state.settings.markAsDoneOnUnsubscribe) {
×
184
          await markNotificationsAsDone(state, [notification]);
×
185
        } else {
186
          await markNotificationsAsRead(state, [notification]);
×
187
        }
188
      } catch (err) {
189
        log.error(
6✔
190
          '[unsubscribeNotification]: error occurred while unsubscribing from notification thread',
191
          err,
192
        );
193
      }
194

195
      setStatus('success');
6✔
196
    },
197
    [markNotificationsAsRead, markNotificationsAsDone],
198
  );
199

200
  return {
66✔
201
    status,
202
    globalError,
203
    notifications,
204

205
    removeAccountNotifications,
206
    fetchNotifications,
207
    markNotificationsAsRead,
208
    markNotificationsAsDone,
209
    unsubscribeNotification,
210
  };
211
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc