background.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. const SCROBBLE_ENDPOINT = "https://life.lab.unbl.ink/?scrobble_url=";
  2. const STOP_ENDPOINT = "https://life.lab.unbl.ink/?action=stop&scrobble_url=";
  3. // Default settings
  4. const DEFAULT_SETTINGS = {
  5. delay: 10,
  6. blacklist: ["*.unbl.ink", "moz-extension://"],
  7. paused: false,
  8. };
  9. // Utility: wildcard match
  10. function matchPattern(url, pattern) {
  11. if (pattern.startsWith("*.")) {
  12. const domain = pattern.slice(2);
  13. return url.includes(domain);
  14. }
  15. return url.startsWith(pattern);
  16. }
  17. function isBlacklisted(url, blacklist) {
  18. return blacklist.some((p) => matchPattern(url, p));
  19. }
  20. let activeTabs = new Map();
  21. // Load settings
  22. async function getSettings() {
  23. return new Promise((resolve) => {
  24. browser.storage.local.get(DEFAULT_SETTINGS, (items) => resolve(items));
  25. });
  26. }
  27. // Save pause state
  28. async function setPaused(paused) {
  29. await browser.storage.local.set({ paused });
  30. updateIcon(paused ? "pause" : "wait");
  31. }
  32. function updateIcon(state) {
  33. const icons = {
  34. wait: "icons/wait.png",
  35. scrobbled: "icons/check.png",
  36. stopped: "icons/stop.png",
  37. pause: "icons/pause.png",
  38. };
  39. browser.browserAction.setIcon({ path: icons[state] });
  40. }
  41. // Handle tab updates
  42. browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
  43. if (changeInfo.status !== "complete" || !tab.url) return;
  44. const settings = await getSettings();
  45. const { delay, blacklist, paused } = settings;
  46. if (paused || isBlacklisted(tab.url, blacklist)) return;
  47. if (tab.url.startsWith("moz-extension://")) return;
  48. const url = encodeURIComponent(tab.url);
  49. updateIcon("wait");
  50. if (activeTabs.has(tabId)) clearTimeout(activeTabs.get(tabId));
  51. const timeout = setTimeout(() => {
  52. fetch(`${SCROBBLE_ENDPOINT}${url}`).then(() => updateIcon("scrobbled"));
  53. }, delay * 1000);
  54. activeTabs.set(tabId, timeout);
  55. });
  56. // Stop scrobble when navigating away or closing
  57. function stopScrobble(tabId, url) {
  58. getSettings().then(({ blacklist }) => {
  59. if (!url || isBlacklisted(url, blacklist)) return;
  60. if (url.startsWith("moz-extension://")) return;
  61. fetch(`${STOP_ENDPOINT}${encodeURIComponent(url)}`).then(() =>
  62. updateIcon("stopped"),
  63. );
  64. });
  65. }
  66. browser.tabs.onRemoved.addListener((tabId) => {
  67. if (activeTabs.has(tabId)) clearTimeout(activeTabs.get(tabId));
  68. });
  69. //browser.webNavigation.onBeforeNavigate.addListener((details) => {
  70. // stopScrobble(details.tabId, details.url);
  71. //});
  72. // Toggle pause on icon click
  73. browser.browserAction.onClicked.addListener(async () => {
  74. const { paused } = await getSettings();
  75. setPaused(!paused);
  76. });