import { REFRESH_TIMEOUT, API_URLS, BADGE_COLORS } from './config.js'; document.querySelector('html').setAttribute('lang', browser.i18n.getUILanguage()); browser.runtime.onInstalled.addListener(async (details) => { if (details.reason === 'install') { await browser.tabs.create({ url: 'https://www.usrspace.at/', }); } }); /** * @param {string} url * @returns {Promise} */ async function fetchJson(url) { const response = await fetch(url); return response.json(); } /** * @param {number} days * @returns {Promise>} */ function fetchCalendar(days = 28) { let url = `${API_URLS.calender}?o=json`; if (days) { url += `&r=${days}`; } return fetchJson(url); } /** * @returns {Promise} */ function fetchSpaceApi() { return fetchJson(API_URLS.spaceApi); } async function fetchNewData() { try { const result = await Promise.allSettled([fetchCalendar(), fetchSpaceApi()]); const calendarJson = result[0].value; const spaceApiJson = result[1].value; if (spaceApiJson) { const now = new Date(); const eventActive = calendarJson?.some((event) => ( new Date(event.begin) <= now && now <= new Date(event.end) )) ?? false; const badgeText = browser.i18n.getMessage(spaceApiJson.state.open ? 'badgeOpen' : eventActive ? 'badgeEvent' : 'badgeClosed'); const badgeBgColor = spaceApiJson.state.open ? BADGE_COLORS.open : eventActive ? BADGE_COLORS.event : BADGE_COLORS.closed; await browser.action.setBadgeText({text: badgeText}); await browser.action.setBadgeBackgroundColor({color: badgeBgColor}); const {spaceApi} = await browser.storage.local.get('spaceApi'); if (spaceApi && spaceApi.state.open !== spaceApiJson.state.open) { const state = browser.i18n.getMessage(spaceApiJson.state.open ? 'open' : 'closed'); await browser.notifications.create('status-change', { type: 'basic', title: browser.i18n.getMessage('stateNotificationTitle'), message: browser.i18n.getMessage('stateNotificationMessage', state), iconUrl: browser.runtime.getURL('icons/favicon.svg'), }); } } await browser.storage.local.set({ calendar: calendarJson, spaceApi: spaceApiJson, }); } catch (error) { console.error(error); } } browser.runtime.onStartup.addListener(async () => { await browser.storage.local.remove(['calendar', 'spaceApi']); }); /** * @param {Alarm} alarm */ function handleAlarm(alarm) { if (alarm.name === 'fetchData') { fetchNewData(); } } function startFetching() { fetchNewData(); browser.alarms.onAlarm.addListener(handleAlarm); const now = new Date(); now.setMinutes(Math.ceil((now.getMinutes() + 1) / REFRESH_TIMEOUT) * REFRESH_TIMEOUT, 0, 0); browser.alarms.create('fetchData', { when: now.getTime(), periodInMinutes: REFRESH_TIMEOUT, }); } globalThis.addEventListener('offline', async () => { browser.alarms.onAlarm.removeListener(handleAlarm); await browser.alarms.clear('fetchData'); }); globalThis.addEventListener('online', () => { startFetching(); }); if (globalThis.navigator.onLine) { startFetching(); }