diff options
-rw-r--r-- | FrontEnd/src/app/services/timeline.ts | 51 | ||||
-rw-r--r-- | FrontEnd/src/app/views/timeline-common/Timeline.tsx | 14 | ||||
-rw-r--r-- | FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx | 12 |
3 files changed, 35 insertions, 42 deletions
diff --git a/FrontEnd/src/app/services/timeline.ts b/FrontEnd/src/app/services/timeline.ts index ff9662ad..2dbd3e4d 100644 --- a/FrontEnd/src/app/services/timeline.ts +++ b/FrontEnd/src/app/services/timeline.ts @@ -1,11 +1,9 @@ import { TimelineVisibility } from "@/http/timeline"; import XRegExp from "xregexp"; import { Observable } from "rxjs"; -import { HubConnection, HubConnectionBuilder } from "@microsoft/signalr"; +import { HubConnectionBuilder } from "@microsoft/signalr"; -import { UiLogicError } from "@/common"; - -import { token$ } from "@/http/common"; +import { getHttpToken } from "@/http/common"; const timelineNameReg = XRegExp("^[-_\\p{L}]*$", "u"); @@ -22,45 +20,38 @@ export const timelineVisibilityTooltipTranslationMap: Record< 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( +export function getTimelinePostUpdate$( timelineName: string ): Observable<string> { return new Observable((subscriber) => { - if (timelineHubConnection == null) - throw new UiLogicError("Connection is null."); - - const connection = timelineHubConnection; + const token = getHttpToken(); + const connection = new HubConnectionBuilder() + .withUrl("/api/hub/timeline", { + accessTokenFactory: token == null ? undefined : () => token, + }) + .withAutomaticReconnect() + .build(); const handler = (tn: string): void => { if (timelineName === tn) { subscriber.next(tn); } }; + connection.on("OnTimelinePostChanged", handler); - void connection.invoke("SubscribeTimelinePostChange", timelineName); + + void connection + .start() + .then(() => + connection.invoke("SubscribeTimelinePostChange", timelineName) + ); return () => { - void connection.invoke("UnsubscribeTimelinePostChange", timelineName); connection.off("OnTimelinePostChanged", handler); + + void connection + .invoke("UnsubscribeTimelinePostChange", timelineName) + .then(() => connection.stop()); }; }); } diff --git a/FrontEnd/src/app/views/timeline-common/Timeline.tsx b/FrontEnd/src/app/views/timeline-common/Timeline.tsx index 32d0bdd5..8bdf4d3b 100644 --- a/FrontEnd/src/app/views/timeline-common/Timeline.tsx +++ b/FrontEnd/src/app/views/timeline-common/Timeline.tsx @@ -7,6 +7,8 @@ import { } from "@/http/common"; import { getHttpTimelineClient, HttpTimelinePostInfo } from "@/http/timeline"; +import { getTimelinePostUpdate$ } from "@/services/timeline"; + import TimelinePagedPostListView from "./TimelinePagedPostListView"; import TimelineTop from "./TimelineTop"; import TimelineLoading from "./TimelineLoading"; @@ -34,6 +36,18 @@ const Timeline: React.FC<TimelineProps> = (props) => { }, [timelineName]); React.useEffect(() => { + if (timelineName != null && state === "loaded") { + const timelinePostUpdate$ = getTimelinePostUpdate$(timelineName); + const subscription = timelinePostUpdate$.subscribe(() => { + onReload(); + }); + return () => { + subscription.unsubscribe(); + }; + } + }, [timelineName, state, onReload]); + + React.useEffect(() => { if (timelineName != null) { let subscribe = true; diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx index 4c0cc8e3..81a3c179 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx @@ -12,7 +12,6 @@ import TimelinePostEdit from "./TimelinePostEdit"; import useReverseScrollPositionRemember from "@/utilities/useReverseScrollPositionRemember"; import { generatePalette, setPalette } from "@/palette"; -import { getTimelinePostUpdate as getTimelinePostUpdate$ } from "@/services/timeline"; export interface TimelinePageCardProps { timeline: HttpTimelineInfo; @@ -92,17 +91,6 @@ const TimelinePageTemplate: React.FC<TimelinePageTemplateProps> = (props) => { setTimelineReloadKey((old) => old + 1); }; - React.useEffect(() => { - const timelinePostUpdate$ = getTimelinePostUpdate$(timelineName); - const subscription = timelinePostUpdate$.subscribe(() => { - setTimelineReloadKey((old) => old + 1); - }); - - return () => { - subscription.unsubscribe(); - }; - }, [timelineName]); - const onPostEditHeightChange = React.useCallback((height: number): void => { setBottomSpaceHeight(height); if (height === 0) { |