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

gitify-app / gitify / 12299745471

12 Dec 2024 03:38PM UTC coverage: 87.322% (-0.04%) from 87.358%
12299745471

Pull #1673

github

web-flow
Merge 1ec0fa2e2 into 60c0ced92
Pull Request #1673: refactor: use semver to parse header and perform comparisons

586 of 649 branches covered (90.29%)

Branch coverage included in aggregate %.

3 of 3 new or added lines in 1 file covered. (100.0%)

1556 of 1804 relevant lines covered (86.25%)

24.54 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('Error occurred while marking notification as read', err);
2✔
125
      }
126

127
      setStatus('success');
4✔
128
    },
129
    [notifications],
130
  );
131

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

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

149
        const updatedNotifications = removeNotifications(
2✔
150
          state.settings,
151
          doneNotifications,
152
          notifications,
153
        );
154

155
        setNotifications(updatedNotifications);
2✔
156
        setTrayIconColor(updatedNotifications);
2✔
157
      } catch (err) {
158
        log.error('Error occurred while marking notifications as done', err);
2✔
159
      }
160

161
      setStatus('success');
4✔
162
    },
163
    [notifications],
164
  );
165

166
  const unsubscribeNotification = useCallback(
66✔
167
    async (state: GitifyState, notification: Notification) => {
168
      setStatus('loading');
6✔
169

170
      try {
6✔
171
        await ignoreNotificationThreadSubscription(
6✔
172
          notification.id,
173
          notification.account.hostname,
174
          notification.account.token,
175
        );
176

177
        if (state.settings.markAsDoneOnUnsubscribe) {
×
178
          await markNotificationsAsDone(state, [notification]);
×
179
        } else {
180
          await markNotificationsAsRead(state, [notification]);
×
181
        }
182
      } catch (err) {
183
        log.error(
6✔
184
          'Error occurred while unsubscribing from notification thread',
185
          err,
186
        );
187
      }
188

189
      setStatus('success');
6✔
190
    },
191
    [markNotificationsAsRead, markNotificationsAsDone],
192
  );
193

194
  return {
66✔
195
    status,
196
    globalError,
197
    notifications,
198

199
    removeAccountNotifications,
200
    fetchNotifications,
201
    markNotificationsAsRead,
202
    markNotificationsAsDone,
203
    unsubscribeNotification,
204
  };
205
};
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