From fb64a8f3d4a7dd4035f50ccf2601ae0a683bd1b8 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 31 Aug 2023 01:50:40 +0800 Subject: ... --- FrontEnd/src/components/alert/AlertService.ts | 111 ++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 FrontEnd/src/components/alert/AlertService.ts (limited to 'FrontEnd/src/components/alert/AlertService.ts') diff --git a/FrontEnd/src/components/alert/AlertService.ts b/FrontEnd/src/components/alert/AlertService.ts new file mode 100644 index 00000000..b3565b8a --- /dev/null +++ b/FrontEnd/src/components/alert/AlertService.ts @@ -0,0 +1,111 @@ +import { ThemeColor, Text } from "../common"; + +export interface AlertInfo { + color?: ThemeColor; + message: Text; + dismissTime?: number | "never"; +} + +export interface AlertInfoWithId extends AlertInfo { + id: number; +} + +interface AlertServiceAlert extends AlertInfoWithId { + timerId: number | null; +} + +export type AlertsListener = (alerts: AlertInfoWithId[]) => void; + +export class AlertService { + private listeners: AlertsListener[] = []; + private alerts: AlertServiceAlert[] = []; + private currentId = 1; + + getAlert(alertId?: number | null | undefined): AlertServiceAlert | null { + for (const alert of this.alerts) { + if (alert.id === alertId) return alert; + } + return null; + } + + registerListener(listener: AlertsListener): void { + this.listeners.push(listener); + listener(this.alerts); + } + + unregisterListener(listener: AlertsListener): void { + this.listeners = this.listeners.filter((l) => l !== listener); + } + + notify() { + for (const listener of this.listeners) { + listener(this.alerts); + } + } + + push(alert: AlertInfo): void { + const newAlert: AlertServiceAlert = { + ...alert, + id: this.currentId++, + timerId: null, + }; + + this.alerts.push(newAlert); + this._resetDismissTimer(newAlert); + + this.notify(); + } + + private _dismiss(alert: AlertServiceAlert) { + if (alert.timerId != null) { + window.clearTimeout(alert.timerId); + } + this.alerts = this.alerts.filter((a) => a !== alert); + this.notify(); + } + + dismiss(alertId?: number | null | undefined) { + const alert = this.getAlert(alertId); + if (alert != null) { + this._dismiss(alert); + } + } + + private _clearDismissTimer(alert: AlertServiceAlert) { + if (alert.timerId != null) { + window.clearTimeout(alert.timerId); + alert.timerId = null; + } + } + + clearDismissTimer(alertId?: number | null | undefined) { + const alert = this.getAlert(alertId); + if (alert != null) { + this._clearDismissTimer(alert); + } + } + + private _resetDismissTimer( + alert: AlertServiceAlert, + dismissTime?: number | null | undefined, + ) { + this._clearDismissTimer(alert); + + const realDismissTime = dismissTime ?? alert.dismissTime; + + if (typeof realDismissTime === "number") { + alert.timerId = window.setTimeout(() => { + this._dismiss(alert); + }, realDismissTime); + } + } + + resetDismissTimer(alertId?: number | null | undefined) { + const alert = this.getAlert(alertId); + if (alert != null) { + this._resetDismissTimer(alert); + } + } +} + +export const alertService = new AlertService(); -- cgit v1.2.3 From 4a6d8c606fab0215065ce65d2f105fafd8db7169 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 31 Aug 2023 02:19:01 +0800 Subject: ... --- FrontEnd/src/components/alert/AlertHost.tsx | 9 +++-- FrontEnd/src/components/alert/AlertService.ts | 7 +++- FrontEnd/src/components/alert/alert.css | 7 ++-- FrontEnd/src/pages/setting/index.tsx | 54 ++++++++++++++------------- 4 files changed, 42 insertions(+), 35 deletions(-) (limited to 'FrontEnd/src/components/alert/AlertService.ts') diff --git a/FrontEnd/src/components/alert/AlertHost.tsx b/FrontEnd/src/components/alert/AlertHost.tsx index 23f62472..59f8f27c 100644 --- a/FrontEnd/src/components/alert/AlertHost.tsx +++ b/FrontEnd/src/components/alert/AlertHost.tsx @@ -46,11 +46,14 @@ export default function AlertHost() { const [alerts, setAlerts] = useState([]); useEffect(() => { - alertService.registerListener(setAlerts); + const listener = (alerts: AlertInfoWithId[]) => { + setAlerts(alerts); + }; + + alertService.registerListener(listener); return () => { - alertService.unregisterListener(setAlerts); - alert; + alertService.unregisterListener(listener); }; }, []); diff --git a/FrontEnd/src/components/alert/AlertService.ts b/FrontEnd/src/components/alert/AlertService.ts index b3565b8a..b9cda752 100644 --- a/FrontEnd/src/components/alert/AlertService.ts +++ b/FrontEnd/src/components/alert/AlertService.ts @@ -1,5 +1,7 @@ import { ThemeColor, Text } from "../common"; +const defaultDismissTime = 5000; + export interface AlertInfo { color?: ThemeColor; message: Text; @@ -50,7 +52,7 @@ export class AlertService { timerId: null, }; - this.alerts.push(newAlert); + this.alerts = [...this.alerts, newAlert]; this._resetDismissTimer(newAlert); this.notify(); @@ -91,7 +93,8 @@ export class AlertService { ) { this._clearDismissTimer(alert); - const realDismissTime = dismissTime ?? alert.dismissTime; + const realDismissTime = + dismissTime ?? alert.dismissTime ?? defaultDismissTime; if (typeof realDismissTime === "number") { alert.timerId = window.setTimeout(() => { diff --git a/FrontEnd/src/components/alert/alert.css b/FrontEnd/src/components/alert/alert.css index 063af933..948256de 100644 --- a/FrontEnd/src/components/alert/alert.css +++ b/FrontEnd/src/components/alert/alert.css @@ -5,18 +5,17 @@ .cru-alert { border-radius: 5px; - border: var(--cru-theme-color) 1px solid; + border: var(--cru-theme-color) 2px solid; color: var(--cru-text-primary-color); background-color: var(--cru-container-background-color); - padding: 0.5em 2em; + margin: 1em; + padding: 0.5em 1em; display: flex; align-items: center; } -.cru-alert-message {} - .cru-alert-close-button { margin-left: auto; } \ No newline at end of file diff --git a/FrontEnd/src/pages/setting/index.tsx b/FrontEnd/src/pages/setting/index.tsx index 25434339..88ab5cb2 100644 --- a/FrontEnd/src/pages/setting/index.tsx +++ b/FrontEnd/src/pages/setting/index.tsx @@ -176,34 +176,36 @@ function RegisterCodeSettingItem() { }, [user, registerCode]); return ( - - {registerCode === undefined ? ( - - ) : registerCode === null ? ( - Noop - ) : ( - { - void navigator.clipboard.writeText(registerCode).then(() => { - pushAlert({ - color: "create", - message: "settings.myRegisterCodeCopied", + <> + + {registerCode === undefined ? ( + + ) : registerCode === null ? ( + Noop + ) : ( + { + void navigator.clipboard.writeText(registerCode).then(() => { + pushAlert({ + color: "create", + message: "settings.myRegisterCodeCopied", + }); }); - }); - event.stopPropagation(); - }} - > - {registerCode} - - )} + event.stopPropagation(); + }} + > + {registerCode} + + )} + - + ); } -- cgit v1.2.3