mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2026-03-21 22:56:47 +00:00
The processing page only read dagStatus from the transcript room WS, which loses events during page navigation and React strict mode double-mounting (WS torn down and reconnected, historical replay skips DAG_STATUS). Now also consumes useDagStatusMap() from UserEventsProvider (user room), which uses a singleton WS that survives remounts. Priority: transcript room WS > user room WS > REST API.
134 lines
3.6 KiB
TypeScript
134 lines
3.6 KiB
TypeScript
"use client";
|
|
import { useEffect, use } from "react";
|
|
import {
|
|
Heading,
|
|
Text,
|
|
VStack,
|
|
Spinner,
|
|
Button,
|
|
Center,
|
|
} from "@chakra-ui/react";
|
|
import { useRouter } from "next/navigation";
|
|
import { useTranscriptGet } from "../../../../lib/apiHooks";
|
|
import { parseNonEmptyString } from "../../../../lib/utils";
|
|
import { useWebSockets } from "../../useWebSockets";
|
|
import type { DagTask } from "../../useWebSockets";
|
|
import { useDagStatusMap } from "../../../../lib/UserEventsProvider";
|
|
import DagProgressTable from "./DagProgressTable";
|
|
|
|
type TranscriptProcessing = {
|
|
params: Promise<{
|
|
transcriptId: string;
|
|
}>;
|
|
};
|
|
|
|
export default function TranscriptProcessing(details: TranscriptProcessing) {
|
|
const params = use(details.params);
|
|
const transcriptId = parseNonEmptyString(params.transcriptId);
|
|
const router = useRouter();
|
|
|
|
const transcript = useTranscriptGet(transcriptId);
|
|
const { status: wsStatus, dagStatus: wsDagStatus } =
|
|
useWebSockets(transcriptId);
|
|
const userDagStatusMap = useDagStatusMap();
|
|
const userDagStatus = userDagStatusMap.get(transcriptId) ?? null;
|
|
|
|
const restDagStatus: DagTask[] | null =
|
|
((transcript.data as Record<string, unknown>)?.dag_status as
|
|
| DagTask[]
|
|
| null) ?? null;
|
|
|
|
// Prefer transcript room WS (most granular), then user room WS, then REST
|
|
const dagStatus = wsDagStatus ?? userDagStatus ?? restDagStatus;
|
|
|
|
useEffect(() => {
|
|
const status = wsStatus?.value ?? transcript.data?.status;
|
|
if (!status) return;
|
|
|
|
if (status === "ended" || status === "error") {
|
|
router.replace(`/transcripts/${transcriptId}`);
|
|
} else if (status === "recording") {
|
|
router.replace(`/transcripts/${transcriptId}/record`);
|
|
} else if (status === "idle") {
|
|
const dest =
|
|
transcript.data?.source_kind === "file"
|
|
? `/transcripts/${transcriptId}/upload`
|
|
: `/transcripts/${transcriptId}/record`;
|
|
router.replace(dest);
|
|
}
|
|
}, [
|
|
wsStatus?.value,
|
|
transcript.data?.status,
|
|
transcript.data?.source_kind,
|
|
router,
|
|
transcriptId,
|
|
]);
|
|
|
|
if (transcript.isLoading) {
|
|
return (
|
|
<VStack align="center" py={8}>
|
|
<Heading size="lg">Loading transcript...</Heading>
|
|
</VStack>
|
|
);
|
|
}
|
|
|
|
if (transcript.error) {
|
|
return (
|
|
<VStack align="center" py={8}>
|
|
<Heading size="lg">Transcript not found</Heading>
|
|
<Text>We couldn't load this transcript.</Text>
|
|
</VStack>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<VStack
|
|
align={"left"}
|
|
minH="100vh"
|
|
pt={4}
|
|
mx="auto"
|
|
w={{ base: "full", md: "container.xl" }}
|
|
>
|
|
<Center h={"full"} w="full">
|
|
<VStack
|
|
gap={10}
|
|
bg="gray.100"
|
|
p={10}
|
|
borderRadius="md"
|
|
maxW="600px"
|
|
w="full"
|
|
>
|
|
{dagStatus ? (
|
|
<>
|
|
<Heading size={"md"} textAlign="center">
|
|
Processing recording
|
|
</Heading>
|
|
<DagProgressTable tasks={dagStatus} />
|
|
</>
|
|
) : (
|
|
<>
|
|
<Spinner size="xl" color="blue.500" />
|
|
<Heading size={"md"} textAlign="center">
|
|
Processing recording
|
|
</Heading>
|
|
</>
|
|
)}
|
|
<Text color="gray.600" textAlign="center">
|
|
You can safely return to the library while your recording is being
|
|
processed.
|
|
</Text>
|
|
<Button
|
|
onClick={() => {
|
|
router.push("/browse");
|
|
}}
|
|
>
|
|
Browse
|
|
</Button>
|
|
</VStack>
|
|
</Center>
|
|
</VStack>
|
|
</>
|
|
);
|
|
}
|