diff --git a/app/analyze/[videoId]/page.tsx b/app/analyze/[videoId]/page.tsx index 8ba3af1c..3f77c493 100644 --- a/app/analyze/[videoId]/page.tsx +++ b/app/analyze/[videoId]/page.tsx @@ -1753,7 +1753,22 @@ export default function AnalyzePage() { }); }, [promptSignInForNotes, user]); - const handleSaveEditingNote = useCallback(async ({ noteText, selectedText }: { noteText: string; selectedText: string }) => { + const handleAddNote = useCallback(() => { + if (!user) { + promptSignInForNotes(); + return; + } + + rightColumnTabsRef.current?.switchToNotes(); + + setEditingNote({ + text: "", + metadata: null, + source: "custom", + }); + }, [user, promptSignInForNotes]); + + const handleSaveEditingNote = useCallback(async ({ noteText, selectedText, metadata }: { noteText: string; selectedText: string; metadata?: NoteMetadata }) => { if (!editingNote || !videoId) return; // Use source from editing note or determine from metadata @@ -1771,8 +1786,12 @@ export default function AnalyzePage() { ? { ...(editingNote.metadata ?? {}), selectedText: normalizedSelected, + ...(metadata ?? {}) } - : editingNote.metadata ?? undefined; + : { + ...(editingNote.metadata ?? {}), + ...(metadata ?? {}) + }; await handleSaveNote({ text: noteText, @@ -1999,6 +2018,7 @@ export default function AnalyzePage() { editingNote={editingNote} onSaveEditingNote={handleSaveEditingNote} onCancelEditing={handleCancelEditing} + onAddNote={handleAddNote} isAuthenticated={!!user} onRequestSignIn={handleAuthRequired} selectedLanguage={selectedLanguage} diff --git a/components/note-editor.tsx b/components/note-editor.tsx index f0b87294..6978efd5 100644 --- a/components/note-editor.tsx +++ b/components/note-editor.tsx @@ -6,21 +6,24 @@ import { Textarea } from "@/components/ui/textarea"; import { NoteMetadata } from "@/lib/types"; import { enhanceNoteQuote } from "@/lib/notes-client"; import { toast } from "sonner"; -import { Send, Sparkles, Loader2, RotateCcw, Check } from "lucide-react"; +import { Send, Sparkles, Loader2, RotateCcw, Check, Clock } from "lucide-react"; +import { formatDuration } from "@/lib/utils"; interface NoteEditorProps { selectedText: string; metadata?: NoteMetadata | null; - onSave: (payload: { noteText: string; selectedText: string }) => void; + currentTime?: number; + onSave: (payload: { noteText: string; selectedText: string; metadata?: NoteMetadata }) => void; onCancel: () => void; } -export function NoteEditor({ selectedText, onSave }: NoteEditorProps) { +export function NoteEditor({ selectedText, metadata, currentTime, onSave }: NoteEditorProps) { const [originalQuote, setOriginalQuote] = useState(selectedText.trim()); const [quoteText, setQuoteText] = useState(selectedText.trim()); const [additionalText, setAdditionalText] = useState(""); const [isEnhancing, setIsEnhancing] = useState(false); const [hasEnhanced, setHasEnhanced] = useState(false); + const [capturedTimestamp, setCapturedTimestamp] = useState(null); useEffect(() => { const trimmed = selectedText.trim(); @@ -28,8 +31,15 @@ export function NoteEditor({ selectedText, onSave }: NoteEditorProps) { setQuoteText(trimmed); setHasEnhanced(false); setAdditionalText(""); + setCapturedTimestamp(null); }, [selectedText]); + const handleCaptureTimestamp = useCallback(() => { + if (currentTime !== undefined) { + setCapturedTimestamp(currentTime); + } + }, [currentTime]); + const handleSave = useCallback(() => { const baseQuote = (quoteText || originalQuote).trim(); const noteParts: string[] = []; @@ -47,11 +57,26 @@ export function NoteEditor({ selectedText, onSave }: NoteEditorProps) { return; } + // Merge metadata + let finalMetadata: NoteMetadata | undefined = metadata ? { ...metadata } : undefined; + + if (capturedTimestamp !== null) { + finalMetadata = { + ...(finalMetadata || {}), + transcript: { + ...(finalMetadata?.transcript || {}), + start: capturedTimestamp, + }, + timestampLabel: formatDuration(capturedTimestamp), + }; + } + onSave({ noteText: noteParts.join("\n\n"), selectedText: baseQuote || originalQuote, + metadata: finalMetadata }); - }, [additionalText, onSave, originalQuote, quoteText]); + }, [additionalText, onSave, originalQuote, quoteText, metadata, capturedTimestamp]); const handleEnhance = useCallback(async () => { if (isEnhancing || !quoteText.trim()) { @@ -85,86 +110,112 @@ export function NoteEditor({ selectedText, onSave }: NoteEditorProps) { } }; + const hasQuote = quoteText.length > 0; const enhancementDisabled = isEnhancing || !quoteText.trim(); return (
-
- Selected Snippet - {hasEnhanced && !isEnhancing && ( - - - Cleaned - - )} -
- -
-