import clsx from 'clsx'; import React, { useEffect, useRef } from 'react'; import { useNotebookStore } from '@/store/notebookStore'; import { useTranslation } from '@/hooks/useTranslation'; import { useResponsiveSize } from '@/hooks/useResponsiveSize'; import { TextSelection } from '@/utils/sel'; import { md5Fingerprint } from '@/utils/md5'; import { BookNote } from '@/types/book'; import useShortcuts from '@/hooks/useShortcuts'; interface NoteEditorProps { onSave: (selection: TextSelection, note: string) => void; onEdit: (annotation: BookNote) => void; } const NoteEditor: React.FC = ({ onSave, onEdit }) => { const _ = useTranslation(); const { notebookNewAnnotation, notebookEditAnnotation, setNotebookNewAnnotation, setNotebookEditAnnotation, saveNotebookAnnotationDraft, getNotebookAnnotationDraft, } = useNotebookStore(); const editorRef = useRef(null); const [note, setNote] = React.useState(''); const separatorWidth = useResponsiveSize(3); useEffect(() => { if (editorRef.current) { editorRef.current.focus(); } }, [editorRef]); useEffect(() => { if (notebookEditAnnotation) { setNote(notebookEditAnnotation.note); if (editorRef.current) { editorRef.current.value = notebookEditAnnotation.note; editorRef.current.focus(); adjustHeight(); } } else if (notebookNewAnnotation) { const noteText = getAnnotationText(); if (noteText) { const draftNote = getNotebookAnnotationDraft(md5Fingerprint(noteText)) || ''; setNote(draftNote); if (editorRef.current) { editorRef.current.value = draftNote; editorRef.current.focus(); adjustHeight(); } } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [notebookNewAnnotation, notebookEditAnnotation]); const adjustHeight = () => { if (editorRef.current) { editorRef.current.style.height = 'auto'; editorRef.current.style.height = `${editorRef.current.scrollHeight}px`; } }; const getAnnotationText = () => { return notebookEditAnnotation?.text || notebookNewAnnotation?.text || ''; }; const handleOnChange = (e: React.ChangeEvent) => { adjustHeight(); setNote(e.currentTarget.value); }; const handleOnBlur = () => { if (editorRef.current && editorRef.current.value) { const noteText = getAnnotationText(); if (noteText) { saveNotebookAnnotationDraft(md5Fingerprint(noteText), editorRef.current.value); } } }; const handleSaveNote = () => { if (editorRef.current && notebookNewAnnotation) { onSave(notebookNewAnnotation, editorRef.current.value); } else if (editorRef.current && notebookEditAnnotation) { notebookEditAnnotation.note = editorRef.current.value; onEdit(notebookEditAnnotation); } }; useShortcuts({ onSaveNote: () => { if (editorRef.current && editorRef.current.value) { handleSaveNote(); } }, onEscape: () => { if (notebookNewAnnotation) { setNotebookNewAnnotation(null); } if (notebookEditAnnotation) { setNotebookEditAnnotation(null); } }, }); return (
{getAnnotationText()}
); }; export default NoteEditor;