import { useSignal, useSignalEffect } from '@preact/signals'; import { useEffect } from 'preact/hooks'; import { RequestBody, ResponseBody } from '/routes/api/notes/save.tsx'; import FilesBreadcrumb from '/components/files/FilesBreadcrumb.tsx'; interface NoteProps { fileName: string; currentPath: string; contents: string; } export default function Note({ fileName, currentPath, contents }: NoteProps) { const saveTimeout = useSignal>(0); const hasSavedTimeout = useSignal>(0); const isSaving = useSignal(false); const hasSaved = useSignal(false); function saveNote(newNotes: string) { if (saveTimeout.value) { clearTimeout(saveTimeout.value); } saveTimeout.value = setTimeout(async () => { hasSaved.value = false; isSaving.value = true; try { const requestBody: RequestBody = { fileName, currentPath, contents: newNotes }; const response = await fetch(`/api/notes/save`, { method: 'POST', body: JSON.stringify(requestBody), }); const result = await response.json() as ResponseBody; if (!result.success) { throw new Error('Failed to save note!'); } } catch (error) { console.error(error); } isSaving.value = false; hasSaved.value = true; }, 1000); } useSignalEffect(() => { if (hasSaved.value && !hasSavedTimeout.value) { hasSavedTimeout.value = setTimeout(() => { hasSaved.value = false; }, 3000); } }); useEffect(() => { return () => { if (saveTimeout.value) { clearTimeout(saveTimeout.value); } if (hasSavedTimeout.value) { clearTimeout(hasSavedTimeout.value); } }; }, []); return (

/ {decodeURIComponent(fileName)}

{isSaving.value ? ( <> Saving... ) : null} {hasSaved.value ? ( <> Saved! ) : null} {!isSaving.value && !hasSaved.value ? <>  : null}
); }