prevent double action

This commit is contained in:
Sara
2023-12-12 15:18:22 +01:00
parent 89dfda29a5
commit 5e7eeb8f24
6 changed files with 126 additions and 86 deletions

View File

@@ -38,7 +38,6 @@ export function selectedTextIsTimeSlice(
export default function TranscriptCorrect(details: TranscriptCorrect) {
const transcriptId = details.params.transcriptId;
const transcript = useTranscript(transcriptId);
const stateCurrentTopic = useState<GetTranscriptTopic>();
const [currentTopic, _sct] = stateCurrentTopic;
const topicWithWords = useTopicWithWords(currentTopic?.id, transcriptId);
@@ -47,7 +46,6 @@ export default function TranscriptCorrect(details: TranscriptCorrect) {
const participants = useParticipants(transcriptId);
const stateSelectedText = useState<SelectedText>();
const [selectedText, _sst] = stateSelectedText;
console.log(selectedText);
useEffect(() => {
if (currentTopic) {
@@ -60,9 +58,6 @@ export default function TranscriptCorrect(details: TranscriptCorrect) {
}
}, [currentTopic]);
// TODO BE
// Creating a participant and a speaker ?
return (
<div className="h-full grid grid-cols-2 gap-4">
<div className="flex flex-col h-full">

View File

@@ -12,7 +12,7 @@ type ParticipantList = {
topicWithWords: any;
stateSelectedText: any;
};
// NTH re-order list when searching
const ParticipantList = ({
transcriptId,
participants,
@@ -31,12 +31,6 @@ const ParticipantList = ({
>(null);
const [oneMatch, setOneMatch] = useState<Participant>();
useEffect(() => {
if (loading) {
setLoading(false);
}
}, [participants.loading]);
useEffect(() => {
if (participants.response) {
if (selectedTextIsSpeaker(selectedText)) {
@@ -93,6 +87,7 @@ const ParticipantList = ({
useEffect(() => {
document.onkeyup = (e) => {
if (loading || participants.loading || topicWithWords.loading) return;
if (e.key === "Enter" && e.ctrlKey) {
if (oneMatch) {
if (action == "Create and assign") {
@@ -115,7 +110,9 @@ const ParticipantList = ({
const mergeSpeaker =
(speakerFrom, participantTo: Participant) => async () => {
if (loading || participants.loading || topicWithWords.loading) return;
if (participantTo.speaker) {
setLoading(true);
await api?.v1TranscriptMergeSpeaker({
transcriptId,
speakerMerge: {
@@ -134,17 +131,25 @@ const ParticipantList = ({
topicWithWords.refetch();
setAction(null);
setParticipantInput("");
setLoading(false);
};
const doAction = (e?) => {
e?.preventDefault();
e?.stopPropagation();
if (!participants.response) return;
if (
loading ||
participants.loading ||
topicWithWords.loading ||
!participants.response
)
return;
if (action == "Rename" && selectedTextIsSpeaker(selectedText)) {
const participant = participants.response.find(
(p) => p.speaker == selectedText,
);
if (participant && participant.name !== participantInput) {
setLoading(true);
api
?.v1TranscriptUpdateParticipant({
participantId: participant.id,
@@ -155,6 +160,7 @@ const ParticipantList = ({
})
.then(() => {
participants.refetch();
setLoading(false);
});
}
} else if (
@@ -173,6 +179,7 @@ const ParticipantList = ({
.then(() => {
participants.refetch();
setParticipantInput("");
setLoading(false);
});
} else if (
action == "Create and assign" &&
@@ -187,8 +194,8 @@ const ParticipantList = ({
transcriptId,
})
.then((participant) => {
setLoading(false);
assignTo(participant)();
participants.refetch();
setParticipantInput("");
});
} else if (action == "Create") {
@@ -203,31 +210,34 @@ const ParticipantList = ({
.then(() => {
participants.refetch();
setParticipantInput("");
setLoading(false);
});
}
};
const deleteParticipant = (participantId) => (e) => {
e.stopPropagation();
if (!loading) {
api
?.v1TranscriptDeleteParticipant({
transcriptId,
participantId,
})
.then(() => {
participants.refetch();
});
}
if (loading || participants.loading || topicWithWords.loading) return;
setLoading(true);
api
?.v1TranscriptDeleteParticipant({
transcriptId,
participantId,
})
.then(() => {
participants.refetch();
setLoading(false);
});
};
const assignTo =
(participant) => (e?: React.MouseEvent<HTMLButtonElement>) => {
e?.preventDefault();
e?.stopPropagation();
// fix participant that doesnt have a speaker (wait API)
if (loading || participants.loading || topicWithWords.loading) return;
if (!selectedTextIsTimeSlice(selectedText)) return;
setLoading(true);
api
?.v1TranscriptAssignSpeaker({
speakerAssignment: {
@@ -239,6 +249,8 @@ const ParticipantList = ({
})
.then(() => {
topicWithWords.refetch();
participants.refetch();
setLoading(false);
});
};
@@ -253,6 +265,7 @@ const ParticipantList = ({
setSelectedParticipant(undefined);
setSelectedText(undefined);
setAction(null);
setParticipantInput("");
};
const preventClick = (e) => {
e?.stopPropagation();
@@ -279,12 +292,14 @@ const ParticipantList = ({
)}
</div>
{participants.loading && (
<FontAwesomeIcon
icon={faSpinner}
className="animate-spin-slow text-gray-300 h-8"
/>
)}
{loading ||
participants.loading ||
(topicWithWords.loading && (
<FontAwesomeIcon
icon={faSpinner}
className="animate-spin-slow text-gray-300 h-8"
/>
))}
{participants.response && (
<ul>
{participants.response.map((participant: Participant) => (
@@ -306,23 +321,25 @@ const ParticipantList = ({
<span>{participant.name}</span>
<div>
{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>
)}
{selectedTextIsSpeaker(selectedText) &&
!selectedParticipant &&
!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)}>
{oneMatch &&

View File

@@ -2,7 +2,6 @@ import { faArrowLeft, faArrowRight } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import useTopics from "../../useTopics";
import { Dispatch, SetStateAction, useEffect } from "react";
import { TranscriptTopic } from "../../../../api/models/TranscriptTopic";
import { GetTranscriptTopic } from "../../../../api";
type TopicHeader = {
@@ -26,17 +25,33 @@ export default function TopicHeader({
}
}, [topics.loading]);
if (topics.topics && currentTopic) {
const number = topics.topics.findIndex(
(topic) => topic.id == currentTopic.id,
);
const canGoPrevious = number > 0;
const total = topics.topics.length;
const canGoNext = total && number < total + 1;
const number = topics.topics?.findIndex(
(topic) => topic.id == currentTopic?.id,
);
const canGoPrevious = typeof number == "number" && number > 0;
const total = topics.topics?.length;
const canGoNext = total && typeof number == "number" && number + 1 < total;
const onPrev = () => setCurrentTopic(topics.topics?.at(number - 1));
const onNext = () => setCurrentTopic(topics.topics?.at(number + 1));
const onPrev = () =>
canGoPrevious && setCurrentTopic(topics.topics?.at(number - 1));
const onNext = () =>
canGoNext && setCurrentTopic(topics.topics?.at(number + 1));
const keyHandler = (e) => {
if (e.key == "ArrowLeft") {
onPrev();
} else if (e.key == "ArrowRight") {
onNext();
}
};
useEffect(() => {
document.addEventListener("keyup", keyHandler);
return () => {
document.removeEventListener("keyup", keyHandler);
};
});
if (topics.topics && currentTopic && typeof number == "number") {
return (
<div className="flex flex-row">
<button

View File

@@ -8,8 +8,23 @@ const TopicPlayer = ({ transcriptId, selectedTime, topicTime }) => {
const [endSelectionCallback, setEndSelectionCallback] =
useState<() => void>();
//TODO shortcuts
// TODO if selection changes while playing, don't play
const keyHandler = (e) => {
if (e.key == "!") {
if (isPlaying) {
mp3.media?.pause();
setIsPlaying(false);
} else {
mp3.media?.play();
setIsPlaying(true);
}
}
};
useEffect(() => {
document.addEventListener("keyup", keyHandler);
return () => {
document.removeEventListener("keyup", keyHandler);
};
});
useEffect(() => {
setEndTopicCallback(
@@ -26,10 +41,17 @@ const TopicPlayer = ({ transcriptId, selectedTime, topicTime }) => {
}
},
);
if (mp3.media) {
mp3.media.currentTime = topicTime.start;
if (mp3.media && topicTime) {
mp3.media?.pause();
// there's no callback on pause but apparently changing the time while palying doesn't work... so here is a timeout
setTimeout(() => {
if (mp3.media) {
mp3.media.currentTime = topicTime.start;
}
}, 10);
setIsPlaying(false);
}
}, [topicTime]);
}, [topicTime, mp3.media]);
useEffect(() => {
endTopicCallback &&
@@ -43,17 +65,9 @@ const TopicPlayer = ({ transcriptId, selectedTime, topicTime }) => {
};
}, [endTopicCallback]);
const setEndTime = (time) => () => {
if (mp3.media && time && mp3.media.currentTime >= time) {
mp3.media.pause();
setIsPlaying(false);
mp3.media.removeEventListener("timeupdate", setEndTime);
}
};
const playSelection = () => {
if (mp3.media && selectedTime?.start !== undefined) {
mp3.media.currentTime = selectedTime?.start;
mp3.media.currentTime = selectedTime.start;
setEndSelectionCallback(
() =>
function () {
@@ -64,8 +78,7 @@ const TopicPlayer = ({ transcriptId, selectedTime, topicTime }) => {
) {
mp3.media.pause();
setIsPlaying(false);
endSelectionCallback &&
removeEventListener("timeupdate", endSelectionCallback);
setEndSelectionCallback(() => {});
}
},
@@ -101,7 +114,7 @@ const TopicPlayer = ({ transcriptId, selectedTime, topicTime }) => {
setIsPlaying(true);
};
const pause = () => {
const pause = (e) => {
mp3.media?.pause();
setIsPlaying(false);
};

View File

@@ -38,9 +38,11 @@ const useParticipants = (transcriptId: string): UseParticipants => {
const [count, setCount] = useState(0);
const refetch = () => {
setCount(count + 1);
setLoading(true);
setErrorState(null);
if (!loading) {
setCount(count + 1);
setLoading(true);
setErrorState(null);
}
};
useEffect(() => {

View File

@@ -42,7 +42,7 @@ const useTopicWithWords = (
): UseTopicWithWords => {
const [response, setResponse] =
useState<GetTranscriptTopicWithWordsPerSpeaker | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [loading, setLoading] = useState<boolean>(false);
const [error, setErrorState] = useState<Error | null>(null);
const { setError } = useError();
const api = getApi();
@@ -50,15 +50,13 @@ const useTopicWithWords = (
const [count, setCount] = useState(0);
const refetch = () => {
setCount(count + 1);
setLoading(true);
setErrorState(null);
if (!loading) {
setCount(count + 1);
setLoading(true);
setErrorState(null);
}
};
useEffect(() => {
setLoading(true);
}, [transcriptId, topicId]);
useEffect(() => {
if (!transcriptId || !topicId || !api) return;