const SCROBBLE_ENDPOINT = "https://life.lab.unbl.ink/?scrobble_url="; const STOP_ENDPOINT = "https://life.lab.unbl.ink/?action=stop&scrobble_url="; // Default settings const DEFAULT_SETTINGS = { delay: 10, blacklist: ["*.unbl.ink", "moz-extension://"], paused: false, }; // Utility: wildcard match function matchPattern(url, pattern) { if (pattern.startsWith("*.")) { const domain = pattern.slice(2); return url.includes(domain); } return url.startsWith(pattern); } function isBlacklisted(url, blacklist) { return blacklist.some((p) => matchPattern(url, p)); } let activeTabs = new Map(); // Load settings async function getSettings() { return new Promise((resolve) => { browser.storage.local.get(DEFAULT_SETTINGS, (items) => resolve(items)); }); } // Save pause state async function setPaused(paused) { await browser.storage.local.set({ paused }); updateIcon(paused ? "pause" : "wait"); } function updateIcon(state) { const icons = { wait: "icons/wait.png", scrobbled: "icons/check.png", stopped: "icons/stop.png", pause: "icons/pause.png", }; browser.browserAction.setIcon({ path: icons[state] }); } // Handle tab updates browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => { if (changeInfo.status !== "complete" || !tab.url) return; const settings = await getSettings(); const { delay, blacklist, paused } = settings; if (paused || isBlacklisted(tab.url, blacklist)) return; if (tab.url.startsWith("moz-extension://")) return; const url = encodeURIComponent(tab.url); updateIcon("wait"); if (activeTabs.has(tabId)) clearTimeout(activeTabs.get(tabId)); const timeout = setTimeout(() => { fetch(`${SCROBBLE_ENDPOINT}${url}`).then(() => updateIcon("scrobbled")); }, delay * 1000); activeTabs.set(tabId, timeout); }); // Stop scrobble when navigating away or closing function stopScrobble(tabId, url) { getSettings().then(({ blacklist }) => { if (!url || isBlacklisted(url, blacklist)) return; if (url.startsWith("moz-extension://")) return; fetch(`${STOP_ENDPOINT}${encodeURIComponent(url)}`).then(() => updateIcon("stopped"), ); }); } browser.tabs.onRemoved.addListener((tabId) => { if (activeTabs.has(tabId)) clearTimeout(activeTabs.get(tabId)); }); //browser.webNavigation.onBeforeNavigate.addListener((details) => { // stopScrobble(details.tabId, details.url); //}); // Toggle pause on icon click browser.browserAction.onClicked.addListener(async () => { const { paused } = await getSettings(); setPaused(!paused); });