mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
prevent double action
This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -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,13 +210,15 @@ const ParticipantList = ({
|
||||
.then(() => {
|
||||
participants.refetch();
|
||||
setParticipantInput("");
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const deleteParticipant = (participantId) => (e) => {
|
||||
e.stopPropagation();
|
||||
if (!loading) {
|
||||
if (loading || participants.loading || topicWithWords.loading) return;
|
||||
setLoading(true);
|
||||
api
|
||||
?.v1TranscriptDeleteParticipant({
|
||||
transcriptId,
|
||||
@@ -217,17 +226,18 @@ const ParticipantList = ({
|
||||
})
|
||||
.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 && (
|
||||
{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,7 +321,9 @@ const ParticipantList = ({
|
||||
<span>{participant.name}</span>
|
||||
|
||||
<div>
|
||||
{selectedTextIsSpeaker(selectedText) && !loading && (
|
||||
{selectedTextIsSpeaker(selectedText) &&
|
||||
!selectedParticipant &&
|
||||
!loading && (
|
||||
<button onClick={mergeSpeaker(selectedText, participant)}>
|
||||
{oneMatch &&
|
||||
action == "Create to rename" &&
|
||||
|
||||
@@ -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 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 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
|
||||
|
||||
@@ -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 && 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;
|
||||
}
|
||||
}, [topicTime]);
|
||||
}, 10);
|
||||
setIsPlaying(false);
|
||||
}
|
||||
}, [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);
|
||||
};
|
||||
|
||||
@@ -38,9 +38,11 @@ const useParticipants = (transcriptId: string): UseParticipants => {
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
const refetch = () => {
|
||||
if (!loading) {
|
||||
setCount(count + 1);
|
||||
setLoading(true);
|
||||
setErrorState(null);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -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 = () => {
|
||||
if (!loading) {
|
||||
setCount(count + 1);
|
||||
setLoading(true);
|
||||
setErrorState(null);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
}, [transcriptId, topicId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!transcriptId || !topicId || !api) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user