aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/components/alert/AlertService.ts
blob: b9cda75239919c53f92176b4ebfd2945719e2f6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { ThemeColor, Text } from "../common";

const defaultDismissTime = 5000;

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 = [...this.alerts, 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 ?? defaultDismissTime;

    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();