Updates the tab icon and title when an action stops.
// ==UserScript== // @name ⛏️Ironwood Idle Indicators // @description Updates the tab icon and title when an action stops. // @version 1.0.3 // @license MIT // @author bradp // @namespace bradp // @match https://ironwoodrpg.com/* // @run-at document-end // @grant none // ==/UserScript== (() => { 'use strict'; const onRequest = (url, callback) => { const req = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function () { this.addEventListener('load', function () { if (this.responseText) { let response = {}; try { response = JSON.parse(this.responseText); } catch (e) { return; } if (response && this.responseURL.indexOf(url) !== -1) { callback(response); } } }); req.apply(this, arguments); }; }; const updateFavicon = (state = 'idle') => { const favicons = [ { size: 16, href: 'https://ironwoodrpg.com/favicon/favicon-16x16.png' }, { size: 32, href: 'https://ironwoodrpg.com/favicon/favicon-32x32.png' }, { size: 192, href: 'https://ironwoodrpg.com/favicon/android-chrome-192x192.png' }, { size: 512, href: 'https://ironwoodrpg.com/favicon/android-chrome-512x512.png' }, { size: 180, rel: 'apple-touch-icon', href: 'https://ironwoodrpg.com/favicon/apple-touch-icon.png' }, ]; favicons.forEach((favicon) => { // remove existing favicons const existing = document.querySelector(`link[rel="${favicon.rel || 'icon'}"][sizes="${favicon.size}"]`); if (existing) { existing.remove(); } // add new favicon const link = document.createElement('link'); link.rel = favicon.rel || 'icon'; link.sizes = favicon.size; link.href = state === 'idle' ? `https://brrad.com/ironwood/icons/${favicon.size}.png` : favicon.href; document.head.appendChild(link); }); }; onRequest('stopAction', (response) => { // Update the tab title to show the action has stopped. setTimeout(() => { // only update if the title doesn't already contain the indicator text if (document.title.indexOf('🟥️ ') !== -1) { return; } document.title = `🟥️ ${document.title}`; updateFavicon('idle'); }, 250); }); onRequest('startAction', (response) => { // Update the tab title to remove the action stopped indicator. document.title = document.title.replace('🟥️ ', ''); updateFavicon('active'); }); })();