diff --git a/app/frontend/src/page/annotate/Panel/Load.tsx b/app/frontend/src/page/annotate/Panel/Load.tsx index 0e55bed..cd4db08 100644 --- a/app/frontend/src/page/annotate/Panel/Load.tsx +++ b/app/frontend/src/page/annotate/Panel/Load.tsx @@ -3,13 +3,12 @@ import intl from 'react-intl-universal'; import {Alert} from 'antd'; import {useStore as useRenderStore} from 'state/annotate/render'; import {useAnnoStore} from 'state/annotate/annotation-provider'; -import {useGetVideoAnnotationYjs} from 'state/server/annotation'; import {useGetVideo} from 'state/server/video'; import {NutshClientContext} from 'common/context'; import PageLayout from 'page/Layout'; -import {mustDecodeJsonStr as mustDecodeAnnotationJsonStr} from 'type/annotation'; import type {Video} from 'openapi/nutsh'; import {PanelLoadProject} from './LoadProject'; +import {useJoinYjs} from '@@frontend/state/server/annotation'; export const PanelLoad: FC<{id: Video['id']}> = ({id}) => { const client = useContext(NutshClientContext); @@ -20,41 +19,34 @@ export const PanelLoad: FC<{id: Video['id']}> = ({id}) => { const setAnnotation = useAnnoStore(s => s.setAnnotation); // server state - const {isFetching: isFetchingVideo, data: getVideoData} = useGetVideo(client, id); - const {isFetching: isFetchingAnno, data: getVideoAnnotationData} = useGetVideoAnnotationYjs(id); + const {isFetching: isFetchingVideo, data: videoData} = useGetVideo(client, id); + + // yjs + useJoinYjs(id); // local state const [errorCode, setErrorCode] = useState(undefined); useEffect(() => { - if (!getVideoAnnotationData) return; - if (!getVideoData) return; + if (!videoData) return; setErrorCode(undefined); - const {annotation_json: annoJson, annotation_version: annoVersion} = getVideoAnnotationData; - const {frame_urls: frameUrls} = getVideoData.video; + const {frame_urls: frameUrls} = videoData.video; if (!frameUrls || frameUrls.length === 0) { setErrorCode('error.missing_video_frames'); return; } - try { - const annotation = annoJson ? mustDecodeAnnotationJsonStr(annoJson) : undefined; - setAnnotation(annotation); - startAnnotation(frameUrls, annoVersion); - } catch (e) { - console.error((e as Error).cause); - setErrorCode('error.invalid_annotation_json'); - } - }, [getVideoData, getVideoAnnotationData, setAnnotation, startAnnotation]); + startAnnotation(frameUrls, ''); + }, [videoData, setAnnotation, startAnnotation]); - if (!isLoaded || !getVideoData) { + if (!isLoaded || !videoData) { return ( - + {errorCode && } ); } - return ; + return ; }; diff --git a/app/frontend/src/state/server/annotation.ts b/app/frontend/src/state/server/annotation.ts index aee60f1..a8d3aac 100644 --- a/app/frontend/src/state/server/annotation.ts +++ b/app/frontend/src/state/server/annotation.ts @@ -1,7 +1,7 @@ import {useQuery, useMutation} from '@tanstack/react-query'; import {useYjsContext} from 'common/yjs/context'; -import {readAnnotationFromYjs} from 'common/yjs/convert'; import type {NutshClient, DefaultService, Video} from 'openapi/nutsh'; +import {useEffect} from 'react'; import {WebsocketProvider} from 'y-websocket'; /** @@ -23,31 +23,12 @@ export const usePatchVideoAnnotation = (client: NutshClient) => { }); }; -export const useGetVideoAnnotationYjs = (id: Video['id']) => { +export const useJoinYjs = (id: Video['id']) => { const {doc} = useYjsContext(); - return useQuery({ - queryKey: ['getVideoAnnotationV2', id], - queryFn: async () => { - // connect to the yjs server - const origin = wsOrigin(); - const provider = new WebsocketProvider(origin, `ws/video/${id}`, doc); - - // reconstruct the initial annotation - const annoJson = await new Promise(resolve => { - provider.on('sync', async (isSynced: boolean) => { - if (!isSynced) { - return; - } - const anno = readAnnotationFromYjs(doc); - - // stringify for backward-compatibility - resolve(JSON.stringify(anno)); - }); - }); - - return {annotation_json: annoJson, annotation_version: ''}; - }, - }); + useEffect(() => { + const origin = wsOrigin(); + new WebsocketProvider(origin, `ws/video/${id}`, doc); + }, [doc, id]); }; function wsOrigin(): string {