aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/app/services/timeline.ts
blob: ff9662ad7a5dcc949dbbfb530d835b731df80458 (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
import { TimelineVisibility } from "@/http/timeline";
import XRegExp from "xregexp";
import { Observable } from "rxjs";
import { HubConnection, HubConnectionBuilder } from "@microsoft/signalr";

import { UiLogicError } from "@/common";

import { token$ } from "@/http/common";

const timelineNameReg = XRegExp("^[-_\\p{L}]*$", "u");

export function validateTimelineName(name: string): boolean {
  return timelineNameReg.test(name);
}

export const timelineVisibilityTooltipTranslationMap: Record<
  TimelineVisibility,
  string
> = {
  Public: "timeline.visibilityTooltip.public",
  Register: "timeline.visibilityTooltip.register",
  Private: "timeline.visibilityTooltip.private",
};

function createTimelineHubConnection(token: string | null): HubConnection {
  return new HubConnectionBuilder()
    .withUrl("/api/hub/timeline", {
      accessTokenFactory: token == null ? undefined : () => token,
    })
    .withAutomaticReconnect()
    .build();
}

let timelineHubConnection: HubConnection | null = null;

token$.subscribe((token) => {
  if (timelineHubConnection != null) {
    void timelineHubConnection.stop();
  }
  timelineHubConnection = createTimelineHubConnection(token);
  void timelineHubConnection.start();
});

export function getTimelinePostUpdate(
  timelineName: string
): Observable<string> {
  return new Observable((subscriber) => {
    if (timelineHubConnection == null)
      throw new UiLogicError("Connection is null.");

    const connection = timelineHubConnection;

    const handler = (tn: string): void => {
      if (timelineName === tn) {
        subscriber.next(tn);
      }
    };
    connection.on("OnTimelinePostChanged", handler);
    void connection.invoke("SubscribeTimelinePostChange", timelineName);

    return () => {
      void connection.invoke("UnsubscribeTimelinePostChange", timelineName);
      connection.off("OnTimelinePostChanged", handler);
    };
  });
}