diff --git a/src/config/apiendpoint.js b/src/config/apiendpoint.js index 52d1fff26..bd1c666ee 100644 --- a/src/config/apiendpoint.js +++ b/src/config/apiendpoint.js @@ -16,6 +16,7 @@ const apiendpoint = { authUser:"/users/auth/users/", functions:"/functions/", Glossary:"/v1/", + transliteration_log: "logs/transliteration-log/", }; export default apiendpoint; \ No newline at end of file diff --git a/src/redux/actions/CL-Transcription/GetAnnotationsTask.js b/src/redux/actions/CL-Transcription/GetAnnotationsTask.js index 37bdfadad..b252692bc 100644 --- a/src/redux/actions/CL-Transcription/GetAnnotationsTask.js +++ b/src/redux/actions/CL-Transcription/GetAnnotationsTask.js @@ -7,7 +7,7 @@ export default class GetAnnotationsTaskAPI extends API { constructor(taskId,timeout = 2000) { super("GET", timeout, false); this.type = constants.GET_ANNOTATIONS_TASK; - this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getTasks}${taskId}/annotations/?enable_chitralekha_UI=true`; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getTasks}${taskId}/annotations/?enable_chitralekha_UI=True`; } processResponse(res) { diff --git a/src/redux/actions/api/Annotation/PostTransliterationForLogging.js b/src/redux/actions/api/Annotation/PostTransliterationForLogging.js new file mode 100644 index 000000000..1dbd9e931 --- /dev/null +++ b/src/redux/actions/api/Annotation/PostTransliterationForLogging.js @@ -0,0 +1,47 @@ +import API from "../../../api"; +import ENDPOINTS from "../../../../config/apiendpoint"; +import constants from "../../../constants"; + +export default class PostTransliterationForLogging extends API { + constructor(source_text, target_text, orginal_romanised_text,edited_romanised_text,target_language, timeout = 2000) { + super("POST", timeout, false); + this.transliterationLog = { + source_english_text: source_text, + indic_translation_text: target_text, + romanised_text: orginal_romanised_text, + edited_romanised_text: edited_romanised_text, + language: target_language, + }; + this.type = constants.POST_TRANSLITERATION_LOG; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.transliteration_log}`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.newTransliterationLog = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return this.transliterationLog; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization": `JWT ${localStorage.getItem('shoonya_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.newTransliterationLog; + } +} diff --git a/src/redux/actions/api/LSFAPI/LSFAPI.js b/src/redux/actions/api/LSFAPI/LSFAPI.js index fadef9d6f..29c9fd35b 100644 --- a/src/redux/actions/api/LSFAPI/LSFAPI.js +++ b/src/redux/actions/api/LSFAPI/LSFAPI.js @@ -36,6 +36,29 @@ const fetchAnnotation = async (taskID) => { } }; + +const fetchTransliteration = async (sourceText,tgtLng) => { + const url = `https://xlit-api.ai4bharat.org/rt/${encodeURIComponent(tgtLng)}/${encodeURIComponent(sourceText)}`; + const response = await fetch(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + return { + timestamp: data.at, + error: data.error, + input: data.input, + romanised_transliteration: data.result.join(", "), // Assuming result is always an array; join elements for a single string output + success: data.success + }; +}; + const postAnnotation = async ( result, task, @@ -273,6 +296,7 @@ export { patchAnnotation, deleteAnnotation, fetchAnnotation, + fetchTransliteration, postReview, patchReview, patchSuperChecker, diff --git a/src/redux/actions/apitransport/apitransport.js b/src/redux/actions/apitransport/apitransport.js index c62fc2b4a..5779de2b4 100644 --- a/src/redux/actions/apitransport/apitransport.js +++ b/src/redux/actions/apitransport/apitransport.js @@ -124,14 +124,23 @@ export default function dispatchAPI(api) { }; } return dispatch => { - dispatch(apiStatusAsync(api.dontShowApiLoader() ? false : true, false, "",null, null, true)); - axios - .get(api.apiEndPoint(), api.getHeaders()) - .then(res => { - success(res, api, dispatch); - }) - .catch(err => { - error(err, api, dispatch); - }); + if (api.dontShowApiLoader && typeof api.dontShowApiLoader === 'function') { + dispatch(apiStatusAsync(api.dontShowApiLoader() ? false : true, false, "",null, null, true)); + } + + if (api.apiEndPoint && typeof api.apiEndPoint === 'function' && api.getHeaders && typeof api.getHeaders === 'function') { + axios + .get(api.apiEndPoint(), api.getHeaders()) + .then(res => { + if (success && typeof success === 'function') { + success(res, api, dispatch); + } + }) + .catch(err => { + if (error && typeof error === 'function') { + error(err, api, dispatch); + } + }); + } }; } diff --git a/src/redux/constants.js b/src/redux/constants.js index c1aaae310..d2293df1f 100644 --- a/src/redux/constants.js +++ b/src/redux/constants.js @@ -118,6 +118,7 @@ const constants = { SUBTITLES: "SUBTITLES", PATCH_ANNOTATION:"PATCH_ANNOTATION", UPDATE_UI_PREFS: "UPDATE_UI_PREFS", + POST_TRANSLITERATION_LOG : "POST_TRANSLITERATION_LOG" }; diff --git a/src/ui/Layout.js b/src/ui/Layout.js index fbae1971e..7b7a4d141 100644 --- a/src/ui/Layout.js +++ b/src/ui/Layout.js @@ -94,7 +94,7 @@ const Layout= (props) => { return (
Loading....
}>
{ const classes = AudioTranscriptionLandingStyle(); // const dispatch = useDispatch(); @@ -100,6 +103,27 @@ const SettingsButtonComponent = ({ )} + {showMerge && ( + + + + + + )} { props.type === "review" && row.push( { onChange={handleReviewToggle} /> */} - @@ -668,7 +668,7 @@ const AdvancedOperation = (props) => { ))} - + :null} {((userRole.WorkspaceManager === loggedInUserData?.role || userRole.OrganizationOwner === loggedInUserData?.role || diff --git a/src/ui/pages/component/Tabs/DatasetProjectsTable.jsx b/src/ui/pages/component/Tabs/DatasetProjectsTable.jsx index a4df42d62..f40b0cc97 100644 --- a/src/ui/pages/component/Tabs/DatasetProjectsTable.jsx +++ b/src/ui/pages/component/Tabs/DatasetProjectsTable.jsx @@ -16,6 +16,7 @@ import Search from "../../component/common/Search"; import { Grid, Stack, ThemeProvider } from "@mui/material"; import tableTheme from "../../../theme/tableTheme"; import { width } from "@mui/system"; +import userRole from "../../../../utils/UserMappedByRole/Roles"; const columns = [ { @@ -179,6 +180,9 @@ export default function DatasetProjectsTable({ datasetId }) { }); } }; + const loggedInUserData = useSelector( + (state) => state.fetchLoggedInUserData.data + ); const renderSnackBar = () => { return ( - getExportProjectButton(project)} label="Export" /> + {userRole.Admin === loggedInUserData?.role ? getExportProjectButton(project)} label="Export" />:null} getPullNewDataAPI(project)} label="Pull New Data Items" /> ), diff --git a/src/ui/pages/component/common/Header.jsx b/src/ui/pages/component/common/Header.jsx index 938e94155..5f272b6df 100644 --- a/src/ui/pages/component/common/Header.jsx +++ b/src/ui/pages/component/common/Header.jsx @@ -67,6 +67,9 @@ const Header = () => { const [selectedNotificationId, setSelectedNotificationId] = useState(null); const [showTransliterationModel, setShowTransliterationModel] = useState(false); + + const ProjectDetails = useSelector((state) => state.getProjectDetails.data); + const [snackbar, setSnackbarInfo] = useState({ open: false, message: "", @@ -758,6 +761,17 @@ console.log(unseenNotifications,'uuu'); // onclick: () => {}, // }, ]; + + if (ProjectDetails?.project_type?.includes("ContextualTranslationEditing")) { + appSettings.splice(1, 0, { + name: "Romanised Transliteration", + onclick: () => { + handleCloseSettingsMenu(); + localStorage.setItem("showRomanisedTransliterationModel", "true" ); + }, + }); + } + const helpMenu = [ { name: "Help", diff --git a/src/ui/pages/container/CL-Transcription/AllAudioTranscriptionLandingPage.jsx b/src/ui/pages/container/CL-Transcription/AllAudioTranscriptionLandingPage.jsx index 52cc1db99..8227a1e36 100644 --- a/src/ui/pages/container/CL-Transcription/AllAudioTranscriptionLandingPage.jsx +++ b/src/ui/pages/container/CL-Transcription/AllAudioTranscriptionLandingPage.jsx @@ -41,6 +41,7 @@ import ArrowRightIcon from "@mui/icons-material/ArrowRight"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import getTaskAssignedUsers from '../../../../utils/getTaskAssignedUsers'; import LightTooltip from "../../component/common/Tooltip"; +import configs from '../../../../config/config'; import StandarisedisedTranscriptionEditing from './StandardizedTranscription'; const AllAudioTranscriptionLandingPage = () => { @@ -85,6 +86,7 @@ const AllAudioTranscriptionLandingPage = () => { const [advancedWaveformSettings, setAdvancedWaveformSettings] = useState(false); const [assignedUsers, setAssignedUsers] = useState(null); const [waveSurfer, setWaveSurfer] = useState(true); + const [audioURL, setAudioURL] = useState(""); const handleCollapseClick = () => { !showNotes && setShowStdTranscript(false); @@ -114,11 +116,32 @@ const AllAudioTranscriptionLandingPage = () => { }); } else { setTaskData(resp); - if (resp?.data?.audio_duration < 700){ + if (resp?.data?.audio_duration < 1000){ setWaveSurfer(false); }else{ setWaveSurfer(true); } + const fetchAudioData = await fetch(String(resp?.data?.audio_url).replace("https://asr-transcription.objectstore.e2enetworks.net/", `${configs.BASE_URL_AUTO}/task/get_audio_file/?audio_url=`), { + method: "GET", + headers: ProjectObj.getHeaders().headers + }) + if (!fetchAudioData.ok){ + setAudioURL(resp?.data?.audio_url) + }else{ + try { + var base64data = await fetchAudioData.json(); + var binaryData = atob(base64data); + var buffer = new ArrayBuffer(binaryData.length); + var view = new Uint8Array(buffer); + for (var i = 0; i < binaryData.length; i++) { + view[i] = binaryData.charCodeAt(i); + } + var blob = new Blob([view], { type: 'audio/mpeg' }); + setAudioURL(URL.createObjectURL(blob)); + } catch { + setAudioURL(resp?.data?.audio_url) + } + } } setLoading(false); }; @@ -473,11 +496,14 @@ const AllAudioTranscriptionLandingPage = () => { + {audioURL && + } @@ -728,7 +754,7 @@ const AllAudioTranscriptionLandingPage = () => { position="fixed" bottom={1} > - {waveSurfer ? : } + {audioURL && (waveSurfer ? : )} ); diff --git a/src/ui/pages/container/CL-Transcription/AnnotationTranscription.jsx b/src/ui/pages/container/CL-Transcription/AnnotationTranscription.jsx index e24e5a911..351570100 100644 --- a/src/ui/pages/container/CL-Transcription/AnnotationTranscription.jsx +++ b/src/ui/pages/container/CL-Transcription/AnnotationTranscription.jsx @@ -27,7 +27,7 @@ const AnnotationTranscription = () => { return (
{ProjectDetails?.project_type === "StandardizedTranscriptionEditing" ? ( - + ) : ( )} diff --git a/src/ui/pages/container/CL-Transcription/AudioPanel.jsx b/src/ui/pages/container/CL-Transcription/AudioPanel.jsx index 99f60dc3a..e61dc8c63 100644 --- a/src/ui/pages/container/CL-Transcription/AudioPanel.jsx +++ b/src/ui/pages/container/CL-Transcription/AudioPanel.jsx @@ -15,7 +15,8 @@ import APITransport from "../../../../redux/actions/apitransport/apitransport"; const AudioPanel = memo( ({ setCurrentTime, setPlaying, - taskData + taskData, + audioUrl }) => { const classes = AudioTranscriptionLandingStyle(); const dispatch = useDispatch(); @@ -67,7 +68,7 @@ const AudioPanel = memo( ({ id ="audio-panel" controls controlsList="nodownload" - src={TaskDetails?.data?.audio_url} + src={audioUrl} preload="metadata" type="audio" // style={{ diff --git a/src/ui/pages/container/CL-Transcription/AudioTranscriptionLandingPage.jsx b/src/ui/pages/container/CL-Transcription/AudioTranscriptionLandingPage.jsx index ba322f629..d0425a020 100644 --- a/src/ui/pages/container/CL-Transcription/AudioTranscriptionLandingPage.jsx +++ b/src/ui/pages/container/CL-Transcription/AudioTranscriptionLandingPage.jsx @@ -48,8 +48,13 @@ import ArrowRightIcon from "@mui/icons-material/ArrowRight"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import getTaskAssignedUsers from '../../../../utils/getTaskAssignedUsers'; import LightTooltip from "../../component/common/Tooltip"; +import configs from '../../../../config/config'; +import { Tab, Tabs } from "@mui/material"; +import FormControl from "@mui/material/FormControl"; +import StandarisedisedTranscriptionEditing from './StandardizedTranscription'; -const AudioTranscriptionLandingPage = () => { + +const AudioTranscriptionLandingPage = ({project_type}) => { const classes = AudioTranscriptionLandingStyle(); const dispatch = useDispatch(); const navigate = useNavigate(); @@ -89,6 +94,7 @@ const AudioTranscriptionLandingPage = () => { const [annotationtext, setannotationtext] = useState('') const [reviewtext, setreviewtext] = useState('') const [taskData, setTaskData] = useState() + const [updatedProjectData, setUpdatedProjectData] = useState([]); const [snackbar, setSnackbarInfo] = useState({ open: false, message: "", @@ -112,6 +118,7 @@ const AudioTranscriptionLandingPage = () => { const [autoSave, setAutoSave] = useState(true); const [waveSurfer, setWaveSurfer] = useState(true); const [autoSaveTrigger, setAutoSaveTrigger] = useState(false); + const [audioURL, setAudioURL] = useState(""); // useEffect(() => { // let intervalId; @@ -137,6 +144,11 @@ const AudioTranscriptionLandingPage = () => { // }; // }, []); + const [tabValue, setTabValue] = useState(0); + const handleTabChange = (e, v) => { + e.preventDefault() + setTabValue(v); + } const filterAnnotations = (annotations, user) => { let disableSkip = false; let disableUpdate = false; @@ -288,11 +300,32 @@ const AudioTranscriptionLandingPage = () => { }); } else { setTaskData(resp); - if (resp?.data?.audio_duration < 700){ + if (resp?.data?.audio_duration < 1000){ setWaveSurfer(false); }else{ setWaveSurfer(true); } + const fetchAudioData = await fetch(String(resp?.data?.audio_url).replace("https://asr-transcription.objectstore.e2enetworks.net/", `${configs.BASE_URL_AUTO}/task/get_audio_file/?audio_url=`), { + method: "GET", + headers: ProjectObj.getHeaders().headers + }) + if (!fetchAudioData.ok){ + setAudioURL(resp?.data?.audio_url) + }else{ + try { + var base64data = await fetchAudioData.json(); + var binaryData = atob(base64data); + var buffer = new ArrayBuffer(binaryData.length); + var view = new Uint8Array(buffer); + for (var i = 0; i < binaryData.length; i++) { + view[i] = binaryData.charCodeAt(i); + } + var blob = new Blob([view], { type: 'audio/mpeg' }); + setAudioURL(URL.createObjectURL(blob)); + } catch { + setAudioURL(resp?.data?.audio_url) + } + } } setLoading(false); }; @@ -823,6 +856,7 @@ const [waveSurferWaveformSettings, setWaveSurferWaveformSettings] = useState({ "barHeight": waveSurferBarHeight }); + useEffect(() => { setWaveSurferWaveformSettings({ "height": waveSurferHeight, @@ -927,6 +961,7 @@ useEffect(() => { filterMessage={filterMessage} taskData={taskData} /> + {audioURL && { onNextAnnotation={onNextAnnotation} AnnotationsTaskDetails={AnnotationsTaskDetails} taskData={taskData} - /> + audioUrl={audioURL} + />} @@ -1187,7 +1223,39 @@ useEffect(() => { - + + + + {ProjectDetails?.metadata_json?.acoustic_enabled_stage <=1 && + + } + + + + } + + {ProjectDetails && ProjectDetails?.project_type==="StandardizedTranscriptionEditing" ? + + : + { setWaveSurfer={setWaveSurfer} annotationId={annotations[0]?.id} /> + } + @@ -1210,7 +1280,7 @@ useEffect(() => { bottom={1} // style={fullscreen ? { visibility: "hidden" } : {}} > - {waveSurfer ? : } + {audioURL && (waveSurfer ? : )} ); diff --git a/src/ui/pages/container/CL-Transcription/ReviewAudioTranscriptionLandingPage.jsx b/src/ui/pages/container/CL-Transcription/ReviewAudioTranscriptionLandingPage.jsx index 8c8d072c7..7bbd9f9db 100644 --- a/src/ui/pages/container/CL-Transcription/ReviewAudioTranscriptionLandingPage.jsx +++ b/src/ui/pages/container/CL-Transcription/ReviewAudioTranscriptionLandingPage.jsx @@ -49,11 +49,11 @@ import ArrowRightIcon from "@mui/icons-material/ArrowRight"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import getTaskAssignedUsers from '../../../../utils/getTaskAssignedUsers'; import LightTooltip from "../../component/common/Tooltip" +import configs from '../../../../config/config'; import StandarisedisedTranscriptionEditing from './StandardizedTranscription'; import { Tab, Tabs } from "@mui/material"; import FormControl from "@mui/material/FormControl"; - const ReviewAudioTranscriptionLandingPage = () => { const classes = AudioTranscriptionLandingStyle(); const dispatch = useDispatch(); @@ -90,9 +90,12 @@ const ReviewAudioTranscriptionLandingPage = () => { targetlang: "en", fontSize: "Normal" }); + const [updatedProjectData, setUpdatedProjectData] = useState([]); const [anchorEl, setAnchorEl] = useState(null); const [speakerBox, setSpeakerBox] = useState(""); const[taskDetailList,setTaskDetailList] = useState() + + const [snackbar, setSnackbarInfo] = useState({ open: false, message: "", @@ -120,6 +123,8 @@ const ReviewAudioTranscriptionLandingPage = () => { const [autoSave, setAutoSave] = useState(true); const [waveSurfer, setWaveSurfer] = useState(true); const [autoSaveTrigger, setAutoSaveTrigger] = useState(false); + const [audioURL, setAudioURL] = useState(""); + // useEffect(() => { // let intervalId; @@ -313,11 +318,33 @@ const ReviewAudioTranscriptionLandingPage = () => { variant: "error", }); }else{setTaskDetailList(resp); - if (resp?.data?.audio_duration < 700){ + if (resp?.data?.audio_duration < 1000){ setWaveSurfer(false); }else{ setWaveSurfer(true); - }} + } + const fetchAudioData = await fetch(String(resp?.data?.audio_url).replace("https://asr-transcription.objectstore.e2enetworks.net/", `${configs.BASE_URL_AUTO}/task/get_audio_file/?audio_url=`), { + method: "GET", + headers: ProjectObj.getHeaders().headers + }) + if (!fetchAudioData.ok){ + setAudioURL(resp?.data?.audio_url) + }else{ + try { + var base64data = await fetchAudioData.json(); + var binaryData = atob(base64data); + var buffer = new ArrayBuffer(binaryData.length); + var view = new Uint8Array(buffer); + for (var i = 0; i < binaryData.length; i++) { + view[i] = binaryData.charCodeAt(i); + } + var blob = new Blob([view], { type: 'audio/mpeg' }); + setAudioURL(URL.createObjectURL(blob)); + } catch { + setAudioURL(resp?.data?.audio_url) + } + } + } setLoading(false); }; @@ -1134,13 +1161,16 @@ useEffect(() => { disableButton={disableButton} anchorEl={anchorEl} setAnchorEl={setAnchorEl} /> + {audioURL && + } @@ -1418,15 +1448,20 @@ useEffect(() => { + {ProjectDetails && ProjectDetails?.project_type==="StandardizedTranscriptionEditing" && + {ProjectDetails?.metadata_json?.acoustic_enabled_stage <=2 && + } - - + + } + {ProjectDetails && ProjectDetails?.project_type==="StandardizedTranscriptionEditing" ? + { waveSurfer={waveSurfer} setWaveSurfer={setWaveSurfer} annotationId={annotations[0]?.id} + updatedProjectData={updatedProjectData} + setUpdatedProjectData={setUpdatedProjectData} /> + : + + } @@ -1450,7 +1503,7 @@ useEffect(() => { bottom={1} // style={fullscreen ? { visibility: "hidden" } : {}} > - {waveSurfer ? : } + {audioURL && (waveSurfer ? : )} ); diff --git a/src/ui/pages/container/CL-Transcription/ReviewerSupercheckerTranscription.jsx b/src/ui/pages/container/CL-Transcription/ReviewerSupercheckerTranscription.jsx new file mode 100644 index 000000000..aa6caf841 --- /dev/null +++ b/src/ui/pages/container/CL-Transcription/ReviewerSupercheckerTranscription.jsx @@ -0,0 +1,42 @@ +import ReviewLSF from "../Label-Studio/ReviewLSF"; +import ReviewAudioTranscriptionLandingPage from "./ReviewAudioTranscriptionLandingPage"; +import { useSelector } from "react-redux"; +import { useEffect } from "react"; +import { useParams } from "react-router-dom"; +import GetProjectDetailsAPI from "../../../../redux/actions/api/ProjectDetails/GetProjectDetails"; +import APITransport from "../../../../redux/actions/apitransport/apitransport"; +import { useDispatch } from "react-redux"; +import SuperCheckerLSF from "../Label-Studio/SuperCheckerLSF"; +import SuperCheckerAudioTranscriptionLandingPage from "./SuperCheckerAudioTranscriptionLandingPage"; + +const ReviewerSupercheckerTranscription = () => { + const ProjectDetails = useSelector((state) => state.getProjectDetails?.data); + const { projectId, taskId } = useParams(); + const dispatch = useDispatch(); + + const getProjectDetails = () => { + const projectObj = new GetProjectDetailsAPI(projectId); + dispatch(APITransport(projectObj)); + }; + useEffect(() => { + getProjectDetails(); + }, [projectId, taskId]); + + return ( +
+ {ProjectDetails?.project_type === "StandardizedTranscriptionEditing" ? ( + ProjectDetails?.project_stage === 2 ? ( + + ) : ProjectDetails?.project_stage === 3 ? ( + + ) : ( + + ) + ) : ( + + )} +
+ ); +}; + +export default ReviewerSupercheckerTranscription; diff --git a/src/ui/pages/container/CL-Transcription/StandardizedTranscription.jsx b/src/ui/pages/container/CL-Transcription/StandardizedTranscription.jsx index b66dee38a..644343e62 100644 --- a/src/ui/pages/container/CL-Transcription/StandardizedTranscription.jsx +++ b/src/ui/pages/container/CL-Transcription/StandardizedTranscription.jsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect, useState, useRef, memo } from "react"; import { IndicTransliterate } from "@ai4bharat/indic-transliterate"; import { useDispatch, useSelector } from "react-redux"; -import { useNavigate, useParams } from "react-router-dom"; +import { useLoaderData, useNavigate, useParams } from "react-router-dom"; import { Resizable } from 're-resizable'; import { addSubtitleBox, @@ -85,6 +85,8 @@ const StandarisedisedTranscriptionEditing = ({ waveSurfer, setWaveSurfer, annotationId, + updatedProjectData, + setUpdatedProjectData }) => { const { taskId } = useParams(); const classes = AudioTranscriptionLandingStyle(); @@ -96,6 +98,8 @@ const StandarisedisedTranscriptionEditing = ({ const assignedOrgId = JSON.parse(localStorage.getItem("userData")) ?.organization?.id; const subtitles = useSelector((state) => state.commonReducer.subtitles); + console.log(subtitles); + console.log(subtitles); const player = useSelector((state) => state.commonReducer.player); const currentPage = useSelector((state) => state.commonReducer.currentPage); @@ -112,9 +116,10 @@ const StandarisedisedTranscriptionEditing = ({ const startIndex = (page - 1) * itemsPerPage; const endIndex = startIndex + itemsPerPage; const currentPageData = subtitles; + console.log(currentPageData) // const currentPageData = subtitles?.slice(startIndex, endIndex); const idxOffset = (itemsPerPage * (page - 1)); - const showAcousticText = ProjectDetails?.project_type === "AcousticNormalisedTranscriptionEditing" && ProjectDetails?.metadata_json?.acoustic_enabled_stage <= stage; + const showAcousticText = ProjectDetails?.project_type === "StandardizedTranscriptionEditing" && ProjectDetails?.metadata_json?.acoustic_enabled_stage <= stage; const [snackbar, setSnackbarInfo] = useState({ open: false, message: "", @@ -154,6 +159,7 @@ const StandarisedisedTranscriptionEditing = ({ const textRefs = useRef([]); const [currentTextRefIdx, setCurrentTextRefIdx] = useState(null); const [currentSelection, setCurrentSelection] = useState(null); + const [selectedSpeaker, setSelectedSpeaker] = useState(speakerIdList?.[0]?.name); useEffect(() => { currentPageData?.length && (textRefs.current = textRefs.current.slice(0, (showAcousticText ? 2 : 1) * currentPageData.length)); @@ -257,9 +263,13 @@ const StandarisedisedTranscriptionEditing = ({ const onMergeClick = useCallback( (index) => { - const selectionStart = getSelectionStart(index); - const timings = getTimings(index); - + console.log(stage); + console.log(updatedProjectData); + const selectionStart = getSelectionStart(index, stage, updatedProjectData); + console.log("selectionstart: "+selectionStart) + const timings = getTimings(index, stage, updatedProjectData); + console.log("timings: "+timings) + setUndoStack((prevState) => [ ...prevState, { @@ -267,17 +277,28 @@ const StandarisedisedTranscriptionEditing = ({ index: index, timings, selectionStart, + stage: stage, + updatedProjectData: updatedProjectData }, ]); setRedoStack([]); - - const sub = onMerge(index); - dispatch(setSubtitles(sub, C.SUBTITLES)); + + const sub = onMerge(index, stage, updatedProjectData); + console.log(sub); + if(stage==3){ + const updatedData = [...updatedProjectData]; + updatedData.splice(index, 2, sub[index]) + setUpdatedProjectData(updatedData) + } + else{ + dispatch(setSubtitles(sub, C.SUBTITLES)); + } + // saveTranscriptHandler(false, true, sub); }, - // eslint-disable-next-line - [limit, currentOffset] + [limit, currentOffset, stage, updatedProjectData] ); + const onMouseUp = (e, blockIdx) => { if (e.target.selectionStart < e.target.value?.length) { @@ -289,23 +310,66 @@ const StandarisedisedTranscriptionEditing = ({ }; const onSplitClick = useCallback(() => { - setUndoStack((prevState) => [ - ...prevState, - { - type: "split", - index: currentIndexToSplitTextBlock, - selectionStart, - }, - ]); + console.log(stage); + console.log(updatedProjectData); + + const newSubtitles = onSplit(currentIndexToSplitTextBlock, selectionStart, stage, updatedProjectData); + + if (newSubtitles.length > updatedProjectData.length) { + if (stage === 3) { + const updatedData = [...updatedProjectData]; + updatedData[currentIndexToSplitTextBlock] = newSubtitles[currentIndexToSplitTextBlock]; + updatedData.splice(currentIndexToSplitTextBlock + 1, 0, newSubtitles[currentIndexToSplitTextBlock + 1]); + console.log(updatedData); // Log updated data to confirm changes + + + // Update the undo stack within the state setter + setUndoStack((prevState) => [ + ...prevState, + { + type: "split", + index: currentIndexToSplitTextBlock, + selectionStart, + stage: stage, + updatedProjectData: updatedData, + }, + ]); + setUpdatedProjectData(updatedData); + // dispatch(setSubtitles(updatedData, C.SUBTITLES)); + + } else { + dispatch(setSubtitles(newSubtitles, C.SUBTITLES)); + setUndoStack((prevState) => [ + ...prevState, + { + type: "split", + index: currentIndexToSplitTextBlock, + selectionStart, + stage: stage, + // updatedProjectData: newSubtitles, + }, + ]); + } + } else { + setSnackbarInfo({ + open: true, + message: "The split duration is too less", + variant: "info", + }); + } + setRedoStack([]); - const sub = onSplit(currentIndexToSplitTextBlock, selectionStart); - dispatch(setSubtitles(sub, C.SUBTITLES)); - // saveTranscriptHandler(false, true, sub); - + // eslint-disable-next-line }, [currentIndexToSplitTextBlock, selectionStart, limit, currentOffset]); + + useEffect(() => { + console.log(updatedProjectData); // This should show the updated length + }, [updatedProjectData]); + - const changeTranscriptHandler = (event, index, updateAcoustic = false) => { + + const changeTranscriptHandler = (event, index, updateAcoustic) => { const { target: { value }, currentTarget, @@ -334,8 +398,18 @@ const StandarisedisedTranscriptionEditing = ({ setCurrentSelection(event.target.selectionEnd); setTagSuggestionsAcoustic(updateAcoustic); } - const sub = onSubtitleChange(value, index, updateAcoustic, false); - dispatch(setSubtitles(sub, C.SUBTITLES)); + const sub = onSubtitleChange(value, index, updateAcoustic, false, stage, updatedProjectData); + if(stage === 3){ + const updatedData = [...updatedProjectData]; + console.log(updatedData); + console.log(index); + console.log(value); + updatedData[index].acoustic_standardized_text = sub[index].acoustic_standardized_text + setUpdatedProjectData(updatedData) + } + else{ + dispatch(setSubtitles(sub, C.SUBTITLES)); + } // saveTranscriptHandler(false, false, sub); }; @@ -407,42 +481,80 @@ const StandarisedisedTranscriptionEditing = ({ const onDelete = useCallback( (index) => { - setUndoStack((prevState) => [ - ...prevState, - { - type: "delete", - index: index, - data: getItemForDelete(index), - }, - ]); - setRedoStack([]); + console.log("index: "+ index); + console.log("stage: " + stage) + console.log("updatedprojdatad: "+updatedProjectData) + const data = getItemForDelete(index, stage, updatedProjectData); + + const sub = onSubtitleDelete(index, stage, updatedProjectData) + + console.log(sub); + + if (stage === 3) { + setUndoStack((prevState) => [ + ...prevState, + { + type: "delete", + index: index, + data: data, + stage: stage, + updatedProjectData: sub, + }, + ]); + setRedoStack([]); + setUpdatedProjectData(sub); + console.log(updatedProjectData) + } + else{ + setUndoStack((prevState) => [ + ...prevState, + { + type: "delete", + index: index, + data: data, + // stage: stage, + // updatedProjectData: updatedProjectData, + }, + ]); + setRedoStack([]); + dispatch(setSubtitles(sub, C.SUBTITLES)); + } - const sub = onSubtitleDelete(index); - dispatch(setSubtitles(sub, C.SUBTITLES)); + // saveTranscriptHandler(false, false, sub); }, // eslint-disable-next-line - [limit, currentOffset] + [limit, currentOffset, stage, updatedProjectData, dispatch, setUpdatedProjectData, setUndoStack, setRedoStack] ); const addNewSubtitleBox = useCallback( (index) => { - const sub = addSubtitleBox(index); - dispatch(setSubtitles(sub, C.SUBTITLES)); - // saveTranscriptHandler(false, false, sub); - + const sub = addSubtitleBox(index, stage, updatedProjectData); + + if (stage === 3) { + const updatedData = [...updatedProjectData]; + updatedData.splice(index + 1, 0, sub[index + 1]); + setUpdatedProjectData(updatedData); + } else { + dispatch(setSubtitles(sub, C.SUBTITLES)); + } + + // Add to undo stack setUndoStack((prevState) => [ ...prevState, { type: "add", index: index, + stage:stage, + updatedProjectData: updatedProjectData, }, ]); + + // Clear redo stack setRedoStack([]); }, - // eslint-disable-next-line - [limit, currentOffset] - ); + [stage, updatedProjectData, dispatch, setUpdatedProjectData, setUndoStack, setRedoStack] + ); const onUndo = useCallback(() => { if (undoStack?.length > 0) { @@ -451,7 +563,14 @@ const StandarisedisedTranscriptionEditing = ({ // modifing subtitles based on last action const sub = onUndoAction(lastAction); - dispatch(setSubtitles(sub, C.SUBTITLES)); + console.log("after undo is performed" + sub); + if(stage===3){ + setUpdatedProjectData(sub); + } + else{ + dispatch(setSubtitles(sub, C.SUBTITLES)); + } + //removing the last action from undo and putting in redo stack setUndoStack(undoStack.slice(0, undoStack?.length - 1)); @@ -468,7 +587,13 @@ const StandarisedisedTranscriptionEditing = ({ // modifing subtitles based on last action const sub = onRedoAction(lastAction); - dispatch(setSubtitles(sub, C.SUBTITLES)); + console.log("after redo stack: "+ sub); + if(stage === 3){ + setUpdatedProjectData(sub); + } + else{ + dispatch(setSubtitles(sub, C.SUBTITLES)); + } //removing the last action from redo and putting in undo stack setRedoStack(redoStack.slice(0, redoStack?.length - 1)); @@ -489,8 +614,14 @@ const StandarisedisedTranscriptionEditing = ({ }; const handleSpeakerChange = (id, index) => { - const sub = assignSpeakerId(id, index); - dispatch(setSubtitles(sub, C.SUBTITLES)); + const sub = assignSpeakerId(id, index, stage, updatedProjectData); + console.log(sub); + if(stage===3){ + setUpdatedProjectData(sub) + }else{ + dispatch(setSubtitles(sub, C.SUBTITLES)); + } + // saveTranscriptHandler(false, false, sub); }; @@ -536,28 +667,45 @@ const StandarisedisedTranscriptionEditing = ({ return () => clearTimeout(timer); }, []); -if(currentPageData) +useEffect(() => { + if (currentPageData?.length && stage===3 ) { + setUpdatedProjectData([{ + start_time: currentPageData[0].start_time, + end_time: currentPageData[currentPageData.length - 1].end_time, + text: currentPageData[0].text, + acoustic_standardized_text: currentPageData[0].acoustic_standardized_text? currentPageData[0].acoustic_standardized_text : currentPageData[0].acoustic_normalised_text, + + }]); + } + else { - console.log("currentPageData", currentPageData) + setUpdatedProjectData(currentPageData); } +}, [currentPageData, stage]); // add dependencies +console.log(updatedProjectData) + +const onMergeClickL3 = useCallback(()=>{ + // merge the transcription L2 into L3 + if (currentPageData?.length && stage===3) { + console.log(currentPageData); + console.log(stage) + console.log(updatedProjectData) + setUpdatedProjectData([{ + start_time: currentPageData[0].start_time, + end_time: currentPageData[currentPageData.length - 1].end_time, + text: currentPageData[0].text, + acoustic_standardized_text: currentPageData[0].acoustic_standardized_text? currentPageData[0].acoustic_standardized_text : currentPageData.map((item) => item.acoustic_normalised_text).join(' ') + + }]); + + console.log(updatedProjectData); + } +}, [currentPageData, stage, updatedProjectData]); -let updatedProjectData = [] -if (currentPageData?.length && stage===3) { - updatedProjectData = [{ - start_time: currentPageData[0].start_time, - end_time: currentPageData[currentPageData.length - 1].end_time, - text: currentPageData.map((item) => item.text) - }] -} -else -{ - updatedProjectData = currentPageData; -} - if(currentPageData) - { - console.log("updatedPageData", updatedProjectData) - } - +useEffect(() => { + setSelectedSpeaker(speakerIdList?.[0]?.name); +}, [stage]); + console.log("stage : " + stage); return ( <> {" "} @@ -570,7 +718,7 @@ else > - {showAcousticText && - {updatedProjectData?.map((item, index) => { + {stage!==3 && updatedProjectData?.map((item, index) => { return ( handleSpeakerChange(event.target.value, index + idxOffset) } @@ -774,9 +925,12 @@ else onClick={() => { if (pauseOnType && player) { player.pause(); - if (player.currentTime < item.startTime || player.currentTime > item.endTime) { - player.currentTime = item.startTime + 0.001; - } + // if (player.currentTime >= item.startTime || player.currentTime <= item.endTime) { + // player.currentTime = player.currentTime + // } + // else{ + // player.currentTime = item.startTime + 0.001; + // } } }} > @@ -786,7 +940,7 @@ else lang={targetlang} value={item.text} onChange={(event) => { - changeTranscriptHandler(event, index + idxOffset, false); + changeTranscriptHandler(event, index + idxOffset, 0); }} enabled={enableTransliterationSuggestion} onChangeText={() => { }} @@ -828,7 +982,7 @@ else // ref={el => textRefs.current[index] = el} // onChange={(event) => { onInput={(event) => { - changeTranscriptHandler(event, index + idxOffset, false); + changeTranscriptHandler(event, index + idxOffset, 0); }} onMouseUp={(e) => onMouseUp(e, index + idxOffset)} value={item.text} @@ -848,14 +1002,14 @@ else */}
)} - {showAcousticText && + {stage==2 && (ProjectDetails?.tgt_language !== "en" && enableTransliteration ? ( { - changeTranscriptHandler(event, index + idxOffset, true); + changeTranscriptHandler(event, index + idxOffset, 1); }} enabled={enableTransliterationSuggestion} onChangeText={() => { }} @@ -881,7 +1035,7 @@ else