diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 9b336ba..34e9aaf 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -73,6 +73,7 @@ const Index = () => { console.log(`Component mounted after ${Date.now() - GLOBAL_START_TIME}ms`); const [currentNote, setCurrentNote] = useState(''); + const [currentNoteTags, setCurrentNoteTags] = useState([]); const [previousNote, setPreviousNote] = useState(null); const [scratchPad, setScratchPad] = useState(''); const [scratchId, setScratchId] = useState(null); @@ -251,7 +252,7 @@ Focus on: - Problem domains or contexts - Key technical terms that someone might search for -Return ONLY a JSON array of strings, no other text. Example: ["golang", "testing", "array-comparison", "cmp-library"] +Return ONLY a comma-separated list of tags, no other text. Example: golang, testing, array-comparison, cmp-library Keep tags concise, use lowercase, and separate words with hyphens if needed.`; @@ -273,37 +274,25 @@ ${content}`; }, 'Generate Tags'); if (!response.ok) { - throw new Error('Failed to generate tags'); + const errorText = await response.text().catch(() => 'Unknown error'); + throw new Error(`Ollama API error ${response.status}: ${errorText}`); } const data = await response.json(); const responseText = data.response?.trim(); if (!responseText) { - throw new Error('Empty response from Ollama'); + throw new Error('Empty response from Ollama - check if model is loaded'); } - // Try to parse JSON from the response - try { - const tags = JSON.parse(responseText); - if (Array.isArray(tags) && tags.every(tag => typeof tag === 'string')) { - addDebugInfo(`Generated ${tags.length} tags: ${tags.join(', ')}`); - return tags; - } - } catch (parseError) { - console.warn('Failed to parse tags as JSON, trying to extract from text:', responseText); - } - - // Fallback: try to extract tags from text response - const tagMatch = responseText.match(/\[(.*?)\]/); - if (tagMatch) { - const tags = tagMatch[1] - .split(',') - .map((tag: string) => tag.trim().replace(/"/g, '')) - .filter((tag: string) => tag.length > 0); - addDebugInfo(`Extracted ${tags.length} tags from text: ${tags.join(', ')}`); - return tags; - } + // Parse CSV format from the response + const tags = responseText + .split(',') + .map((tag: string) => tag.trim()) + .filter((tag: string) => tag.length > 0); + + addDebugInfo(`Generated ${tags.length} tags: ${tags.join(', ')}`); + return tags; // Last resort: return empty array addDebugInfo('Could not extract tags from Ollama response'); @@ -311,13 +300,34 @@ ${content}`; } catch (error) { console.error('Error generating tags:', error); const errorMessage = error instanceof Error ? error.message : 'Unknown error'; - addDebugInfo(`Tag generation failed: ${errorMessage}`); - // Check if it's a connection error - if (errorMessage.includes('fetch') || errorMessage.includes('network') || errorMessage.includes('ECONNREFUSED')) { - addDebugInfo('Ollama appears to be offline. Please ensure Ollama is running on localhost:11434'); + // More detailed error logging and user notification + let userMessage = 'Failed to generate tags'; + + if (error instanceof TypeError && error.message.includes('fetch')) { + addDebugInfo('Tag generation failed: Network error - Ollama not reachable at localhost:11434'); + userMessage = 'Ollama not reachable - check if it\'s running on localhost:11434'; + } else if (errorMessage.includes('Failed to fetch')) { + addDebugInfo('Tag generation failed: Ollama connection refused - check if Ollama is running'); + userMessage = 'Ollama connection refused - check if Ollama is running'; + } else if (errorMessage.includes('404')) { + addDebugInfo('Tag generation failed: Ollama endpoint not found - check model name'); + userMessage = 'Model not found - check if llama3.2:3b is installed'; + } else if (errorMessage.includes('500')) { + addDebugInfo('Tag generation failed: Ollama server error - check model is loaded'); + userMessage = 'Ollama server error - check if model is loaded'; + } else { + addDebugInfo(`Tag generation failed: ${errorMessage}`); + userMessage = `Tag generation failed: ${errorMessage}`; } + // Show error to user + toast({ + title: "Tag Generation Failed", + description: userMessage, + variant: "destructive", + }); + return []; } }; @@ -434,9 +444,9 @@ ${content}`; const { mostFrequentLetter, mostFrequentLetterFrequency, letterCount } = calculateLetterFrequency(trimmedContent); const now = new Date(); - // Generate tags using Ollama if enabled - let tags: string[] = []; - if (autoGenerateTags) { + // 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...'); tags = await generateTags(trimmedContent); } @@ -480,6 +490,7 @@ ${content}`; setNoteCache(prev => [newNote, ...prev]); setPreviousNote(newNote); setCurrentNoteIndex(0); + setCurrentNoteTags([]); toast({ title: "Note saved", @@ -1696,28 +1707,44 @@ ${content}`; ref={previousNoteRef} className="flex-1 bg-card rounded-lg border border-border shadow-sm p-6 overflow-auto cursor-pointer select-none" > -
+
Previous Entry {currentNoteIndex > 0 && `(${currentNoteIndex + 1} of ${noteCache.length})`} Scroll to navigate
- {previousNote && !autoGenerateTags && ( - + }} + className={`flex-1 border-0 bg-transparent ${getTextClass('base')} p-0 outline-none`} + /> + {!autoGenerateTags && ( + + )} +
)}
{previousNote ? ( @@ -1725,15 +1752,6 @@ ${content}`;
{formatDate(previousNote.epochTime)}
- {previousNote.tags && previousNote.tags.length > 0 && ( -
- {previousNote.tags.map((tag, index) => ( - - {tag} - - ))} -
- )}