diff --git a/frontend/src/components/MaestroButton.tsx b/frontend/src/components/MaestroButton.tsx index cff2454..a186358 100644 --- a/frontend/src/components/MaestroButton.tsx +++ b/frontend/src/components/MaestroButton.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useState, useEffect, useRef } from 'react' import type { PromptStructure } from './StructuredPromptEditor' interface Props { @@ -19,26 +19,39 @@ interface Props { onStructuredResult?: (fields: PromptStructure, mode: 'generate' | 'complete') => void } -function NoteIcon({ bouncing }: { bouncing: boolean }) { +// ── Note Variants ───────────────────────────────────────────────────── + +const NOTES = [ + // Quarter note (♩) + 'M5.5 13 C4 13 3 12 3 11.5 C3 11 4 10.5 5.5 10.5 C7 10.5 8 11 8 11.5 C8 12 7 13 5.5 13 Z M7.8 11 L7.8 4', + // Eighth note (♪) + 'M5.5 13 C4 13 3 12 3 11.5 C3 11 4 10.5 5.5 10.5 C7 10.5 8 11 8 11.5 C8 12 7 13 5.5 13 Z M7.8 11 L7.8 4 C10 5.5 9.5 7.5 7.8 8', + // Beamed eighths (♫) + 'M3 13 C1.5 13 0.5 12 0.5 11.5 C0.5 11 1.5 10.5 3 10.5 C4.5 10.5 5.5 11 5.5 11.5 C5.5 12 4.5 13 3 13 Z M5.3 11 L5.3 4 M10 12.5 C8.5 12.5 7.5 11.5 7.5 11 C7.5 10.5 8.5 10 10 10 C11.5 10 12.5 10.5 12.5 11 C12.5 11.5 11.5 12.5 10 12.5 Z M12.3 11 L12.3 4 M5.3 4 L12.3 4', + // Sixteenth note (♬) + 'M5.5 13 C4 13 3 12 3 11.5 C3 11 4 10.5 5.5 10.5 C7 10.5 8 11 8 11.5 C8 12 7 13 5.5 13 Z M7.8 11 L7.8 4 M7.8 7 C10 6 9.5 5.5 7.8 5 M7.8 9 C10 8 9.5 7.5 7.8 7', +] + +const STAFF_LINES = ( + <> + + + + + +) + +function NoteIcon({ noteIndex, bouncing }: { noteIndex: number; bouncing: boolean }) { return ( ) } @@ -52,6 +65,26 @@ export default function MaestroButton({ onStructuredResult, }: Props) { const [isMaestroing, setIsMaestroing] = useState(false) + const [noteIndex, setNoteIndex] = useState(1) // Start on eighth note (♪) + const intervalRef = useRef | null>(null) + + // Cycle through note variants while loading + useEffect(() => { + if (isMaestroing) { + intervalRef.current = setInterval(() => { + setNoteIndex(prev => (prev + 1) % NOTES.length) + }, 800) // Change note every 800ms (slightly slower than bounce) + } else { + if (intervalRef.current) { + clearInterval(intervalRef.current) + intervalRef.current = null + } + setNoteIndex(1) // Reset to eighth note when idle + } + return () => { + if (intervalRef.current) clearInterval(intervalRef.current) + } + }, [isMaestroing]) const handleMaestro = async () => { setIsMaestroing(true) @@ -109,7 +142,7 @@ export default function MaestroButton({ : "Let Maestro complete your prompt with musical details" } > - + {isMaestroing ? (mode === 'generate' ? 'Dreaming...' : 'Composing...')