import { useRef, useEffect, memo } from 'react' import { useEditorTabSwap } from '../hooks/useEditorTabSwap' import { useCreateBlockNote } from '@blocknote/react' import '@blocknote/mantine/style.css' import { uploadImageFile } from '../hooks/useImageDrop' import type { VaultEntry, GitCommit, NoteStatus } from '../types' import type { FrontmatterValue } from './Inspector' import { ResizeHandle } from './ResizeHandle' import { TabBar } from './TabBar' import { useDiffMode } from '../hooks/useDiffMode' import { useEditorFocus } from '../hooks/useEditorFocus' import { EditorRightPanel } from './EditorRightPanel' import { EditorContent } from './EditorContent' import { schema } from './editorSchema' import './Editor.css' import './EditorTheme.css' interface Tab { entry: VaultEntry content: string } interface EditorProps { tabs: Tab[] activeTabPath: string | null entries: VaultEntry[] onSwitchTab: (path: string) => void onCloseTab: (path: string) => void onReorderTabs?: (fromIndex: number, toIndex: number) => void onNavigateWikilink: (target: string) => void onLoadDiff?: (path: string) => Promise onLoadDiffAtCommit?: (path: string, commitHash: string) => Promise getNoteStatus?: (path: string) => NoteStatus onCreateNote?: () => void inspectorCollapsed: boolean onToggleInspector: () => void inspectorWidth: number onInspectorResize: (delta: number) => void inspectorEntry: VaultEntry | null inspectorContent: string | null allContent: Record gitHistory: GitCommit[] onUpdateFrontmatter?: (path: string, key: string, value: FrontmatterValue) => Promise onDeleteProperty?: (path: string, key: string) => Promise onAddProperty?: (path: string, key: string, value: FrontmatterValue) => Promise showAIChat?: boolean onToggleAIChat?: () => void vaultPath?: string onTrashNote?: (path: string) => void onRestoreNote?: (path: string) => void onArchiveNote?: (path: string) => void onUnarchiveNote?: (path: string) => void onRenameTab?: (path: string, newTitle: string) => void onContentChange?: (path: string, content: string) => void canGoBack?: boolean canGoForward?: boolean onGoBack?: () => void onGoForward?: () => void } function EditorEmptyState() { return (

Select a note to start editing

Cmd+P to search · Cmd+N to create
) } export const Editor = memo(function Editor({ tabs, activeTabPath, entries, onSwitchTab, onCloseTab, onReorderTabs, onNavigateWikilink, onLoadDiff, onLoadDiffAtCommit, getNoteStatus, onCreateNote, inspectorCollapsed, onToggleInspector, inspectorWidth, onInspectorResize, inspectorEntry, inspectorContent, allContent, gitHistory, onUpdateFrontmatter, onDeleteProperty, onAddProperty, showAIChat, onToggleAIChat, vaultPath, onTrashNote, onRestoreNote, onArchiveNote, onUnarchiveNote, onRenameTab, onContentChange, canGoBack, canGoForward, onGoBack, onGoForward, }: EditorProps) { const vaultPathRef = useRef(vaultPath) useEffect(() => { vaultPathRef.current = vaultPath }, [vaultPath]) const editor = useCreateBlockNote({ schema, uploadFile: (file: File) => uploadImageFile(file, vaultPathRef.current), }) const { handleEditorChange, editorMountedRef } = useEditorTabSwap({ tabs, activeTabPath, editor, onContentChange }) useEditorFocus(editor, editorMountedRef) const { diffMode, diffContent, diffLoading, handleToggleDiff, handleViewCommitDiff } = useDiffMode({ activeTabPath, onLoadDiff, onLoadDiffAtCommit, }) const activeTab = tabs.find((t) => t.entry.path === activeTabPath) ?? null const isLoadingNewTab = activeTabPath !== null && !activeTab const activeStatus = activeTab ? getNoteStatus?.(activeTab.entry.path) ?? 'clean' : 'clean' const showDiffToggle = !!(activeTab && (diffMode || activeStatus === 'modified')) const showRightPanel = !!(showAIChat || !inspectorCollapsed) return (
{tabs.length === 0 ? : } {showRightPanel && }
) })