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

import { getHttpToken } 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",
};

export function getTimelinePostUpdate$(
  owner: string,
  timeline: string
): Observable<{ update: boolean; state: HubConnectionState }> {
  return new Observable((subscriber) => {
    subscriber.next({
      update: false,
      state: HubConnectionState.Connecting,
    });

    const token = getHttpToken();
    const connection = new HubConnectionBuilder()
      .withUrl("/api/hub/timeline", {
        accessTokenFactory: token == null ? undefined : () => token,
      })
      .withAutomaticReconnect()
      .build();

    const o = owner;
    const t = timeline;

    const handler = (owner: string, timeline: string): void => {
      if (owner === o && timeline === t) {
        subscriber.next({ update: true, state: connection.state });
      }
    };

    connection.onclose(() => {
      subscriber.next({
        update: false,
        state: HubConnectionState.Disconnected,
      });
    });

    connection.onreconnecting(() => {
      subscriber.next({
        update: false,
        state: HubConnectionState.Reconnecting,
      });
    });

    connection.onreconnected(() => {
      subscriber.next({
        update: false,
        state: HubConnectionState.Connected,
      });
    });

    connection.on("OnTimelinePostChangedV2", handler);

    void connection.start().then(() => {
      subscriber.next({ update: false, state: HubConnectionState.Connected });

      return connection.invoke(
        "SubscribeTimelinePostChangeV2",
        owner,
        timeline
      );
    });

    return () => {
      connection.off("OnTimelinePostChangedV2", handler);

      if (connection.state === HubConnectionState.Connected) {
        void connection
          .invoke("UnsubscribeTimelinePostChangeV2", owner, timeline)
          .then(() => connection.stop());
      }
    };
  });
}