aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-05-17 21:02:31 +0800
committercrupest <crupest@outlook.com>2021-05-17 21:02:31 +0800
commitc7528bfdfa920f1e2e5de2876c4bb7691419d7d6 (patch)
tree88ba1e1af79738fb00277f7033586e0c07041db9 /FrontEnd/src
parent7d847632c59e247189f9039385aac1d630e87212 (diff)
downloadtimeline-c7528bfdfa920f1e2e5de2876c4bb7691419d7d6.tar.gz
timeline-c7528bfdfa920f1e2e5de2876c4bb7691419d7d6.tar.bz2
timeline-c7528bfdfa920f1e2e5de2876c4bb7691419d7d6.zip
feat: Prepare for connection status badge.
Diffstat (limited to 'FrontEnd/src')
-rw-r--r--FrontEnd/src/app/services/timeline.ts40
-rw-r--r--FrontEnd/src/app/views/timeline-common/Timeline.tsx22
2 files changed, 51 insertions, 11 deletions
diff --git a/FrontEnd/src/app/services/timeline.ts b/FrontEnd/src/app/services/timeline.ts
index b19dcbe9..d8c0ae00 100644
--- a/FrontEnd/src/app/services/timeline.ts
+++ b/FrontEnd/src/app/services/timeline.ts
@@ -22,8 +22,13 @@ export const timelineVisibilityTooltipTranslationMap: Record<
export function getTimelinePostUpdate$(
timelineName: string
-): Observable<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", {
@@ -34,17 +39,38 @@ export function getTimelinePostUpdate$(
const handler = (tn: string): void => {
if (timelineName === tn) {
- subscriber.next(tn);
+ 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("OnTimelinePostChanged", handler);
- void connection
- .start()
- .then(() =>
- connection.invoke("SubscribeTimelinePostChange", timelineName)
- );
+ void connection.start().then(() => {
+ subscriber.next({ update: false, state: HubConnectionState.Connected });
+
+ return connection.invoke("SubscribeTimelinePostChange", timelineName);
+ });
return () => {
connection.off("OnTimelinePostChanged", handler);
diff --git a/FrontEnd/src/app/views/timeline-common/Timeline.tsx b/FrontEnd/src/app/views/timeline-common/Timeline.tsx
index 8bdf4d3b..65378563 100644
--- a/FrontEnd/src/app/views/timeline-common/Timeline.tsx
+++ b/FrontEnd/src/app/views/timeline-common/Timeline.tsx
@@ -1,4 +1,5 @@
import React from "react";
+import { HubConnectionState } from "@microsoft/signalr";
import {
HttpForbiddenError,
@@ -19,6 +20,7 @@ export interface TimelineProps {
timelineName?: string;
reloadKey: number;
onReload: () => void;
+ onConnectionStateChanged?: (state: HubConnectionState) => void;
}
const Timeline: React.FC<TimelineProps> = (props) => {
@@ -35,17 +37,29 @@ const Timeline: React.FC<TimelineProps> = (props) => {
setPosts([]);
}, [timelineName]);
+ const onConnectionStateChanged =
+ React.useRef<((state: HubConnectionState) => void) | null>(null);
+
+ React.useEffect(() => {
+ onConnectionStateChanged.current = props.onConnectionStateChanged ?? null;
+ }, [props.onConnectionStateChanged]);
+
React.useEffect(() => {
if (timelineName != null && state === "loaded") {
const timelinePostUpdate$ = getTimelinePostUpdate$(timelineName);
- const subscription = timelinePostUpdate$.subscribe(() => {
- onReload();
- });
+ const subscription = timelinePostUpdate$.subscribe(
+ ({ update, state }) => {
+ if (update) {
+ onReload();
+ }
+ onConnectionStateChanged.current?.(state);
+ }
+ );
return () => {
subscription.unsubscribe();
};
}
- }, [timelineName, state, onReload]);
+ }, [timelineName, state, onReload, onConnectionStateChanged]);
React.useEffect(() => {
if (timelineName != null) {