This repository was archived by the owner on Oct 22, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathEchoStore.ts
94 lines (74 loc) · 3.11 KB
/
EchoStore.ts
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
/*
Copyright 2024 New Vector Ltd.
Copyright 2020 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
import { Room } from "matrix-js-sdk/src/matrix";
import { GenericEchoChamber } from "./GenericEchoChamber";
import { RoomEchoChamber } from "./RoomEchoChamber";
import { RoomEchoContext } from "./RoomEchoContext";
import { AsyncStoreWithClient } from "../AsyncStoreWithClient";
import defaultDispatcher from "../../dispatcher/dispatcher";
import { ActionPayload } from "../../dispatcher/payloads";
import { ContextTransactionState, EchoContext } from "./EchoContext";
import NonUrgentToastStore, { ToastReference } from "../NonUrgentToastStore";
import NonUrgentEchoFailureToast from "../../components/views/toasts/NonUrgentEchoFailureToast";
interface IState {
toastRef: ToastReference;
}
type ContextKey = string;
const roomContextKey = (room: Room): ContextKey => `room-${room.roomId}`;
export class EchoStore extends AsyncStoreWithClient<IState> {
private static _instance: EchoStore;
private caches = new Map<ContextKey, GenericEchoChamber<any, any, any>>();
public constructor() {
super(defaultDispatcher);
}
public static get instance(): EchoStore {
if (!this._instance) {
this._instance = new EchoStore();
}
return this._instance;
}
public get contexts(): EchoContext[] {
return Array.from(this.caches.values()).map((e) => e.context);
}
public getOrCreateChamberForRoom(room: Room): RoomEchoChamber {
if (this.caches.has(roomContextKey(room))) {
return this.caches.get(roomContextKey(room)) as RoomEchoChamber;
}
const context = new RoomEchoContext(room);
context.whenAnything(() => this.checkContexts());
const echo = new RoomEchoChamber(context);
echo.setClient(this.matrixClient);
this.caches.set(roomContextKey(room), echo);
return echo;
}
private async checkContexts(): Promise<void> {
let hasOrHadError = false;
for (const echo of this.caches.values()) {
hasOrHadError = echo.context.state === ContextTransactionState.PendingErrors;
if (hasOrHadError) break;
}
if (hasOrHadError && !this.state.toastRef) {
const ref = NonUrgentToastStore.instance.addToast(NonUrgentEchoFailureToast);
await this.updateState({ toastRef: ref });
} else if (!hasOrHadError && this.state.toastRef) {
NonUrgentToastStore.instance.removeToast(this.state.toastRef);
await this.updateState({ toastRef: null });
}
}
protected async onReady(): Promise<any> {
if (!this.caches) return; // can only happen during initialization
for (const echo of this.caches.values()) {
echo.setClient(this.matrixClient);
}
}
protected async onNotReady(): Promise<any> {
for (const echo of this.caches.values()) {
echo.setClient(null);
}
}
protected async onAction(payload: ActionPayload): Promise<void> {}
}