mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-21 04:39:06 +00:00
loading and redirecting front-end
This commit is contained in:
@@ -13,6 +13,7 @@ import ShareLink from "../shareLink";
|
|||||||
import QRCode from "react-qr-code";
|
import QRCode from "react-qr-code";
|
||||||
import TranscriptTitle from "../transcriptTitle";
|
import TranscriptTitle from "../transcriptTitle";
|
||||||
import Player from "../player";
|
import Player from "../player";
|
||||||
|
import WaveformLoading from "../waveformLoading";
|
||||||
|
|
||||||
type TranscriptDetails = {
|
type TranscriptDetails = {
|
||||||
params: {
|
params: {
|
||||||
@@ -83,9 +84,9 @@ export default function TranscriptDetails(details: TranscriptDetails) {
|
|||||||
mediaDuration={transcript.response.duration}
|
mediaDuration={transcript.response.duration}
|
||||||
/>
|
/>
|
||||||
) : mp3.error || waveform.error ? (
|
) : mp3.error || waveform.error ? (
|
||||||
"error loading this recording"
|
<div>"error loading this recording"</div>
|
||||||
) : (
|
) : (
|
||||||
"Loading Recording"
|
<WaveformLoading />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 grid-rows-2 lg:grid-rows-1 gap-2 lg:gap-4 h-full">
|
<div className="grid grid-cols-1 lg:grid-cols-2 grid-rows-2 lg:grid-rows-1 gap-2 lg:gap-4 h-full">
|
||||||
@@ -104,10 +105,17 @@ export default function TranscriptDetails(details: TranscriptDetails) {
|
|||||||
summary={transcript.response.longSummary}
|
summary={transcript.response.longSummary}
|
||||||
transcriptId={transcript.response.id}
|
transcriptId={transcript.response.id}
|
||||||
/>
|
/>
|
||||||
) : transcript.response.status == "processing" ? (
|
|
||||||
"Loading Transcript"
|
|
||||||
) : (
|
) : (
|
||||||
"error final summary"
|
<div className="flex flex-col h-full justify-center content-center">
|
||||||
|
{transcript.response.status == "processing" ? (
|
||||||
|
<p>Loading Transcript</p>
|
||||||
|
) : (
|
||||||
|
<p>
|
||||||
|
There was an error generating the final summary, please
|
||||||
|
come back later
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,12 @@ import { Topic } from "../../webSocketTypes";
|
|||||||
import LiveTrancription from "../../liveTranscription";
|
import LiveTrancription from "../../liveTranscription";
|
||||||
import DisconnectedIndicator from "../../disconnectedIndicator";
|
import DisconnectedIndicator from "../../disconnectedIndicator";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faGear } from "@fortawesome/free-solid-svg-icons";
|
import { faGear, faSpinner } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { lockWakeState, releaseWakeState } from "../../../../lib/wakeLock";
|
import { lockWakeState, releaseWakeState } from "../../../../lib/wakeLock";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import Player from "../../player";
|
||||||
|
import useMp3 from "../../useMp3";
|
||||||
|
import WaveformLoading from "../../waveformLoading";
|
||||||
|
|
||||||
type TranscriptDetails = {
|
type TranscriptDetails = {
|
||||||
params: {
|
params: {
|
||||||
@@ -42,8 +45,10 @@ const TranscriptRecord = (details: TranscriptDetails) => {
|
|||||||
|
|
||||||
const { audioDevices, getAudioStream } = useAudioDevice();
|
const { audioDevices, getAudioStream } = useAudioDevice();
|
||||||
|
|
||||||
const [hasRecorded, setHasRecorded] = useState(false);
|
const [recordedTime, setRecordedTime] = useState(0);
|
||||||
|
const [startTime, setStartTime] = useState(0);
|
||||||
const [transcriptStarted, setTranscriptStarted] = useState(false);
|
const [transcriptStarted, setTranscriptStarted] = useState(false);
|
||||||
|
const mp3 = useMp3(true, "");
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -54,8 +59,6 @@ const TranscriptRecord = (details: TranscriptDetails) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const statusToRedirect = ["ended", "error"];
|
const statusToRedirect = ["ended", "error"];
|
||||||
console.log(webSockets.status, "hey");
|
|
||||||
console.log(transcript.response, "ho");
|
|
||||||
|
|
||||||
//TODO if has no topic and is error, get back to new
|
//TODO if has no topic and is error, get back to new
|
||||||
if (
|
if (
|
||||||
@@ -80,16 +83,31 @@ const TranscriptRecord = (details: TranscriptDetails) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Recorder
|
{webSockets.waveform && mp3.media ? (
|
||||||
setStream={setStream}
|
<Player
|
||||||
onStop={() => {
|
topics={webSockets.topics || []}
|
||||||
setStream(null);
|
useActiveTopic={useActiveTopic}
|
||||||
setHasRecorded(true);
|
waveform={webSockets.waveform}
|
||||||
webRTC?.send(JSON.stringify({ cmd: "STOP" }));
|
media={mp3.media}
|
||||||
}}
|
mediaDuration={recordedTime}
|
||||||
getAudioStream={getAudioStream}
|
/>
|
||||||
audioDevices={audioDevices}
|
) : recordedTime ? (
|
||||||
/>
|
<WaveformLoading />
|
||||||
|
) : (
|
||||||
|
<Recorder
|
||||||
|
setStream={setStream}
|
||||||
|
onStop={() => {
|
||||||
|
setStream(null);
|
||||||
|
setRecordedTime(Date.now() - startTime);
|
||||||
|
webRTC?.send(JSON.stringify({ cmd: "STOP" }));
|
||||||
|
}}
|
||||||
|
onRecord={() => {
|
||||||
|
setStartTime(Date.now());
|
||||||
|
}}
|
||||||
|
getAudioStream={getAudioStream}
|
||||||
|
audioDevices={audioDevices}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 grid-rows-mobile-inner lg:grid-rows-1 gap-2 lg:gap-4 h-full">
|
<div className="grid grid-cols-1 lg:grid-cols-2 grid-rows-mobile-inner lg:grid-rows-1 gap-2 lg:gap-4 h-full">
|
||||||
<TopicList
|
<TopicList
|
||||||
@@ -101,7 +119,7 @@ const TranscriptRecord = (details: TranscriptDetails) => {
|
|||||||
<section
|
<section
|
||||||
className={`w-full h-full bg-blue-400/20 rounded-lg md:rounded-xl p-2 md:px-4`}
|
className={`w-full h-full bg-blue-400/20 rounded-lg md:rounded-xl p-2 md:px-4`}
|
||||||
>
|
>
|
||||||
{!hasRecorded ? (
|
{!recordedTime ? (
|
||||||
<>
|
<>
|
||||||
{transcriptStarted && (
|
{transcriptStarted && (
|
||||||
<h2 className="md:text-lg font-bold">Transcription</h2>
|
<h2 className="md:text-lg font-bold">Transcription</h2>
|
||||||
@@ -135,7 +153,7 @@ const TranscriptRecord = (details: TranscriptDetails) => {
|
|||||||
couple of minutes. Please do not navigate away from the page
|
couple of minutes. Please do not navigate away from the page
|
||||||
during this time.
|
during this time.
|
||||||
</p>
|
</p>
|
||||||
{/* TODO If login required remove last sentence */}
|
{/* NTH If login required remove last sentence */}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default function FinalSummary(props: FinalSummaryProps) {
|
|||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
(isEditMode ? "overflow-y-none" : "overflow-y-auto") +
|
(isEditMode ? "overflow-y-none" : "overflow-y-auto") +
|
||||||
" h-auto max-h-full flex flex-col h-full"
|
" max-h-full flex flex-col h-full"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="flex flex-row flex-wrap-reverse justify-between items-center">
|
<div className="flex flex-row flex-wrap-reverse justify-between items-center">
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ import { waveSurferStyles } from "../../styles/recorder";
|
|||||||
import { useError } from "../../(errors)/errorContext";
|
import { useError } from "../../(errors)/errorContext";
|
||||||
|
|
||||||
type RecorderProps = {
|
type RecorderProps = {
|
||||||
setStream?: React.Dispatch<React.SetStateAction<MediaStream | null>>;
|
setStream: React.Dispatch<React.SetStateAction<MediaStream | null>>;
|
||||||
onStop?: () => void;
|
onStop: () => void;
|
||||||
getAudioStream?: (deviceId) => Promise<MediaStream | null>;
|
onRecord?: () => void;
|
||||||
audioDevices?: Option[];
|
getAudioStream: (deviceId) => Promise<MediaStream | null>;
|
||||||
mediaDuration?: number | null;
|
audioDevices: Option[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Recorder(props: RecorderProps) {
|
export default function Recorder(props: RecorderProps) {
|
||||||
@@ -94,7 +94,6 @@ export default function Recorder(props: RecorderProps) {
|
|||||||
autoCenter: true,
|
autoCenter: true,
|
||||||
barWidth: 2,
|
barWidth: 2,
|
||||||
height: "auto",
|
height: "auto",
|
||||||
duration: props.mediaDuration || 1,
|
|
||||||
|
|
||||||
...waveSurferStyles.player,
|
...waveSurferStyles.player,
|
||||||
});
|
});
|
||||||
@@ -161,10 +160,10 @@ export default function Recorder(props: RecorderProps) {
|
|||||||
setScreenMediaStream(null);
|
setScreenMediaStream(null);
|
||||||
setDestinationStream(null);
|
setDestinationStream(null);
|
||||||
} else {
|
} else {
|
||||||
|
if (props.onRecord) props.onRecord();
|
||||||
const stream = await getCurrentStream();
|
const stream = await getCurrentStream();
|
||||||
|
|
||||||
if (props.setStream) props.setStream(stream);
|
if (props.setStream) props.setStream(stream);
|
||||||
waveRegions?.clearRegions();
|
|
||||||
if (stream) {
|
if (stream) {
|
||||||
await record.startRecording(stream);
|
await record.startRecording(stream);
|
||||||
setIsRecording(true);
|
setIsRecording(true);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { Topic, FinalSummary, Status } from "./webSocketTypes";
|
import { Topic, FinalSummary, Status } from "./webSocketTypes";
|
||||||
import { useError } from "../../(errors)/errorContext";
|
import { useError } from "../../(errors)/errorContext";
|
||||||
import { useRouter } from "next/navigation";
|
|
||||||
import { DomainContext } from "../domainContext";
|
import { DomainContext } from "../domainContext";
|
||||||
|
import { AudioWaveform } from "../../api";
|
||||||
|
|
||||||
export type UseWebSockets = {
|
export type UseWebSockets = {
|
||||||
transcriptText: string;
|
transcriptText: string;
|
||||||
@@ -11,6 +11,7 @@ export type UseWebSockets = {
|
|||||||
topics: Topic[];
|
topics: Topic[];
|
||||||
finalSummary: FinalSummary;
|
finalSummary: FinalSummary;
|
||||||
status: Status;
|
status: Status;
|
||||||
|
waveform: AudioWaveform | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
||||||
@@ -21,6 +22,7 @@ export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
|||||||
const [translationQueue, setTranslationQueue] = useState<string[]>([]);
|
const [translationQueue, setTranslationQueue] = useState<string[]>([]);
|
||||||
const [isProcessing, setIsProcessing] = useState(false);
|
const [isProcessing, setIsProcessing] = useState(false);
|
||||||
const [topics, setTopics] = useState<Topic[]>([]);
|
const [topics, setTopics] = useState<Topic[]>([]);
|
||||||
|
const [waveform, setWaveForm] = useState<AudioWaveform | null>(null);
|
||||||
const [finalSummary, setFinalSummary] = useState<FinalSummary>({
|
const [finalSummary, setFinalSummary] = useState<FinalSummary>({
|
||||||
summary: "",
|
summary: "",
|
||||||
});
|
});
|
||||||
@@ -405,5 +407,13 @@ export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
|||||||
};
|
};
|
||||||
}, [transcriptId]);
|
}, [transcriptId]);
|
||||||
|
|
||||||
return { transcriptText, translateText, topics, finalSummary, title, status };
|
return {
|
||||||
|
transcriptText,
|
||||||
|
translateText,
|
||||||
|
topics,
|
||||||
|
finalSummary,
|
||||||
|
title,
|
||||||
|
status,
|
||||||
|
waveform,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
11
www/app/[domain]/transcripts/waveformLoading.tsx
Normal file
11
www/app/[domain]/transcripts/waveformLoading.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { faSpinner } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div className="flex flex-grow items-center justify-center h-20">
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faSpinner}
|
||||||
|
className="animate-spin-slow text-gray-600 flex-grow rounded-lg md:rounded-xl h-10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user