import clsx from 'clsx'; import React, { useEffect } from 'react'; import { useReaderStore } from '@/store/readerStore'; import { useEnv } from '@/context/EnvContext'; import useDragBar from '../../hooks/useDragBar'; import NotebookHeader from './Header'; import NoteEditor from './NoteEditor'; import { TextSelection } from '@/utils/sel'; import { BookNote } from '@/types/book'; import { uniqueId } from '@/utils/misc'; import BooknoteItem from '../sidebar/BooknoteItem'; const MIN_NOTEBOOK_WIDTH = 0.15; const MAX_NOTEBOOK_WIDTH = 0.45; const Notebook: React.FC = ({}) => { const { envConfig } = useEnv(); const { settings, sideBarBookKey, notebookWidth } = useReaderStore(); const { isNotebookVisible, isNotebookPinned } = useReaderStore(); const { notebookNewAnnotation, notebookEditAnnotation } = useReaderStore(); const { setNotebookWidth, setNotebookPin, toggleNotebookPin } = useReaderStore(); const { getConfig, saveConfig, getView, setNotebookVisible, updateBooknotes } = useReaderStore(); const { setNotebookNewAnnotation, setNotebookEditAnnotation } = useReaderStore(); useEffect(() => { setNotebookWidth(settings.globalReadSettings.notebookWidth); setNotebookPin(settings.globalReadSettings.isNotebookPinned); setNotebookVisible(settings.globalReadSettings.isNotebookPinned); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const handleNotebookResize = (newWidth: string) => { setNotebookWidth(newWidth); settings.globalReadSettings.notebookWidth = newWidth; }; const handleTogglePin = () => { toggleNotebookPin(); settings.globalReadSettings.isNotebookPinned = !isNotebookPinned; }; const handleClickOverlay = (event: React.MouseEvent) => { event.preventDefault(); event.stopPropagation(); setNotebookVisible(false); }; const handleDragMove = (e: MouseEvent) => { const widthFraction = 1 - e.clientX / window.innerWidth; const newWidth = Math.max(MIN_NOTEBOOK_WIDTH, Math.min(MAX_NOTEBOOK_WIDTH, widthFraction)); handleNotebookResize(`${Math.round(newWidth * 10000) / 100}%`); }; const handleSaveNote = (selection: TextSelection, note: string) => { if (!sideBarBookKey) return; const view = getView(sideBarBookKey); const config = getConfig(sideBarBookKey)!; const cfi = view?.getCFI(selection.index, selection.range); if (!cfi) return; const { booknotes: annotations = [] } = config; const annotation: BookNote = { id: uniqueId(), type: 'annotation', cfi, note, href: selection.href || '', text: selection.text, created: Date.now(), }; annotations.push(annotation); const updatedConfig = updateBooknotes(sideBarBookKey, annotations); if (updatedConfig) { saveConfig(envConfig, sideBarBookKey, updatedConfig, settings); } setNotebookNewAnnotation(null); }; const handleEditNote = (annotation: BookNote) => { if (!sideBarBookKey) return; const config = getConfig(sideBarBookKey)!; const { booknotes: annotations = [] } = config; const existingIndex = annotations.findIndex((item) => item.id === annotation.id); if (existingIndex === -1) return; annotation.modified = Date.now(); annotations[existingIndex] = annotation; const updatedConfig = updateBooknotes(sideBarBookKey, annotations); if (updatedConfig) { saveConfig(envConfig, sideBarBookKey, updatedConfig, settings); } setNotebookEditAnnotation(null); }; const { handleMouseDown } = useDragBar(handleDragMove); const deleteNote = (note: BookNote) => { if (!sideBarBookKey) return; const config = getConfig(sideBarBookKey); if (!config) return; const { booknotes = [] } = config; const updatedNotes = booknotes.filter((item) => item.id !== note.id); const updatedConfig = updateBooknotes(sideBarBookKey, updatedNotes); if (updatedConfig) { saveConfig(envConfig, sideBarBookKey, updatedConfig, settings); } }; if (!sideBarBookKey) return null; const config = getConfig(sideBarBookKey); const { booknotes: allNotes = [] } = config || {}; const annotationNotes = allNotes .filter((note) => note.type === 'annotation' && note.note) .sort((a, b) => b.created - a.created); const excerptNotes = allNotes .filter((note) => note.type === 'excerpt') .sort((a, b) => a.created - b.created); return isNotebookVisible ? ( <> {!isNotebookPinned && (
)}
{excerptNotes.length > 0 &&

Excerpts

}
    {excerptNotes.map((item, index) => (
  • {item.text || `Excerpt ${index + 1}`}

    e.stopPropagation()} >

    {item.text}

  • ))}
{(notebookNewAnnotation || annotationNotes.length > 0) && (

Notes

)}
{(notebookNewAnnotation || notebookEditAnnotation) && ( )}
    {annotationNotes.map((item, index) => ( ))}
) : null; }; export default Notebook;