feat(Index.tsx): implement debounced tag generation for improved user experience

This commit is contained in:
2025-08-29 11:02:44 +02:00
parent 5fbe98630b
commit 588940bf30

View File

@@ -98,6 +98,7 @@ const Index = () => {
const [autoGenerateTags, setAutoGenerateTags] = useState(true);
const [ollamaStatus, setOllamaStatus] = useState<'unknown' | 'online' | 'offline'>('unknown');
const [includeTagsInSearch, setIncludeTagsInSearch] = useState(true);
const [tagGenerationTimeout, setTagGenerationTimeout] = useState<NodeJS.Timeout>();
const { resolvedTheme, setTheme } = useTheme();
@@ -240,12 +241,46 @@ const Index = () => {
}
};
// Debounced tag generation
const debouncedGenerateTags = (content: string, noteIndex?: number) => {
if (tagGenerationTimeout) {
clearTimeout(tagGenerationTimeout);
}
const timeout = setTimeout(async () => {
if (content.trim() && autoGenerateTags) {
try {
addDebugInfo('Auto-generating tags...');
const tags = await generateTags(content, noteIndex);
if (noteIndex !== undefined) {
// For existing notes
const note = noteCache[noteIndex];
if (note) {
const updatedNote = { ...note, tags };
setPreviousNote(updatedNote);
setIsPreviousNoteModified(true);
}
} else {
// For current note
setCurrentNoteTags(tags);
}
} catch (error) {
console.error('Auto tag generation failed:', error);
}
}
}, 200);
setTagGenerationTimeout(timeout);
};
// Generate tags using Ollama
const generateTags = async (content: string, noteIndex?: number): Promise<string[]> => {
try {
const systemPrompt = `You are a helpful assistant that generates searchable tags for journal entries.
Your task is to analyze the content and generate 3-8 relevant tags that would help the author find this note later.
Your task is to analyze the content and generate 1-3 relevant tags that would help the author find this note later.
Focus on the quality of tags, not the quantity.
Focus on:
- Programming languages, frameworks, libraries mentioned
- Technical concepts and methodologies
@@ -468,7 +503,7 @@ ${content}${context}`;
// Use current note tags or generate tags using Ollama if enabled
let tags: string[] = currentNoteTags;
if (autoGenerateTags && tags.length === 0) {
addDebugInfo('Generating tags for new note...');
addDebugInfo('Generating tags for new note before saving...');
tags = await generateTags(trimmedContent, 0); // New note will be at index 0
}
@@ -543,6 +578,13 @@ ${content}${context}`;
const noteIndex = noteCache.findIndex(n => n.id === note.id);
tags = await generateTags(trimmedContent, noteIndex);
}
// Generate tags if none are present and auto-generation is enabled
if (autoGenerateTags && tags.length === 0) {
addDebugInfo('No tags present, generating tags before saving...');
const noteIndex = noteCache.findIndex(n => n.id === note.id);
tags = await generateTags(trimmedContent, noteIndex);
}
const document = {
id: note.id,
@@ -1147,6 +1189,10 @@ ${content}${context}`;
if (saveTimeoutRef.current) {
clearTimeout(saveTimeoutRef.current);
}
// Clear any pending tag generation timeout on cleanup
if (tagGenerationTimeout) {
clearTimeout(tagGenerationTimeout);
}
};
}, [currentNote, previousNote, scratchPad, isPreviousNoteModified, isSearchOpen, isGotoOpen, isCleanupOpen]);
@@ -1778,10 +1824,12 @@ ${content}${context}`;
<Textarea
value={previousNote.content}
onChange={(e) => {
const updatedNote = { ...previousNote, content: e.target.value };
const newContent = e.target.value;
const updatedNote = { ...previousNote, content: newContent };
setPreviousNote(updatedNote);
setIsPreviousNoteModified(true);
if (e.target.value.trim() === '') {
debouncedGenerateTags(newContent, currentNoteIndex);
if (newContent.trim() === '') {
deleteNote(previousNote.id);
}
}}
@@ -1834,7 +1882,9 @@ ${content}${context}`;
ref={currentNoteRef}
value={currentNote}
onChange={(e) => {
setCurrentNote(e.target.value);
const newContent = e.target.value;
setCurrentNote(newContent);
debouncedGenerateTags(newContent);
}}
onBlur={handleCurrentNoteBlur}
className={`h-[calc(100%-2rem)] border-0 resize-none focus:ring-0 bg-transparent ${getTextClass('2xl')}`}