// ==UserScript== // @name 4chan Page 10 Notifier // @namespace moe.rita.4chanPage10Notifier // @match https://boards.4chan.org/*/thread/* // @run-at document-end // @grant none // @version 1.2.2 // @author Kody // @description Notify when the thread gets to page 10. // @icon https://www.google.com/s2/favicons?domain=4chan.org // @downloadURL https://gist.rita.moe/kody/c3cd33a8d923423c9045ad738ec302ba/raw/HEAD/4chan-page-notifier.user.js // ==/UserScript== (function () { 'use strict' let pageCountEl const lastPage = 10 let notified = false const pageNotify = () => { // Extract the current page number from the text // but be careful that it might be 10(x) const currPage = parseInt(pageCountEl.innerText.split('(')[0]?.trim(), 10) console.log('Current page:', currPage) // Check if it's a valid number and greater than 0 if (isNaN(currPage) || currPage < 1) { console.warn('Invalid page number:', currPage) return } // Reset notification state if page is less than 10 if (currPage < lastPage && notified) { notified = false return } // Skip if already notified or current page is less than the last page if (currPage < lastPage || notified) { return } // Send a browser notification const subject = document.querySelector('.subject')?.innerText || 'Last Page Reached' if (window.Notification.permission === 'granted') { const notification = new window.Notification( subject, { body: `The thread has reached page ${currPage}.`, icon: 'https://www.google.com/s2/favicons?domain=4chan.org', } ) notification.onclick = () => { window.focus() notification.close() } notified = true } } const setupObserver = () => { pageCountEl = document.getElementById('page-count') if (pageCountEl) { const observer = new window.MutationObserver(pageNotify) observer.observe( pageCountEl, { childList: true, subtree: true, characterData: true, } ) } else { console.error('Could not find element with ID "page-count"') } } // Wait 3 seconds before setting up the observer setTimeout(setupObserver, 3000) })()