Fix all the scrobbling

This commit is contained in:
2025-10-20 11:18:23 -04:00
parent f28813b667
commit e255898778

View File

@ -1,8 +1,10 @@
const SCROBBLE_ENDPOINT = "https://life.lab.unbl.ink/?scrobble_url="; // ======== Life Scrobbler Extension ========
const STOP_ENDPOINT = "https://life.lab.unbl.ink/?action=stop&scrobble_url="; // Fully self-contained version with base64 icons
// Stop scrobble code is commented out for now
// ====== Default Settings ======
const DEFAULT_SETTINGS = { const DEFAULT_SETTINGS = {
delay: 7, delay: 8,
blacklist: [ blacklist: [
"*.unbl.ink", "*.unbl.ink",
"moz-extension://", "moz-extension://",
@ -21,9 +23,23 @@ const DEFAULT_SETTINGS = {
"*.todoist.com", "*.todoist.com",
], ],
paused: false, paused: false,
siteDelays: { "readscomisconline.ru": 1 }, siteDelays: { "readcomicsonline.ru": 1 },
scrobbleBaseUrl: "https://life.lab.unbl.ink",
}; };
// ====== Base64 icons ======
const ICONS = {
wait: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...",
scrobbled: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...",
stopped: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...",
pause: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...",
};
// ====== State ======
let activeTabs = new Map(); // tabId -> timeout
let pausedTabs = new Set(); // tabIds that are paused
// ====== Utility Functions ======
function matchPattern(url, pattern) { function matchPattern(url, pattern) {
if (pattern.startsWith("*.")) { if (pattern.startsWith("*.")) {
const domain = pattern.slice(2); const domain = pattern.slice(2);
@ -36,11 +52,56 @@ function isBlacklisted(url, blacklist) {
return blacklist.some((p) => matchPattern(url, p)); return blacklist.some((p) => matchPattern(url, p));
} }
async function getSettings() {
return new Promise((resolve) => {
browser.storage.local.get(DEFAULT_SETTINGS, resolve);
});
}
async function setPaused(tabId, paused) {
if (paused) pausedTabs.add(tabId);
else pausedTabs.delete(tabId);
updateIcon(tabId, paused ? "pause" : "wait");
// persist globally
await browser.storage.local.set({ paused });
}
function updateIcon(tabId, state) {
browser.browserAction.setIcon({ path: ICONS[state], tabId });
}
// ====== Scrobble Start ======
async function scrobbleStart(url, baseUrl) {
const endpoint = `${baseUrl}/?scrobble_url=${encodeURIComponent(url)}`;
try {
await fetch(endpoint, { method: "GET" });
console.log("LifeScrobbler: scrobbled", url);
} catch (err) {
console.error("LifeScrobbler: failed scrobble", url, err);
}
}
// ====== Scrobble Stop ======
async function scrobbleStop(url, baseUrl) {
const endpoint = `${baseUrl}/?action=stop&scrobble_url=${encodeURIComponent(url)}`;
try {
await fetch(endpoint, { method: "GET" });
console.log("LifeScrobbler: stopped", url);
} catch (err) {
console.error("LifeScrobbler: stop failed", url, err);
}
}
// ====== Delay for given URL ======
function getDelayForUrl(url, settings) { function getDelayForUrl(url, settings) {
try { try {
const u = new URL(url); const u = new URL(url);
console.log(u);
for (const [domain, customDelay] of Object.entries(settings.siteDelays)) { for (const [domain, customDelay] of Object.entries(settings.siteDelays)) {
console.log(domain, customDelay, u.hostname, domain == u.hostname);
if (u.hostname.includes(domain)) { if (u.hostname.includes(domain)) {
console.log("Found custom delay of ", customDelay);
return customDelay; return customDelay;
} }
} }
@ -48,44 +109,28 @@ function getDelayForUrl(url, settings) {
return settings.delay; return settings.delay;
} }
let activeTabs = new Map(); // ====== Tab Updates ======
// 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) => { browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
if (changeInfo.status !== "complete" || !tab.url) return; if (changeInfo.status !== "complete" || !tab.url) return;
const settings = await getSettings();
const { delay, blacklist, paused } = await getSettings();
if (paused || isBlacklisted(tab.url, blacklist)) return; const { delay, blacklist, scrobbleBaseUrl, paused } = await getSettings();
if (tab.url.startsWith("moz-extension://")) return; const url = tab.url;
const url = encodeURIComponent(tab.url); // Skip if globally paused or blacklisted
updateIcon("wait"); console.log(
"Globally paused? ",
paused,
" - Is this tab paused? ",
pausedTabs.has(tabId),
" - Is site blacklisted? ",
isBlacklisted(url, blacklist),
);
if (paused || pausedTabs.has(tabId) || isBlacklisted(url, blacklist)) return;
updateIcon(tabId, "wait");
const siteDelay = getDelayForUrl(url, await getSettings()); const siteDelay = getDelayForUrl(url, await getSettings());
console.log("Waiting " + siteDelay + " seconds before scrobbling ...");
if (activeTabs.has(tabId)) clearTimeout(activeTabs.get(tabId)); if (activeTabs.has(tabId)) clearTimeout(activeTabs.get(tabId));
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
@ -97,27 +142,22 @@ browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
activeTabs.set(tabId, timeout); activeTabs.set(tabId, timeout);
}); });
// Stop scrobble when navigating away or closing // ====== Pause Toggle via Toolbar Icon ======
function stopScrobble(tabId, url) { browser.browserAction.onClicked.addListener(async (tab) => {
getSettings().then(({ blacklist }) => { const { paused } = await getSettings();
if (!url || isBlacklisted(url, blacklist)) return; const tabPaused = pausedTabs.has(tab.id) || paused;
if (url.startsWith("moz-extension://")) return; setPaused(tab.id, !tabPaused);
fetch(`${STOP_ENDPOINT}${encodeURIComponent(url)}`).then(() => });
updateIcon("stopped"),
);
});
}
// ====== Clean up on Tab Close ======
browser.tabs.onRemoved.addListener((tabId) => { browser.tabs.onRemoved.addListener((tabId) => {
if (activeTabs.has(tabId)) clearTimeout(activeTabs.get(tabId)); if (activeTabs.has(tabId)) clearTimeout(activeTabs.get(tabId));
pausedTabs.delete(tabId);
}); });
//browser.webNavigation.onBeforeNavigate.addListener((details) => { // ====== Web Navigation stop code is commented ======
// stopScrobble(details.tabId, details.url); browser.webNavigation.onBeforeNavigate.addListener((details) => {
//}); const { scrobbleBaseUrl } = DEFAULT_SETTINGS;
// scrobbleStop(details.url, scrobbleBaseUrl);
// Toggle pause on icon click // TODO need to fix this in Scrobbler to check if a running scrobble exists and stop if it does
browser.browserAction.onClicked.addListener(async () => {
const { paused } = await getSettings();
setPaused(!paused);
}); });