import {Component, render} from "preact"; import {log, querySelectorAll, sleep} from "../../../utilities/exports.js"; export function runUnignoreAllButtonFeature(): void { if (addUnignoreAllButton()) { log("Added Unignore All button."); } } function addUnignoreAllButton(): boolean { // Only add the button when we're on the ignore list page and the ignore list // isn't empty. if ( window.location.pathname !== "/ignored_topics" && document.querySelector("main > .empty") === null ) { return false; } const heading = document.querySelector(".heading-main") ?? undefined; if (heading === undefined) { return false; } const button = document.createDocumentFragment(); render(, button); heading.after(button); return true; } type Props = Record; type State = { isRunning: boolean; remaining: number; total: number; wasCanceled: boolean; }; class UnignoreAllButton extends Component { constructor(props: Props) { super(props); this.state = { isRunning: false, remaining: 0, total: 0, wasCanceled: false, }; } click = () => { if (this.state.isRunning) { // If we're already running, cancel the run. this.setState({isRunning: false, wasCanceled: true}); window.setTimeout(() => { // And after 5 seconds, return back to the default state. this.setState({wasCanceled: false}); }, 5000); return; } // Select the ignore buttons that have a HTTP DELETE method set. Since we're // going to have Intercooler do all the work for us, we don't want to // accidentally also select ignore buttons that would ignore the topics // again. const unignoreButtons = querySelectorAll( 'button[name="topic-actions-ignore"][data-ic-delete-from]', ); this.setState({ isRunning: true, remaining: unignoreButtons.length, total: unignoreButtons.length, }); void this.unignoreAll(unignoreButtons); }; unignoreAll = async (buttons: HTMLButtonElement[]) => { let remaining = buttons.length; for (const ignoreButton of buttons) { // Stop the loop if the user canceled it. if (!this.state.isRunning && this.state.wasCanceled) { return; } ignoreButton.click(); remaining--; this.setState({remaining}); await sleep(250); } this.setState({isRunning: false}); }; render() { const {isRunning, remaining, total, wasCanceled} = this.state; let text = "Unignore All"; if (isRunning) { // When we're running show how many topics are remaining. text = `Unignoring topics, ${remaining} out of ${total} remaining`; } else if (wasCanceled) { // If the user canceled, say that. text = "Canceled unignoring all topics"; } return ( ); } }