import type React from 'react' import { useCallback } from 'react' import type { VaultEntry, NoteStatus } from '../types' import type { useCreateBlockNote } from '@blocknote/react' import { DiffView } from './DiffView' import { BreadcrumbBar } from './BreadcrumbBar' import { TitleField } from './TitleField' import { NoteIcon } from './NoteIcon' import { TrashedNoteBanner } from './TrashedNoteBanner' import { ArchivedNoteBanner } from './ArchivedNoteBanner' import { RawEditorView } from './RawEditorView' import { countWords } from '../utils/wikilinks' import { SingleEditorView } from './SingleEditorView' import { isEmoji } from '../utils/emoji' interface Tab { entry: VaultEntry content: string } interface EditorContentProps { activeTab: Tab | null isLoadingNewTab: boolean entries: VaultEntry[] editor: ReturnType diffMode: boolean diffContent: string | null diffLoading: boolean onToggleDiff: () => void rawMode: boolean onToggleRaw: () => void onRawContentChange?: (path: string, content: string) => void onSave?: () => void activeStatus: NoteStatus showDiffToggle: boolean showAIChat?: boolean onToggleAIChat?: () => void inspectorCollapsed: boolean onToggleInspector: () => void onNavigateWikilink: (target: string) => void onEditorChange?: () => void onTrashNote?: (path: string) => void onRestoreNote?: (path: string) => void onDeleteNote?: (path: string) => void onArchiveNote?: (path: string) => void onUnarchiveNote?: (path: string) => void vaultPath?: string isDarkTheme?: boolean /** Ref updated by RawEditorView on every keystroke with the latest doc. */ rawLatestContentRef?: React.MutableRefObject /** Called when the user edits the dedicated title field. */ onTitleChange?: (path: string, newTitle: string) => void /** Called when user sets or changes an emoji icon via the picker. */ onSetNoteIcon?: (path: string, emoji: string) => void /** Called when user removes an emoji icon. */ onRemoveNoteIcon?: (path: string) => void } function EditorLoadingSkeleton() { return (
) } function DiffModeView({ diffContent, onToggleDiff }: { diffContent: string | null; onToggleDiff: () => void }) { return (
) } function RawModeEditorSection({ rawMode, activeTab, entries, onContentChange, onSave, isDark, latestContentRef, }: { rawMode: boolean activeTab: Tab | null entries: VaultEntry[] onContentChange?: (path: string, content: string) => void onSave?: () => void isDark?: boolean latestContentRef?: React.MutableRefObject }) { if (!rawMode || !activeTab) return null return ( {})} onSave={onSave ?? (() => {})} isDark={isDark} latestContentRef={latestContentRef} /> ) } /** Bind an optional callback to a path, returning undefined if callback is absent */ function bindPath(cb: ((path: string) => void) | undefined, path: string) { return cb ? () => cb(path) : undefined } function ActiveTabBreadcrumb({ activeTab, props }: { activeTab: Tab props: Omit }) { const wordCount = countWords(activeTab.content) const path = activeTab.entry.path return ( ) } function EditorBody({ activeTab, isLoadingNewTab, entries, editor, diffMode, diffContent, onToggleDiff, rawMode, onRawContentChange, onSave, onNavigateWikilink, onEditorChange, vaultPath, isDarkTheme, isTrashed, rawLatestContentRef }: { activeTab: Tab | null; isLoadingNewTab: boolean; entries: VaultEntry[] editor: ReturnType diffMode: boolean; diffContent: string | null; onToggleDiff: () => void rawMode: boolean; onRawContentChange?: (path: string, content: string) => void; onSave?: () => void onNavigateWikilink: (target: string) => void; onEditorChange?: () => void vaultPath?: string; isDarkTheme?: boolean; isTrashed: boolean rawLatestContentRef?: React.MutableRefObject }) { const showEditor = !diffMode && !rawMode return ( <> {diffMode && } {showEditor && activeTab && (
)} {isLoadingNewTab && showEditor && } ) } export function EditorContent({ activeTab, isLoadingNewTab, entries, editor, diffMode, diffContent, onToggleDiff, rawMode, onToggleRaw, onRawContentChange, onSave, onNavigateWikilink, onEditorChange, vaultPath, isDarkTheme, onDeleteNote, rawLatestContentRef, onTitleChange, onSetNoteIcon, onRemoveNoteIcon, ...breadcrumbProps }: EditorContentProps) { const isTrashed = activeTab?.entry.trashed ?? false const showTitleField = activeTab && !diffMode && !rawMode const entryIcon = activeTab?.entry.icon ?? null const emojiIcon = entryIcon && isEmoji(entryIcon) ? entryIcon : null const handleSetIcon = useCallback((emoji: string) => { if (activeTab) onSetNoteIcon?.(activeTab.entry.path, emoji) }, [activeTab, onSetNoteIcon]) const handleRemoveIcon = useCallback(() => { if (activeTab) onRemoveNoteIcon?.(activeTab.entry.path) }, [activeTab, onRemoveNoteIcon]) return (
{activeTab && ( )} {activeTab && isTrashed && ( breadcrumbProps.onRestoreNote?.(activeTab.entry.path)} onDeletePermanently={() => onDeleteNote?.(activeTab.entry.path)} /> )} {activeTab?.entry.archived && breadcrumbProps.onUnarchiveNote && ( breadcrumbProps.onUnarchiveNote!(activeTab.entry.path)} /> )} {showTitleField && ( )} {showTitleField && ( onTitleChange?.(activeTab.entry.path, newTitle)} /> )}
) }