changes types, assign to participant instead of speaker

This commit is contained in:
Sara
2023-12-12 13:29:55 +01:00
parent d8c4f29d72
commit c02c3b190c
7 changed files with 312 additions and 224 deletions

View File

@@ -1,59 +1,77 @@
"use client"; "use client";
import { useEffect, useRef, useState } from "react"; import { useEffect, useState } from "react";
import useTranscript from "../../useTranscript"; import useTranscript from "../../useTranscript";
import TopicHeader from "./topicHeader"; import TopicHeader from "./topicHeader";
import TopicWords from "./topicWords"; import TopicWords from "./topicWords";
import TopicPlayer from "./topicPlayer"; import TopicPlayer from "./topicPlayer";
import getApi from "../../../../lib/getApi";
import useParticipants from "../../useParticipants"; import useParticipants from "../../useParticipants";
import useTopicWithWords from "../../useTopicWithWords"; import useTopicWithWords from "../../useTopicWithWords";
import ParticipantList from "./participantList"; import ParticipantList from "./participantList";
import { GetTranscriptTopic } from "../../../../api";
type TranscriptCorrect = { export type TranscriptCorrect = {
params: { params: {
transcriptId: string; transcriptId: string;
}; };
}; };
type TimeSlice = { export type TimeSlice = {
start: number; start: number;
end: number; end: number;
}; };
export type SelectedText = number | TimeSlice | undefined;
export function selectedTextIsSpeaker(
selectedText: SelectedText,
): selectedText is number {
return typeof selectedText == "number";
}
export function selectedTextIsTimeSlice(
selectedText: SelectedText,
): selectedText is TimeSlice {
return (
typeof (selectedText as any)?.start == "number" &&
typeof (selectedText as any)?.end == "number"
);
}
export default function TranscriptCorrect(details: TranscriptCorrect) { export default function TranscriptCorrect(details: TranscriptCorrect) {
const transcriptId = details.params.transcriptId; const transcriptId = details.params.transcriptId;
const transcript = useTranscript(transcriptId); const transcript = useTranscript(transcriptId);
const [currentTopic, setCurrentTopic] = useState(""); const stateCurrentTopic = useState<GetTranscriptTopic>();
const topicWithWords = useTopicWithWords(currentTopic, transcriptId); const [currentTopic, _sct] = stateCurrentTopic;
const topicWithWords = useTopicWithWords(currentTopic?.id, transcriptId);
const [selectedTime, setSelectedTime] = useState<TimeSlice>();
const [topicTime, setTopicTime] = useState<TimeSlice>(); const [topicTime, setTopicTime] = useState<TimeSlice>();
const participants = useParticipants(transcriptId); const participants = useParticipants(transcriptId);
const stateSelectedSpeaker = useState<number>(); const stateSelectedText = useState<SelectedText>();
const [selectedText, _sst] = stateSelectedText;
console.log(selectedText);
useEffect(() => {
if (currentTopic) {
setTopicTime({
start: currentTopic.timestamp,
end: currentTopic.timestamp + currentTopic.duration,
});
} else {
setTopicTime(undefined);
}
}, [currentTopic]);
// TODO BE // TODO BE
// Get one topic with words
// -> fix useTopicWithWords.ts
// Add start and end time of each topic in the topic list
// -> use full current topic instead of topicId here
// -> remove time calculation and setting from TopicHeader
// -> pass in topicTime to player directly
// Should we have participants by default, one for each speaker ?
// Creating a participant and a speaker ? // Creating a participant and a speaker ?
return ( return (
<div className="h-full grid grid-cols-2 gap-4"> <div className="h-full grid grid-cols-2 gap-4">
<div className="flex flex-col h-full"> <div className="flex flex-col h-full">
<TopicHeader <TopicHeader
currentTopic={currentTopic} stateCurrentTopic={stateCurrentTopic}
setCurrentTopic={setCurrentTopic}
transcriptId={transcriptId} transcriptId={transcriptId}
/> />
<TopicWords <TopicWords
setSelectedTime={setSelectedTime} stateSelectedText={stateSelectedText}
selectedTime={selectedTime}
setTopicTime={setTopicTime}
stateSelectedSpeaker={stateSelectedSpeaker}
participants={participants} participants={participants}
topicWithWords={topicWithWords} topicWithWords={topicWithWords}
/> />
@@ -61,16 +79,17 @@ export default function TranscriptCorrect(details: TranscriptCorrect) {
<div className="flex flex-col justify-stretch"> <div className="flex flex-col justify-stretch">
<TopicPlayer <TopicPlayer
transcriptId={transcriptId} transcriptId={transcriptId}
selectedTime={selectedTime} selectedTime={
selectedTextIsTimeSlice(selectedText) ? selectedText : undefined
}
topicTime={topicTime} topicTime={topicTime}
/> />
<ParticipantList <ParticipantList
{...{ {...{
transcriptId, transcriptId,
participants, participants,
selectedTime,
topicWithWords, topicWithWords,
stateSelectedSpeaker, stateSelectedText,
}} }}
/> />
</div> </div>

View File

@@ -4,28 +4,27 @@ import { useEffect, useRef, useState } from "react";
import { Participant } from "../../../../api"; import { Participant } from "../../../../api";
import getApi from "../../../../lib/getApi"; import getApi from "../../../../lib/getApi";
import { UseParticipants } from "../../useParticipants"; import { UseParticipants } from "../../useParticipants";
import { selectedTextIsSpeaker, selectedTextIsTimeSlice } from "./page";
type ParticipantList = { type ParticipantList = {
participants: UseParticipants; participants: UseParticipants;
transcriptId: string; transcriptId: string;
selectedTime: any;
topicWithWords: any; topicWithWords: any;
stateSelectedSpeaker: any; stateSelectedText: any;
}; };
const ParticipantList = ({ const ParticipantList = ({
transcriptId, transcriptId,
participants, participants,
selectedTime,
topicWithWords, topicWithWords,
stateSelectedSpeaker, stateSelectedText,
}: ParticipantList) => { }: ParticipantList) => {
const api = getApi(); const api = getApi();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [participantInput, setParticipantInput] = useState(""); const [participantInput, setParticipantInput] = useState("");
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const [selectedSpeaker, setSelectedSpeaker] = stateSelectedSpeaker; const [selectedText, setSelectedText] = stateSelectedText;
const [selectedParticipant, setSelectedParticipant] = useState<Participant>(); const [selectedParticipant, setSelectedParticipant] = useState<Participant>();
const [action, setAction] = useState< const [action, setAction] = useState<
"Create" | "Create to rename" | "Create and assign" | "Rename" | null "Create" | "Create to rename" | "Create and assign" | "Rename" | null
@@ -40,10 +39,10 @@ const ParticipantList = ({
useEffect(() => { useEffect(() => {
if (participants.response) { if (participants.response) {
if (selectedSpeaker !== undefined) { if (selectedTextIsSpeaker(selectedText)) {
inputRef.current?.focus(); inputRef.current?.focus();
const participant = participants.response.find( const participant = participants.response.find(
(p) => p.speaker == selectedSpeaker, (p) => p.speaker == selectedText,
); );
if (participant) { if (participant) {
setParticipantInput(participant.name); setParticipantInput(participant.name);
@@ -57,20 +56,23 @@ const ParticipantList = ({
setAction("Create to rename"); setAction("Create to rename");
} }
} }
if (selectedTime) { if (selectedTextIsTimeSlice(selectedText)) {
setParticipantInput(""); setParticipantInput("");
inputRef.current?.focus(); inputRef.current?.focus();
setAction("Create and assign"); setAction("Create and assign");
setSelectedParticipant(undefined); setSelectedParticipant(undefined);
} }
if (!selectedTime && !selectedSpeaker) { if (typeof selectedText == undefined) {
setAction(null); setAction(null);
} }
} }
}, [selectedTime, selectedSpeaker]); }, [selectedText]);
useEffect(() => { useEffect(() => {
if (participants.response && action == "Create and assign") { if (
participants.response &&
(action == "Create and assign" || action == "Create to rename")
) {
if ( if (
participants.response.filter((p) => p.name.startsWith(participantInput)) participants.response.filter((p) => p.name.startsWith(participantInput))
.length == 1 .length == 1
@@ -87,18 +89,23 @@ const ParticipantList = ({
if (participantInput && !action) { if (participantInput && !action) {
setAction("Create"); setAction("Create");
} }
if (!participantInput) {
setAction(null);
}
}, [participantInput]); }, [participantInput]);
useEffect(() => { useEffect(() => {
document.onkeyup = (e) => { document.onkeyup = (e) => {
if (e.key === "Enter" && e.ctrlKey) { if (e.key === "Enter" && e.ctrlKey) {
if (oneMatch) { if (oneMatch) {
if (action == "Create and assign") {
assignTo(oneMatch)(); assignTo(oneMatch)();
setOneMatch(undefined); setOneMatch(undefined);
setParticipantInput(""); setParticipantInput("");
} else if (
action == "Create to rename" &&
oneMatch &&
selectedTextIsSpeaker(selectedText)
) {
mergeSpeaker(selectedText, oneMatch)();
}
} }
} else if (e.key === "Enter") { } else if (e.key === "Enter") {
doAction(); doAction();
@@ -106,13 +113,36 @@ const ParticipantList = ({
}; };
}); });
const mergeSpeaker =
(speakerFrom, participantTo: Participant) => async () => {
if (participantTo.speaker) {
await api?.v1TranscriptMergeSpeaker({
transcriptId,
speakerMerge: {
speakerFrom: speakerFrom,
speakerTo: participantTo.speaker,
},
});
} else {
await api?.v1TranscriptUpdateParticipant({
transcriptId,
participantId: participantTo.id,
updateParticipant: { speaker: speakerFrom },
});
}
participants.refetch();
topicWithWords.refetch();
setAction(null);
setParticipantInput("");
};
const doAction = (e?) => { const doAction = (e?) => {
e?.preventDefault(); e?.preventDefault();
e?.stopPropagation(); e?.stopPropagation();
if (!participants.response) return; if (!participants.response) return;
if (action == "Rename") { if (action == "Rename" && selectedTextIsSpeaker(selectedText)) {
const participant = participants.response.find( const participant = participants.response.find(
(p) => p.speaker == selectedSpeaker, (p) => p.speaker == selectedText,
); );
if (participant && participant.name !== participantInput) { if (participant && participant.name !== participantInput) {
api api
@@ -127,14 +157,16 @@ const ParticipantList = ({
participants.refetch(); participants.refetch();
}); });
} }
} else if (action == "Create to rename") { } else if (
action == "Create to rename" &&
selectedTextIsSpeaker(selectedText)
) {
setLoading(true); setLoading(true);
console.log(participantInput, selectedSpeaker);
api api
?.v1TranscriptAddParticipant({ ?.v1TranscriptAddParticipant({
createParticipant: { createParticipant: {
name: participantInput, name: participantInput,
speaker: selectedSpeaker, speaker: selectedText,
}, },
transcriptId, transcriptId,
}) })
@@ -142,13 +174,15 @@ const ParticipantList = ({
participants.refetch(); participants.refetch();
setParticipantInput(""); setParticipantInput("");
}); });
} else if (action == "Create and assign") { } else if (
action == "Create and assign" &&
selectedTextIsTimeSlice(selectedText)
) {
setLoading(true); setLoading(true);
api api
?.v1TranscriptAddParticipant({ ?.v1TranscriptAddParticipant({
createParticipant: { createParticipant: {
name: participantInput, name: participantInput,
speaker: Math.floor(Math.random() * 100 + 10),
}, },
transcriptId, transcriptId,
}) })
@@ -191,14 +225,14 @@ const ParticipantList = ({
e?.preventDefault(); e?.preventDefault();
e?.stopPropagation(); e?.stopPropagation();
// fix participant that doesnt have a speaker (wait API) // fix participant that doesnt have a speaker (wait API)
if (selectedTime?.start == undefined || selectedTime?.end == undefined) if (!selectedTextIsTimeSlice(selectedText)) return;
return;
api api
?.v1TranscriptAssignSpeaker({ ?.v1TranscriptAssignSpeaker({
speakerAssignment: { speakerAssignment: {
speaker: participant.speaker, participant: participant.id,
timestampFrom: selectedTime.start, timestampFrom: selectedText.start,
timestampTo: selectedTime.end, timestampTo: selectedText.end,
}, },
transcriptId, transcriptId,
}) })
@@ -209,12 +243,24 @@ const ParticipantList = ({
const selectParticipant = (participant) => (e) => { const selectParticipant = (participant) => (e) => {
setSelectedParticipant(participant); setSelectedParticipant(participant);
setSelectedSpeaker(participant.speaker); setSelectedText(participant.speaker);
setAction("Rename"); setAction("Rename");
setParticipantInput(participant.name); setParticipantInput(participant.name);
}; };
const clearSelection = () => {
setSelectedParticipant(undefined);
setSelectedText(undefined);
setAction(null);
};
const preventClick = (e) => {
e?.stopPropagation();
e?.preventDefault();
};
return ( return (
<> <div className="h-full" onClick={clearSelection}>
<div onClick={preventClick}>
<div> <div>
<input <input
ref={inputRef} ref={inputRef}
@@ -246,7 +292,7 @@ const ParticipantList = ({
className={ className={
"flex flex-row justify-between " + "flex flex-row justify-between " +
(participantInput.length > 0 && (participantInput.length > 0 &&
selectedTime && selectedText &&
participant.name.startsWith(participantInput) participant.name.startsWith(participantInput)
? "bg-blue-100 " ? "bg-blue-100 "
: "") + : "") +
@@ -259,9 +305,27 @@ const ParticipantList = ({
<span>{participant.name}</span> <span>{participant.name}</span>
<div> <div>
{selectedTime && !loading && ( {selectedTextIsSpeaker(selectedText) && !loading && (
<button onClick={mergeSpeaker(selectedText, participant)}>
{oneMatch &&
action == "Create to rename" &&
participant.name.startsWith(participantInput) && (
<>
{" "}
<span>CTRL + </span>{" "}
<FontAwesomeIcon
icon={faArrowTurnDown}
className="rotate-90 mr-2"
/>{" "}
</>
)}{" "}
Merge
</button>
)}
{selectedTextIsTimeSlice(selectedText) && !loading && (
<button onClick={assignTo(participant)}> <button onClick={assignTo(participant)}>
{oneMatch && {oneMatch &&
action == "Create and assign" &&
participant.name.startsWith(participantInput) && ( participant.name.startsWith(participantInput) && (
<> <>
{" "} {" "}
@@ -284,7 +348,8 @@ const ParticipantList = ({
))} ))}
</ul> </ul>
)} )}
</> </div>
</div>
); );
}; };

View File

@@ -1,32 +1,41 @@
import { faArrowLeft, faArrowRight } from "@fortawesome/free-solid-svg-icons"; import { faArrowLeft, faArrowRight } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import useTopics from "../../useTopics"; import useTopics from "../../useTopics";
import { useEffect } from "react"; import { Dispatch, SetStateAction, useEffect } from "react";
import { TranscriptTopic } from "../../../../api/models/TranscriptTopic";
import { GetTranscriptTopic } from "../../../../api";
type TopicHeader = {
stateCurrentTopic: [
GetTranscriptTopic | undefined,
Dispatch<SetStateAction<GetTranscriptTopic | undefined>>,
];
transcriptId: string;
};
export default function TopicHeader({ export default function TopicHeader({
currentTopic, stateCurrentTopic,
setCurrentTopic,
transcriptId, transcriptId,
}) { }: TopicHeader) {
const [currentTopic, setCurrentTopic] = stateCurrentTopic;
const topics = useTopics(transcriptId); const topics = useTopics(transcriptId);
useEffect(() => { useEffect(() => {
if (!topics.loading && !currentTopic) { if (!topics.loading && !currentTopic) {
setCurrentTopic(topics?.topics?.at(0)?.id); setCurrentTopic(topics?.topics?.at(0));
} }
}, [topics.loading]); }, [topics.loading]);
if (topics.topics) { if (topics.topics && currentTopic) {
const title = topics.topics.find((topic) => topic.id == currentTopic) const number = topics.topics.findIndex(
?.title; (topic) => topic.id == currentTopic.id,
const number = topics.topics.findIndex((topic) => topic.id == currentTopic); );
const canGoPrevious = number > 0; const canGoPrevious = number > 0;
const total = topics.topics.length; const total = topics.topics.length;
const canGoNext = total && number < total + 1; const canGoNext = total && number < total + 1;
const onPrev = () => const onPrev = () => setCurrentTopic(topics.topics?.at(number - 1));
setCurrentTopic(topics.topics?.at(number - 1)?.id || ""); const onNext = () => setCurrentTopic(topics.topics?.at(number + 1));
const onNext = () =>
setCurrentTopic(topics.topics?.at(number + 1)?.id || "");
return ( return (
<div className="flex flex-row"> <div className="flex flex-row">
@@ -40,7 +49,7 @@ export default function TopicHeader({
<FontAwesomeIcon icon={faArrowLeft} /> <FontAwesomeIcon icon={faArrowLeft} />
</button> </button>
<h1 className="flex-grow"> <h1 className="flex-grow">
{title}{" "} {currentTopic.title}{" "}
<span> <span>
{number + 1}/{total} {number + 1}/{total}
</span> </span>

View File

@@ -1,68 +1,43 @@
import { SetStateAction, useCallback, useEffect, useState } from "react"; import {
Dispatch,
SetStateAction,
useCallback,
useEffect,
useState,
} from "react";
import WaveformLoading from "../../waveformLoading"; import WaveformLoading from "../../waveformLoading";
import { UseParticipants } from "../../useParticipants"; import { UseParticipants } from "../../useParticipants";
import { Participant } from "../../../../api"; import { Participant } from "../../../../api";
import { UseTopicWithWords } from "../../useTopicWithWords";
type Word = { import { TimeSlice, selectedTextIsTimeSlice } from "./page";
end: number;
speaker: number;
start: number;
text: string;
};
type WordBySpeaker = { speaker: number; words: Word[] }[];
// TODO shortcuts ? // TODO shortcuts ?
// TODO fix key (using indexes might act up, not sure as we don't re-order per say) // TODO fix key (using indexes might act up, not sure as we don't re-order per say)
type TopicWordsProps = { type TopicWordsProps = {
setSelectedTime: SetStateAction<any>; stateSelectedText: [
selectedTime: any; number | TimeSlice | undefined,
setTopicTime: SetStateAction<any>; Dispatch<SetStateAction<number | TimeSlice | undefined>>,
stateSelectedSpeaker: any; ];
participants: UseParticipants; participants: UseParticipants;
topicWithWords: any; topicWithWords: UseTopicWithWords;
}; };
const topicWords = ({ const topicWords = ({
setSelectedTime, stateSelectedText,
selectedTime,
setTopicTime,
stateSelectedSpeaker,
participants, participants,
topicWithWords, topicWithWords,
}: TopicWordsProps) => { }: TopicWordsProps) => {
const [wordsBySpeaker, setWordsBySpeaker] = useState<WordBySpeaker>(); const [selectedText, setSelectedText] = stateSelectedText;
const [selectedSpeaker, setSelectedSpeaker] = stateSelectedSpeaker;
useEffect(() => { useEffect(() => {
if (topicWithWords.loading) { if (topicWithWords.loading) {
setWordsBySpeaker([]); // setWordsBySpeaker([]);
setSelectedTime(undefined); setSelectedText(undefined);
console.log("unsetting topic changed"); console.log("unsetting topic changed");
} }
}, [topicWithWords.loading]); }, [topicWithWords.loading]);
useEffect(() => {
if (!topicWithWords.loading && !topicWithWords.error) {
const wordsFlat = topicWithWords.response.words as Word[];
const wordsSorted = wordsFlat.reduce((acc, curr) => {
if (acc.length > 0 && acc[acc.length - 1].speaker == curr.speaker) {
acc[acc.length - 1].words.push(curr);
return acc;
} else {
acc?.push({ speaker: curr.speaker, words: [curr] });
return acc;
}
}, [] as WordBySpeaker);
setWordsBySpeaker(wordsSorted);
setTopicTime({
start: wordsFlat.at(0)?.start,
end: wordsFlat.at(wordsFlat.length - 1)?.end,
});
}
}, [topicWithWords.response]);
const getStartTimeFromFirstNode = (node, offset, reverse) => { const getStartTimeFromFirstNode = (node, offset, reverse) => {
// if the first element is a word // if the first element is a word
return node.parentElement?.dataset["start"] return node.parentElement?.dataset["start"]
@@ -91,7 +66,7 @@ const topicWords = ({
selection.anchorNode == selection.focusNode && selection.anchorNode == selection.focusNode &&
selection.anchorOffset == selection.focusOffset selection.anchorOffset == selection.focusOffset
) { ) {
setSelectedTime(undefined); setSelectedText(undefined);
selection.empty(); selection.empty();
return; return;
} }
@@ -114,9 +89,11 @@ const topicWords = ({
!focusIsWord && !focusIsWord &&
anchorNode.parentElement == focusNode.parentElement anchorNode.parentElement == focusNode.parentElement
) { ) {
setSelectedSpeaker(focusNode.parentElement?.dataset["speaker"]); setSelectedText(
setSelectedTime(undefined); focusNode.parentElement?.dataset["speaker"]
selection.empty(); ? parseInt(focusNode.parentElement?.dataset["speaker"])
: undefined,
);
console.log("Unset Time : selected Speaker"); console.log("Unset Time : selected Speaker");
return; return;
} }
@@ -139,7 +116,7 @@ const topicWords = ({
const reverse = parseFloat(anchorStart) > parseFloat(focusEnd); const reverse = parseFloat(anchorStart) > parseFloat(focusEnd);
if (!reverse) { if (!reverse) {
setSelectedTime({ setSelectedText({
start: parseFloat(anchorStart), start: parseFloat(anchorStart),
end: parseFloat(focusEnd), end: parseFloat(focusEnd),
}); });
@@ -158,13 +135,14 @@ const topicWords = ({
true, true,
); );
setSelectedTime({ start: focusStart, end: anchorEnd }); setSelectedText({
start: parseFloat(focusStart),
end: parseFloat(anchorEnd),
});
console.log("setting reverse"); console.log("setting reverse");
} }
setSelectedSpeaker();
selection.empty();
} }
selection && selection.empty();
}; };
const getSpeakerName = (speakerNumber: number) => { const getSpeakerName = (speakerNumber: number) => {
@@ -176,15 +154,20 @@ const topicWords = ({
); );
}; };
if (!topicWithWords.loading && wordsBySpeaker && participants.response) { if (
!topicWithWords.loading &&
topicWithWords.response &&
participants.response
) {
return ( return (
<div onMouseUp={onMouseUp} className="p-5 h-full w-full"> <div onMouseUp={onMouseUp} className="p-5 h-full w-full">
{wordsBySpeaker?.map((speakerWithWords, index) => ( {topicWithWords.response.wordsPerSpeaker.map(
(speakerWithWords, index) => (
<p key={index}> <p key={index}>
<span <span
data-speaker={speakerWithWords.speaker} data-speaker={speakerWithWords.speaker}
className={ className={
selectedSpeaker == speakerWithWords.speaker selectedText == speakerWithWords.speaker
? "bg-yellow-200" ? "bg-yellow-200"
: "" : ""
} }
@@ -197,9 +180,9 @@ const topicWords = ({
data-end={word.end} data-end={word.end}
key={index} key={index}
className={ className={
selectedTime && selectedTextIsTimeSlice(selectedText) &&
selectedTime.start <= word.start && selectedText.start <= word.start &&
selectedTime.end >= word.end selectedText.end >= word.end
? "bg-yellow-200" ? "bg-yellow-200"
: "" : ""
} }
@@ -208,7 +191,8 @@ const topicWords = ({
</span> </span>
))} ))}
</p> </p>
))} ),
)}
</div> </div>
); );
} }

View File

@@ -5,6 +5,7 @@
"summary": "The team discusses the first issue in the list", "summary": "The team discusses the first issue in the list",
"timestamp": 0.0, "timestamp": 0.0,
"transcript": "", "transcript": "",
"duration": 33,
"segments": [ "segments": [
{ {
"text": "Let's start with issue one, Alice you've been working on that, can you give an update ?", "text": "Let's start with issue one, Alice you've been working on that, can you give an update ?",

View File

@@ -1,6 +1,13 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { V1TranscriptGetTopicsWithWordsRequest } from "../../api/apis/DefaultApi"; import {
import { GetTranscript, GetTranscriptTopicWithWords } from "../../api"; V1TranscriptGetTopicsWithWordsPerSpeakerRequest,
V1TranscriptGetTopicsWithWordsRequest,
} from "../../api/apis/DefaultApi";
import {
GetTranscript,
GetTranscriptTopicWithWords,
GetTranscriptTopicWithWordsPerSpeaker,
} from "../../api";
import { useError } from "../../(errors)/errorContext"; import { useError } from "../../(errors)/errorContext";
import getApi from "../../lib/getApi"; import getApi from "../../lib/getApi";
import { shouldShowError } from "../../lib/errorUtils"; import { shouldShowError } from "../../lib/errorUtils";
@@ -8,22 +15,22 @@ import { shouldShowError } from "../../lib/errorUtils";
type ErrorTopicWithWords = { type ErrorTopicWithWords = {
error: Error; error: Error;
loading: false; loading: false;
response: any; response: null;
}; };
type LoadingTopicWithWords = { type LoadingTopicWithWords = {
response: any; response: GetTranscriptTopicWithWordsPerSpeaker | null;
loading: true; loading: true;
error: false; error: false;
}; };
type SuccessTopicWithWords = { type SuccessTopicWithWords = {
response: GetTranscriptTopicWithWords; response: GetTranscriptTopicWithWordsPerSpeaker;
loading: false; loading: false;
error: null; error: null;
}; };
type UseTopicWithWords = { refetch: () => void } & ( export type UseTopicWithWords = { refetch: () => void } & (
| ErrorTopicWithWords | ErrorTopicWithWords
| LoadingTopicWithWords | LoadingTopicWithWords
| SuccessTopicWithWords | SuccessTopicWithWords
@@ -33,7 +40,8 @@ const useTopicWithWords = (
topicId: string | null, topicId: string | null,
transcriptId: string, transcriptId: string,
): UseTopicWithWords => { ): UseTopicWithWords => {
const [response, setResponse] = useState<GetTranscript | null>(null); const [response, setResponse] =
useState<GetTranscriptTopicWithWordsPerSpeaker | null>(null);
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [error, setErrorState] = useState<Error | null>(null); const [error, setErrorState] = useState<Error | null>(null);
const { setError } = useError(); const { setError } = useError();
@@ -55,13 +63,14 @@ const useTopicWithWords = (
if (!transcriptId || !topicId || !api) return; if (!transcriptId || !topicId || !api) return;
setLoading(true); setLoading(true);
const requestParameters: V1TranscriptGetTopicsWithWordsRequest = { const requestParameters: V1TranscriptGetTopicsWithWordsPerSpeakerRequest = {
transcriptId, transcriptId,
topicId,
}; };
api api
.v1TranscriptGetTopicsWithWords(requestParameters) .v1TranscriptGetTopicsWithWordsPerSpeaker(requestParameters)
.then((result) => { .then((result) => {
setResponse(result.find((topic) => topic.id == topicId)); setResponse(result);
setLoading(false); setLoading(false);
console.debug("Topics with words Loaded:", result); console.debug("Topics with words Loaded:", result);
}) })

View File

@@ -5,9 +5,10 @@ import { Topic } from "./webSocketTypes";
import getApi from "../../lib/getApi"; import getApi from "../../lib/getApi";
import { shouldShowError } from "../../lib/errorUtils"; import { shouldShowError } from "../../lib/errorUtils";
import mockTopics from "./mockTopics.json"; import mockTopics from "./mockTopics.json";
import { GetTranscriptTopic } from "../../api";
type TranscriptTopics = { type TranscriptTopics = {
topics: Topic[] | null; topics: GetTranscriptTopic[] | null;
loading: boolean; loading: boolean;
error: Error | null; error: Error | null;
}; };