This has been bugging me for a while — any type of repetitive action that shows a toast will quickly cause a big stack of toasts to build up. This fixes that by allowing different categories of toasts to exist, where each category can only have one active toast. _Different_ categories of toast can coexist just fine, but toasts with the same `id` will replace any existing toast with that same `id`. It's been a pet peeve for a while, and it should make any sort of "power user" use of Browsertrix a lot nicer :) I've gone over all the existing toasts and applied what feel like decent differentiations, but I'm not set on any of them — open to suggestions! https://github.com/user-attachments/assets/dbe39141-9e56-427d-b702-124c45ef2b9a --------- Co-authored-by: Ilya Kreymer <ikreymer@users.noreply.github.com>
66 lines
1.5 KiB
TypeScript
66 lines
1.5 KiB
TypeScript
import type {
|
|
ReactiveController,
|
|
ReactiveControllerHost,
|
|
TemplateResult,
|
|
} from "lit";
|
|
|
|
export type NotifyEventDetail = {
|
|
/**
|
|
* Notification message body.
|
|
* Example:
|
|
* ```ts
|
|
* message: html`<strong>Look!</strong>`
|
|
* ```
|
|
*
|
|
* Note: In order for `this` methods to work, you'll
|
|
* need to bind `this` or use a fat arrow function.
|
|
* For example:
|
|
* ```ts
|
|
* message: html`<button @click=${this.onClick.bind(this)}>Go!</button>`
|
|
* ```
|
|
* Or:
|
|
* ```ts
|
|
* message: html`<button @click=${(e) => this.onClick(e)}>Go!</button>`
|
|
* ```
|
|
**/
|
|
message: string | TemplateResult;
|
|
/** Notification title */
|
|
title?: string;
|
|
/** Shoelace icon name */
|
|
icon?: string;
|
|
variant?: "success" | "warning" | "danger" | "primary" | "info";
|
|
duration?: number;
|
|
id?: string | number | symbol;
|
|
};
|
|
|
|
export interface NotifyEventMap {
|
|
"btrix-notify": CustomEvent<NotifyEventDetail>;
|
|
}
|
|
|
|
const NOTIFY_EVENT_NAME: keyof NotifyEventMap = "btrix-notify";
|
|
|
|
/**
|
|
* Manage global app notifications
|
|
*/
|
|
export class NotifyController implements ReactiveController {
|
|
private readonly host: ReactiveControllerHost & EventTarget;
|
|
|
|
constructor(host: NotifyController["host"]) {
|
|
this.host = host;
|
|
host.addController(this);
|
|
}
|
|
|
|
hostConnected() {}
|
|
hostDisconnected() {}
|
|
|
|
toast(detail: NotifyEventDetail) {
|
|
this.host.dispatchEvent(
|
|
new CustomEvent<NotifyEventDetail>(NOTIFY_EVENT_NAME, {
|
|
bubbles: true,
|
|
composed: true,
|
|
detail,
|
|
}),
|
|
);
|
|
}
|
|
}
|