diff --git a/www/app/[domain]/transcripts/[transcriptId]/correct/page.tsx b/www/app/[domain]/transcripts/[transcriptId]/correct/page.tsx index 4277c18e..c27abef7 100644 --- a/www/app/[domain]/transcripts/[transcriptId]/correct/page.tsx +++ b/www/app/[domain]/transcripts/[transcriptId]/correct/page.tsx @@ -28,7 +28,6 @@ export default function TranscriptCorrect(details: TranscriptCorrect) { const [selectedTime, setSelectedTime] = useState(); const [topicTime, setTopicTime] = useState(); - const api = getApi(); const participants = useParticipants(transcriptId); const stateSelectedSpeaker = useState(); @@ -66,7 +65,13 @@ export default function TranscriptCorrect(details: TranscriptCorrect) { topicTime={topicTime} /> diff --git a/www/app/[domain]/transcripts/[transcriptId]/correct/participantList.tsx b/www/app/[domain]/transcripts/[transcriptId]/correct/participantList.tsx index 09e1b3d6..807d2842 100644 --- a/www/app/[domain]/transcripts/[transcriptId]/correct/participantList.tsx +++ b/www/app/[domain]/transcripts/[transcriptId]/correct/participantList.tsx @@ -1,35 +1,36 @@ -import { faSpinner } from "@fortawesome/free-solid-svg-icons"; +import { faArrowTurnDown, faSpinner } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useEffect, useRef, useState } from "react"; import { Participant } from "../../../../api"; import getApi from "../../../../lib/getApi"; +import { UseParticipants } from "../../useParticipants"; +import { unescapeLeadingUnderscores } from "typescript"; + +type ParticipantList = { + participants: UseParticipants; + transcriptId: string; + selectedTime: any; + topicWithWords: any; + stateSelectedSpeaker: any; +}; const ParticipantList = ({ transcriptId, participants, selectedTime, topicWithWords, -}) => { + stateSelectedSpeaker, +}: ParticipantList) => { const api = getApi(); const [loading, setLoading] = useState(false); const [participantInput, setParticipantInput] = useState(""); const inputRef = useRef(null); - - const createParticipant = () => { - if (!loading) { - setLoading(true); - api - ?.v1TranscriptAddParticipant({ - createParticipant: { name: participantInput, speaker: 99 }, - transcriptId, - }) - .then((participant) => { - participants.refetch(); - assignTo(participant)(); - }); - } - }; + const [selectedSpeaker, setSelectedSpeaker] = stateSelectedSpeaker; + const [action, setAction] = useState< + "Create" | "Create to rename" | "Create and assign" | "Rename" | null + >(null); + const [oneMatch, setOneMatch] = useState(); useEffect(() => { if (loading) { @@ -38,10 +39,111 @@ const ParticipantList = ({ }, [participants.loading]); useEffect(() => { - if (selectedTime) { - inputRef.current?.focus(); + if (participants.response) { + if (selectedSpeaker !== undefined) { + inputRef.current?.focus(); + const participant = participants.response.find( + (p) => p.speaker == selectedSpeaker, + ); + if (participant) { + setParticipantInput(participant.name); + inputRef.current?.focus(); + setAction("Rename"); + } else { + setParticipantInput(""); + inputRef.current?.focus(); + setAction("Create to rename"); + } + } + if (selectedTime) { + setParticipantInput(""); + inputRef.current?.focus(); + setAction("Create and assign"); + } } - }, [selectedTime]); + }, [selectedTime, selectedSpeaker]); + + useEffect(() => { + if (participants.response && action == "Create and assign") { + if ( + participants.response.filter((p) => p.name.startsWith(participantInput)) + .length == 1 + ) { + setOneMatch( + participants.response.find((p) => + p.name.startsWith(participantInput), + ), + ); + } else { + setOneMatch(undefined); + } + } + }, [participantInput]); + + useEffect(() => { + document.onkeyup = (e) => { + if (e.key === "Enter" && e.ctrlKey) { + if (oneMatch) { + assignTo(oneMatch)(); + setOneMatch(undefined); + setParticipantInput(""); + } + } + }; + }); + + const doAction = (e) => { + if (!participants.response) return; + if (action == "Rename") { + const participant = participants.response.find( + (p) => p.speaker == selectedSpeaker, + ); + if (participant && participant.name !== participantInput) { + api + ?.v1TranscriptUpdateParticipant({ + participantId: participant.id, + transcriptId, + updateParticipant: { + name: participantInput, + }, + }) + .then(() => { + participants.refetch(); + }); + } + } else if (action == "Create to rename") { + setLoading(true); + console.log(participantInput, selectedSpeaker); + api + ?.v1TranscriptAddParticipant({ + createParticipant: { + name: participantInput, + speaker: selectedSpeaker, + }, + transcriptId, + }) + .then(() => { + participants.refetch(); + }); + } else if (action == "Create and assign") { + setLoading(true); + api + ?.v1TranscriptAddParticipant({ + createParticipant: { + name: participantInput, + speaker: Math.floor(Math.random() * 100 + 10), + }, + transcriptId, + }) + .then((participant) => { + assignTo(participant)(); + participants.refetch(); + }); + } + e.preventDefault(); + console.log(e); + console.log(action); + }; const deleteParticipant = (participantId) => () => { if (!loading) { @@ -75,13 +177,25 @@ const ParticipantList = ({ topicWithWords.refetch(); }); }; + + const selectParticipant = (participant) => (e) => { + console.log(participant, e); + setSelectedSpeaker(participant.speaker); + }; return ( <> - setParticipantInput(e.target.value)} - /> - +
+ setParticipantInput(e.target.value)} + value={participantInput} + /> + +
+ {participants.loading && ( {participants.response.map((participant: Participant) => ( -
  • +
  • 0 && + selectedTime && + participant.name.startsWith(participantInput) + ? "bg-blue-100 " + : "") + + (participant.speaker == selectedSpeaker + ? "border-blue-400 border" + : "") + } + key={participant.id} + > {participant.name} +
    - + {selectedTime && !loading && ( + + )} + diff --git a/www/app/[domain]/transcripts/[transcriptId]/correct/topicWords.tsx b/www/app/[domain]/transcripts/[transcriptId]/correct/topicWords.tsx index 1166d4a6..4806f102 100644 --- a/www/app/[domain]/transcripts/[transcriptId]/correct/topicWords.tsx +++ b/www/app/[domain]/transcripts/[transcriptId]/correct/topicWords.tsx @@ -97,6 +97,7 @@ const topicWords = ({ ) { setSelectedSpeaker(focusNode.parentElement?.dataset["speaker"]); setSelectedTime(undefined); + selection.empty(); console.log("Unset Time : selected Speaker"); return; } @@ -111,9 +112,7 @@ const topicWords = ({ selection.focusNode.parentElement?.parentElement ?.previousElementSibling?.lastElementChild as any )?.dataset["end"]; - - const reverse = anchorStart > focusEnd; - setSelectedTime(undefined); + const reverse = parseFloat(anchorStart) > parseFloat(focusEnd); if (!reverse) { setSelectedTime({ start: anchorStart, end: focusEnd }); diff --git a/www/app/[domain]/transcripts/useParticipants.ts b/www/app/[domain]/transcripts/useParticipants.ts index bcf2ac3b..73673ef2 100644 --- a/www/app/[domain]/transcripts/useParticipants.ts +++ b/www/app/[domain]/transcripts/useParticipants.ts @@ -8,11 +8,11 @@ import { shouldShowError } from "../../lib/errorUtils"; type ErrorParticipants = { error: Error; loading: false; - response: any; + response: null; }; type LoadingParticipants = { - response: any; + response: Participant[] | null; loading: true; error: false; }; @@ -30,7 +30,7 @@ export type UseParticipants = ( ) & { refetch: () => void }; const useParticipants = (transcriptId: string): UseParticipants => { - const [response, setResponse] = useState(null); + const [response, setResponse] = useState(null); const [loading, setLoading] = useState(true); const [error, setErrorState] = useState(null); const { setError } = useError();