Skip to content

Commit

Permalink
fix sync annotation bug
Browse files Browse the repository at this point in the history
  • Loading branch information
hxhxhx88 committed Mar 26, 2024
1 parent aa36519 commit bfc1e89
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 45 deletions.
32 changes: 12 additions & 20 deletions app/frontend/src/page/annotate/Panel/Load.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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<string | undefined>(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 (
<PageLayout loading={isFetchingAnno || isFetchingVideo}>
<PageLayout loading={isFetchingVideo}>
{errorCode && <Alert showIcon={true} type="error" message={intl.get(errorCode)} />}
</PageLayout>
);
}

return <PanelLoadProject video={getVideoData.video} />;
return <PanelLoadProject video={videoData.video} />;
};
31 changes: 6 additions & 25 deletions app/frontend/src/state/server/annotation.ts
Original file line number Diff line number Diff line change
@@ -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';

/**
Expand All @@ -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<string>(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 {
Expand Down

0 comments on commit bfc1e89

Please sign in to comment.