From 36733da4342a601a033ca4af3a51a710a5aa98db Mon Sep 17 00:00:00 2001 From: drelich Date: Wed, 25 Mar 2026 23:48:36 +0100 Subject: [PATCH] Remove title field again after revert - keep auto-resize behavior - Removed separate title input field (reverted back in previous commit) - Title extracted from first line of content - Favorite star moved to toolbar - Fixed duplicate import in NotesList - Auto-resize behavior preserved to avoid scroll jumping issue --- src/components/NoteEditor.tsx | 89 +++++++++++------------------------ src/components/NotesList.tsx | 1 - 2 files changed, 28 insertions(+), 62 deletions(-) diff --git a/src/components/NoteEditor.tsx b/src/components/NoteEditor.tsx index 07e0411..c931327 100644 --- a/src/components/NoteEditor.tsx +++ b/src/components/NoteEditor.tsx @@ -25,13 +25,11 @@ const imageCache = new Map(); export function NoteEditor({ note, onUpdateNote, onUnsavedChanges, categories, isFocusMode, onToggleFocusMode, editorFont = 'Source Code Pro', editorFontSize = 14, previewFont = 'Merriweather', previewFontSize = 16, api }: NoteEditorProps) { - const [localTitle, setLocalTitle] = useState(''); const [localContent, setLocalContent] = useState(''); const [localCategory, setLocalCategory] = useState(''); const [localFavorite, setLocalFavorite] = useState(false); const [isSaving, setIsSaving] = useState(false); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); - const [titleManuallyEdited, setTitleManuallyEdited] = useState(false); const [isExportingPDF, setIsExportingPDF] = useState(false); const [isPreviewMode, setIsPreviewMode] = useState(false); const [processedContent, setProcessedContent] = useState(''); @@ -140,17 +138,10 @@ export function NoteEditor({ note, onUpdateNote, onUnsavedChanges, categories, i useEffect(() => { const loadNewNote = () => { if (note) { - setLocalTitle(note.title); setLocalContent(note.content); setLocalCategory(note.category || ''); setLocalFavorite(note.favorite); setHasUnsavedChanges(false); - setIsPreviewMode(false); - setProcessedContent(''); // Clear preview content immediately - - const firstLine = note.content.split('\n')[0].replace(/^#+\s*/, '').trim(); - const titleMatchesFirstLine = note.title === firstLine || note.title === firstLine.substring(0, 50); - setTitleManuallyEdited(!titleMatchesFirstLine); previousNoteIdRef.current = note.id; previousNoteContentRef.current = note.content; @@ -184,9 +175,13 @@ export function NoteEditor({ note, onUpdateNote, onUnsavedChanges, categories, i console.log('Last 50 chars:', localContent.slice(-50)); setIsSaving(true); setHasUnsavedChanges(false); + + const firstLine = localContent.split('\n')[0].replace(/^#+\s*/, '').trim(); + const title = firstLine || 'Untitled'; + onUpdateNote({ ...note, - title: localTitle, + title, content: localContent, category: localCategory, favorite: localFavorite, @@ -194,36 +189,18 @@ export function NoteEditor({ note, onUpdateNote, onUnsavedChanges, categories, i setTimeout(() => setIsSaving(false), 500); }; - const handleTitleChange = (value: string) => { - setLocalTitle(value); - setTitleManuallyEdited(true); - setHasUnsavedChanges(true); - }; - const handleContentChange = (value: string) => { setLocalContent(value); setHasUnsavedChanges(true); - - if (!titleManuallyEdited) { - const firstLine = value.split('\n')[0].replace(/^#+\s*/, '').trim(); - if (firstLine) { - setLocalTitle(firstLine.substring(0, 50)); - } - } }; const handleDiscard = () => { if (!note) return; - setLocalTitle(note.title); setLocalContent(note.content); setLocalCategory(note.category || ''); setLocalFavorite(note.favorite); setHasUnsavedChanges(false); - - const firstLine = note.content.split('\n')[0].replace(/^#+\s*/, '').trim(); - const titleMatchesFirstLine = note.title === firstLine || note.title === firstLine.substring(0, 50); - setTitleManuallyEdited(!titleMatchesFirstLine); }; const loadFontAsBase64 = async (fontPath: string): Promise => { @@ -344,7 +321,8 @@ export function NoteEditor({ note, onUpdateNote, onUnsavedChanges, categories, i container.style.color = '#000000'; const titleElement = document.createElement('h1'); - titleElement.textContent = localTitle || 'Untitled'; + const firstLine = localContent.split('\n')[0].replace(/^#+\s*/, '').trim(); + titleElement.textContent = firstLine || 'Untitled'; titleElement.style.marginTop = '0'; titleElement.style.marginBottom = '20px'; titleElement.style.fontSize = '24px'; @@ -385,7 +363,8 @@ export function NoteEditor({ note, onUpdateNote, onUnsavedChanges, categories, i // Use jsPDF's html() method with custom font set await pdf.html(container, { callback: async (doc) => { - const fileName = `${localTitle || 'note'}.pdf`; + const firstLine = localContent.split('\n')[0].replace(/^#+\s*/, '').trim(); + const fileName = `${firstLine || 'note'}.pdf`; doc.save(fileName); setTimeout(async () => { @@ -422,9 +401,12 @@ export function NoteEditor({ note, onUpdateNote, onUnsavedChanges, categories, i const handleFavoriteToggle = () => { setLocalFavorite(!localFavorite); if (note) { + const firstLine = localContent.split('\n')[0].replace(/^#+\s*/, '').trim(); + const title = firstLine || 'Untitled'; + onUpdateNote({ ...note, - title: localTitle, + title, content: localContent, category: localCategory, favorite: !localFavorite, @@ -667,36 +649,6 @@ export function NoteEditor({ note, onUpdateNote, onUnsavedChanges, categories, i return (
- {/* Header */} -
-
-
- handleTitleChange(e.target.value)} - placeholder="Note Title" - className="w-full text-2xl font-semibold border-none outline-none focus:ring-0 bg-transparent text-gray-900 dark:text-gray-100 placeholder-gray-400" - /> -
- - -
-
- {/* Toolbar */}
@@ -766,6 +718,21 @@ export function NoteEditor({ note, onUpdateNote, onUnsavedChanges, categories, i {/* Action Buttons */}
+ +