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

gitify-app / gitify / 12586431667

02 Jan 2025 05:40PM UTC coverage: 87.209%. Remained the same
12586431667

Pull #1700

github

web-flow
Merge 35a8d97a0 into 0e8d27442
Pull Request #1700: build(deps): bump cross-spawn from 7.0.3 to 7.0.6

591 of 656 branches covered (90.09%)

Branch coverage included in aggregate %.

1584 of 1838 relevant lines covered (86.18%)

24.61 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 { useCallback, useState } from 'react';
70✔
2

3
import { logError } from '../../shared/logger';
70✔
4
import type {
5
  Account,
6
  AccountNotifications,
7
  GitifyError,
8
  GitifyState,
9
  Status,
10
} from '../types';
11
import type { Notification } from '../typesGitHub';
12
import {
70✔
13
  ignoreNotificationThreadSubscription,
14
  markNotificationThreadAsDone,
15
  markNotificationThreadAsRead,
16
} from '../utils/api/client';
17
import { isMarkAsDoneFeatureSupported } from '../utils/features';
70✔
18
import {
70✔
19
  getAllNotifications,
20
  setTrayIconColor,
21
  triggerNativeNotifications,
22
} from '../utils/notifications';
23
import { removeNotifications } from '../utils/notifications/remove';
70✔
24

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

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

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

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

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

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

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

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

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

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

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

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

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

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

122
        setNotifications(updatedNotifications);
2✔
123
        setTrayIconColor(updatedNotifications);
2✔
124
      } catch (err) {
125
        logError(
2✔
126
          'markNotificationsAsRead',
127
          'Error occurred while marking notifications as read',
128
          err,
129
        );
130
      }
131

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

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

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

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

160
        setNotifications(updatedNotifications);
2✔
161
        setTrayIconColor(updatedNotifications);
2✔
162
      } catch (err) {
163
        logError(
2✔
164
          'markNotificationsAsDone',
165
          'Error occurred while marking notifications as done',
166
          err,
167
        );
168
      }
169

170
      setStatus('success');
4✔
171
    },
172
    [notifications],
173
  );
174

175
  const unsubscribeNotification = useCallback(
66✔
176
    async (state: GitifyState, notification: Notification) => {
177
      setStatus('loading');
6✔
178

179
      try {
6✔
180
        await ignoreNotificationThreadSubscription(
6✔
181
          notification.id,
182
          notification.account.hostname,
183
          notification.account.token,
184
        );
185

186
        if (state.settings.markAsDoneOnUnsubscribe) {
×
187
          await markNotificationsAsDone(state, [notification]);
×
188
        } else {
189
          await markNotificationsAsRead(state, [notification]);
×
190
        }
191
      } catch (err) {
192
        logError(
6✔
193
          'unsubscribeNotification',
194
          'Error occurred while unsubscribing from notification thread',
195
          err,
196
          notification,
197
        );
198
      }
199

200
      setStatus('success');
6✔
201
    },
202
    [markNotificationsAsRead, markNotificationsAsDone],
203
  );
204

205
  return {
66✔
206
    status,
207
    globalError,
208
    notifications,
209

210
    removeAccountNotifications,
211
    fetchNotifications,
212
    markNotificationsAsRead,
213
    markNotificationsAsDone,
214
    unsubscribeNotification,
215
  };
216
};
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