// ==UserScript==
// @name         Proton Mail Unread Favicon
// @namespace    https://gist.github.com/kevinleedrum/d7e261c9d9b0b3281dcc75c16d69f143
// @version      0.1
// @description  Updates the Proton Mail favicon to include a single-digit unread count
// @author       Kevin Lee Drum
// @match        https://mail.proton.me/u/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=proton.me
// @grant        none
// ==/UserScript==

const INBOX_SELECTOR = '[data-testid="navigation-link:inbox"]';
const UNREAD_SELECTOR = `${INBOX_SELECTOR} [data-unread-count]`;
const BADGE_BG = "#fff";
const BADGE_FG = "#000";
const INBOX_TIMEOUT = 10; // 5 seconds

let inboxChecks = 0;
let defaultFavicon;

(function () {
  let waitForInbox = setInterval(() => {
    const inbox = document.querySelector(INBOX_SELECTOR);
    if (inboxChecks > INBOX_TIMEOUT) {
      console.error("Proton Mail Unread Favicon: Timed out waiting for inbox");
      clearInterval(waitForInbox);
      return;
    }
    inboxChecks++;
    if (!inbox) return;
    clearInterval(waitForInbox);
    getDefaultFavicon();
    updateFavicon();
    watchForInboxChange();
  }, 500);
})();

function getDefaultFavicon() {
  const svgFavicon = document.querySelector(
    'link[rel="icon"][type="image/svg+xml"]'
  );
  if (svgFavicon) svgFavicon.remove();
  const favicon = document.querySelector('link[rel="icon"]');
  defaultFavicon = favicon.href;
}

function watchForInboxChange() {
  const inbox = document.querySelector(INBOX_SELECTOR);
  if (!inbox) return;
  const observer = new MutationObserver(updateFavicon);
  observer.observe(inbox, { subtree: true, attributes: true, childList: true });
}

function updateFavicon() {
  const favicon = document.querySelector('link[rel="icon"]');
  const unreadCounter = document.querySelector(UNREAD_SELECTOR);
  let count = 0;
  if (unreadCounter) count = +unreadCounter.dataset.unreadCount;
  if (!count) {
    favicon.href = defaultFavicon;
    return;
  }
  if (count > 9) count = "*";
  drawFavicon(count, favicon);
}

function drawFavicon(count, favicon) {
  const canvas = document.createElement("canvas");
  canvas.width = 16;
  canvas.height = 16;
  const ctx = canvas.getContext("2d");
  const img = document.createElement("img");
  img.src = defaultFavicon;
  img.onload = () => {
    // Draw default favicon
    ctx.drawImage(img, 0, 0, 16, 16);
    // Add circle
    ctx.fillStyle = BADGE_BG;
    ctx.beginPath();
    ctx.arc(12, 4, 5, 0, 2 * Math.PI);
    ctx.fill();
    // Add count
    ctx.fillStyle = BADGE_FG;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.font = "10px sans-serif";
    ctx.fillText(count, 12, 5);
    // Update favicon href
    favicon.href = canvas.toDataURL("image/png");
  };
}