Skip to content

Commit 21fdbbc

Browse files
committed
fix: background
1 parent 40923b3 commit 21fdbbc

File tree

1 file changed

+66
-89
lines changed

1 file changed

+66
-89
lines changed

src/background/index.ts

Lines changed: 66 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -128,25 +128,22 @@ async function getFollowedStreams(userId: string) {
128128
return followedStreams;
129129
}
130130

131-
async function filterFollowedStreams(streams: HelixStream[]) {
132-
const [followedStreams, settings] = await Promise.all([
133-
stores.followedStreams.get(),
134-
stores.settings.get(),
135-
]);
131+
async function filterNewStreams(newStreams: HelixStream[], oldStreams: HelixStream[]) {
132+
const settings = await stores.settings.get();
136133

137134
const {
138135
notifications: { ignoredCategories, selectedUsers, withCategoryChanges, withFilters },
139136
} = settings;
140137

141-
return streams.filter((stream) => {
138+
return newStreams.filter((stream) => {
142139
if (
143140
(withFilters && !selectedUsers.includes(stream.userId)) ||
144-
ignoredCategories.some(matchString.bind(null, stream.gameName))
141+
ignoredCategories.some((input) => matchString(stream.gameName, input))
145142
) {
146143
return false;
147144
}
148145

149-
const oldStream = find(followedStreams, {
146+
const oldStream = find(oldStreams, {
150147
userId: stream.userId,
151148
});
152149

@@ -166,7 +163,7 @@ async function refreshCurrentUser(accessToken: string | null) {
166163
return currentUser;
167164
}
168165

169-
async function refreshFollowedStreams(user: HelixUser, showNotifications = true) {
166+
async function refreshFollowedStreams(user: HelixUser) {
170167
const settings = await stores.settings.get();
171168

172169
let followedStreams = new Array<HelixStream>();
@@ -177,66 +174,70 @@ async function refreshFollowedStreams(user: HelixUser, showNotifications = true)
177174
if (!settings.streams.withReruns) {
178175
remove(followedStreams, isRerunStream);
179176
}
180-
181-
if (showNotifications && settings.notifications.enabled) {
182-
const streams = await filterFollowedStreams(followedStreams);
183-
const users = await getUsersByIds(map(streams, "userId"));
184-
185-
settlePromises(streams, async (stream) => {
186-
const create = (iconUrl = browser.runtime.getURL("icon-96.png")) =>
187-
browser.notifications.create(`${Date.now()}:stream:${stream.userLogin}`, {
188-
title: t(`notificationMessage_stream${stream.gameName ? "Playing" : "Online"}`, [
189-
stream.userName || stream.userLogin,
190-
stream.gameName,
191-
]),
192-
message: stream.title || t("detailText_noTitle"),
193-
type: "basic",
194-
iconUrl,
195-
});
196-
197-
try {
198-
const user = find(users, {
199-
id: stream.userId,
200-
});
201-
202-
if (user) {
203-
return await create(user.profileImageUrl);
204-
}
205-
} catch {} // eslint-disable-line no-empty
206-
207-
await create();
208-
});
209-
}
210177
}
211178

212179
await stores.followedStreams.set(followedStreams);
213180
}
214181

215-
async function refresh(withNotifications: boolean) {
182+
async function refresh() {
216183
try {
217184
const user = await refreshCurrentUser(await stores.accessToken.get());
218185

219186
if (user) {
220-
await refreshFollowedStreams(user, withNotifications);
187+
await refreshFollowedStreams(user);
221188
}
222189
} catch {} // eslint-disable-line no-empty
223190

191+
browser.alarms.clearAll();
224192
browser.alarms.create("refresh", {
225193
delayInMinutes: 1,
226194
});
227195
}
228196

229-
async function refreshActionBadge() {
230-
const [currentUser, followedStreams, settings] = await Promise.all([
197+
async function sendNotifications(newStreams: HelixStream[], oldStreams: HelixStream[]) {
198+
const settings = await stores.settings.get();
199+
200+
if (settings.notifications.enabled) {
201+
const filteredStreams = await filterNewStreams(newStreams, oldStreams);
202+
const users = await getUsersByIds(map(filteredStreams, "userId"));
203+
204+
settlePromises(filteredStreams, async (stream) => {
205+
const create = (iconUrl = browser.runtime.getURL("icon-96.png")) =>
206+
browser.notifications.create(`${Date.now()}:stream:${stream.userLogin}`, {
207+
title: t(`notificationMessage_stream${stream.gameName ? "Playing" : "Online"}`, [
208+
stream.userName || stream.userLogin,
209+
stream.gameName,
210+
]),
211+
message: stream.title || t("detailText_noTitle"),
212+
type: "basic",
213+
iconUrl,
214+
});
215+
216+
try {
217+
const user = find(users, {
218+
id: stream.userId,
219+
});
220+
221+
if (user) {
222+
return await create(user.profileImageUrl);
223+
}
224+
} catch {} // eslint-disable-line no-empty
225+
226+
await create();
227+
});
228+
}
229+
}
230+
231+
async function refreshActionBadge(count: number) {
232+
const [currentUser, settings] = await Promise.all([
231233
stores.currentUser.get(),
232-
stores.followedStreams.get(),
233234
stores.settings.get(),
234235
]);
235236

236237
let text = "";
237238

238-
if (settings.badge.enabled && followedStreams.length > 0) {
239-
text = followedStreams.length.toLocaleString("en-US");
239+
if (settings.badge.enabled && count > 0) {
240+
text = count.toLocaleString("en-US");
240241
}
241242

242243
const getIconPath = (size: number) =>
@@ -288,19 +289,14 @@ async function authorize() {
288289
return openUrl(AUTHORIZE_URL, undefined, true);
289290
}
290291

291-
async function setup(): Promise<void> {
292-
await settlePromises(Object.values(stores), (store) => store.migrate());
293-
await refresh(false);
294-
}
295-
296292
async function reset(): Promise<void> {
297293
await Promise.allSettled([
298294
browser.storage.local.clear(),
299295
browser.storage.session.clear(),
300296
browser.storage.sync.clear(),
301297
]);
302298

303-
await setup();
299+
await refresh();
304300
}
305301

306302
async function revoke() {
@@ -322,19 +318,7 @@ async function revoke() {
322318
await stores.accessToken.reset();
323319
}
324320

325-
const messageHandlers: Dictionary<(...args: any[]) => Promise<any>> = {
326-
authorize,
327-
backup,
328-
refresh,
329-
request,
330-
reset,
331-
restore,
332-
revoke,
333-
};
334-
335-
browser.alarms.onAlarm.addListener((alarm) => {
336-
refresh(Date.now() < alarm.scheduledTime + 300_000);
337-
});
321+
browser.alarms.onAlarm.addListener(() => refresh());
338322

339323
browser.notifications.onClicked.addListener((notificationId) => {
340324
const [, type, data] = notificationId.split(":");
@@ -348,13 +332,15 @@ browser.notifications.onClicked.addListener((notificationId) => {
348332
}
349333
});
350334

351-
browser.runtime.onInstalled.addListener(() => {
352-
setup();
353-
});
354-
355-
browser.runtime.onStartup.addListener(() => {
356-
setup();
357-
});
335+
const messageHandlers: Dictionary<(...args: any[]) => Promise<any>> = {
336+
authorize,
337+
backup,
338+
refresh,
339+
request,
340+
reset,
341+
restore,
342+
revoke,
343+
};
358344

359345
browser.runtime.onMessage.addListener((message) => {
360346
const { [message.type]: handler } = messageHandlers;
@@ -382,24 +368,15 @@ browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
382368
}
383369
});
384370

385-
stores.accessToken.onChange(() => {
386-
refresh(false);
387-
});
388-
389-
stores.followedStreams.onChange(() => {
390-
refreshActionBadge();
391-
});
392-
393-
stores.settings.onChange(() => {
394-
refreshActionBadge();
395-
});
371+
stores.accessToken.onChange(() => refresh());
372+
stores.settings.onChange(() => refresh());
396373

397-
async function checkAlarm() {
398-
if (await browser.alarms.get("refresh")) {
399-
return;
374+
stores.followedStreams.onChange((newValue, oldValue) => {
375+
if (Array.isArray(oldValue)) {
376+
sendNotifications(newValue, oldValue);
400377
}
401378

402-
refresh(false);
403-
}
379+
refreshActionBadge(newValue.length);
380+
});
404381

405-
checkAlarm();
382+
refresh();

0 commit comments

Comments
 (0)