115 lines
2.9 KiB
TypeScript
115 lines
2.9 KiB
TypeScript
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(<UnignoreAllButton />, button);
|
|
heading.after(button);
|
|
|
|
return true;
|
|
}
|
|
|
|
type Props = Record<string, unknown>;
|
|
|
|
type State = {
|
|
isRunning: boolean;
|
|
remaining: number;
|
|
total: number;
|
|
wasCanceled: boolean;
|
|
};
|
|
|
|
class UnignoreAllButton extends Component<Props, State> {
|
|
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<HTMLButtonElement>(
|
|
'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 (
|
|
<button class="btn" onClick={this.click}>
|
|
{text}
|
|
</button>
|
|
);
|
|
}
|
|
}
|