75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
import { useEditorStore } from './store';
|
|
import type { Annotation } from '../../lib/annotations/types';
|
|
|
|
export function useAutosave() {
|
|
const { documentId, annotations, setSaveStatus, setAnnotations } = useEditorStore();
|
|
const timeoutRef = useRef<number | null>(null);
|
|
const isFirstLoad = useRef(true);
|
|
|
|
// Initial load
|
|
useEffect(() => {
|
|
if (!documentId) return;
|
|
|
|
let active = true;
|
|
|
|
async function load() {
|
|
try {
|
|
const res = await fetch(`/api/v1/documents/${documentId}/annotations`);
|
|
if (!res.ok) throw new Error('Failed to load annotations');
|
|
const data = await res.json();
|
|
|
|
if (active) {
|
|
setAnnotations(data.data as Annotation[]);
|
|
setSaveStatus('saved');
|
|
isFirstLoad.current = false;
|
|
}
|
|
} catch (err) {
|
|
console.error('Error loading annotations:', err);
|
|
if (active) setSaveStatus('error');
|
|
}
|
|
}
|
|
|
|
load();
|
|
|
|
return () => { active = false; };
|
|
}, [documentId, setAnnotations, setSaveStatus]);
|
|
|
|
// Debounced save
|
|
useEffect(() => {
|
|
// Don't save on the initial load!
|
|
if (isFirstLoad.current) return;
|
|
if (!documentId) return;
|
|
|
|
setSaveStatus('saving');
|
|
|
|
if (timeoutRef.current) {
|
|
window.clearTimeout(timeoutRef.current);
|
|
}
|
|
|
|
timeoutRef.current = window.setTimeout(async () => {
|
|
try {
|
|
const res = await fetch(`/api/v1/documents/${documentId}/annotations`, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: JSON.stringify({
|
|
data: annotations
|
|
})
|
|
});
|
|
|
|
if (!res.ok) throw new Error('Failed to save');
|
|
setSaveStatus('saved');
|
|
} catch (err) {
|
|
console.error('Error saving annotations:', err);
|
|
setSaveStatus('error');
|
|
}
|
|
}, 500); // 500ms debounce
|
|
|
|
return () => {
|
|
if (timeoutRef.current) window.clearTimeout(timeoutRef.current);
|
|
};
|
|
}, [annotations, documentId, setSaveStatus]);
|
|
}
|