초기 커밋: DefVideo 소스 등록
abcVideo 플레이어 소스 (client / server / shared / pythonsource / docs / .claude). .gitignore 적용으로 node_modules·storage·samplevideo·미디어 등 대용량 일괄 제외. 103 files, ~964K. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
61
client/src/hooks/useAnnotations.ts
Normal file
61
client/src/hooks/useAnnotations.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { useEffect, useCallback } from 'react';
|
||||
import { useAnnotationStore } from '../store/annotationStore';
|
||||
import type { Annotation, CreateAnnotationInput, UpdateAnnotationInput } from '@abcvideo/shared';
|
||||
|
||||
export function useAnnotations(videoId: string | null) {
|
||||
const { annotations, setAnnotations, addAnnotation, updateAnnotation, removeAnnotation } =
|
||||
useAnnotationStore();
|
||||
|
||||
useEffect(() => {
|
||||
if (!videoId) { setAnnotations([]); return; }
|
||||
fetch(`/api/annotations/${videoId}`)
|
||||
.then((r) => r.json())
|
||||
.then((data: Annotation[]) => setAnnotations(data))
|
||||
.catch(console.error);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [videoId]);
|
||||
|
||||
const create = useCallback(
|
||||
async (input: Omit<CreateAnnotationInput, 'videoId'>) => {
|
||||
if (!videoId) return;
|
||||
const res = await fetch(`/api/annotations/${videoId}`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ ...input, videoId }),
|
||||
});
|
||||
const annotation: Annotation = await res.json();
|
||||
addAnnotation(annotation);
|
||||
return annotation;
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[videoId]
|
||||
);
|
||||
|
||||
const update = useCallback(
|
||||
async (id: string, input: UpdateAnnotationInput) => {
|
||||
if (!videoId) return;
|
||||
const res = await fetch(`/api/annotations/${videoId}/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
const annotation: Annotation = await res.json();
|
||||
updateAnnotation(id, annotation);
|
||||
return annotation;
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[videoId]
|
||||
);
|
||||
|
||||
const remove = useCallback(
|
||||
async (id: string) => {
|
||||
if (!videoId) return;
|
||||
await fetch(`/api/annotations/${videoId}/${id}`, { method: 'DELETE' });
|
||||
removeAnnotation(id);
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[videoId]
|
||||
);
|
||||
|
||||
return { annotations, create, update, remove };
|
||||
}
|
||||
Reference in New Issue
Block a user