import browser from 'webextension-polyfill' import dayjs from 'dayjs' import { dashboard } from '../shared/utils' import { insertLog, normalizeTimestamp, DB } from '../shared/db' import { getSettingsWithDefaults, getUsageForHost, percentagesToBool } from '../shared/lib' import { DismissValidator, checkForErrors } from '../shared/validation' browser.browserAction.onClicked.addListener(() => browser.tabs.create({ url: dashboard, active: true })) const frequency = 1000 async function log() { try { const tabs = await browser.tabs.query({}) const windows = await browser.windows.getAll() const active = tabs .filter((tab) => { const window = windows.find((window) => window.id === tab.windowId) return tab.active && window.focused }) .map(({ url, audible, mutedInfo }) => { const { host } = new URL(url) return { host, audio: audible && !mutedInfo.muted } }) .filter((x) => x.host) if (active.length === 0) return const settings = await getSettingsWithDefaults() let idle = false if (settings.idleTimeout > 0) { idle = dayjs(settings.lastActivity).add(settings.idleTimeout, 'minutes').isBefore(dayjs()) } const inserted = active .filter((tab) => !idle || tab.audio) .map((tab) => { return insertLog({ timestamp: normalizeTimestamp(new Date()), host: tab.host, seconds: (frequency / 1000) | 0, }) }) await Promise.all(inserted) } catch (e) { console.error(e) } } async function deleteOldLogs() { const { retention } = await browser.storage.local.get() const maxAge = dayjs().startOf('day').subtract(retention, 'days').toDate() const toDelete = await DB.logs.where('timestamp').below(maxAge).toArray() const ids = toDelete.map((log) => log.id) await DB.logs.bulkDelete(ids) } setInterval(deleteOldLogs, 5 * 60 * 1000) // Delete old logs every 5 minutes setInterval(log, frequency) browser.runtime.onMessage.addListener((message, sender, sendResponse) => { switch (message.type) { case 'check': return getUsageForHost(message.host).then((percentages) => percentagesToBool(percentages)) case 'report': DB.settings.put({ key: 'lastActivity', value: new Date() }) break case 'dismiss': const entry = { host: message.host, timestamp: new Date(), duration: message.duration, } if (!checkForErrors(DismissValidator, entry)) DB.dismiss.put(entry) break } })