import React, { useEffect, useState } from 'react'; import { Gauge, SlidersHorizontal } from 'lucide-react'; import { TuningMeter } from './TuningMeter'; import { TargetNoteControls } from './TargetNoteControls'; import { MetronomeWidget } from './MetronomeWidget'; import { phraseRunBus } from '../hooks/phraseRunBus'; import { useSettings } from '../context/useSettings'; import { getPracticeFilter, type RhythmSettings } from '../types/SettingsTypes'; interface ControlsProps { currentPitch: { note: string; cents: number } | null; } export const Controls: React.FC = ({ currentPitch }) => { const { settings, updateSettings } = useSettings(); const onUpdateSettings = updateSettings; // Phrase run gate: the metronome only ticks while the phrase trainer is // counting in / playing (armed by the user toggle, fired by the run). const [phraseRunActive, setPhraseRunActive] = useState(false); useEffect(() => phraseRunBus.subscribe(setPhraseRunActive), []); // Note-filter panel: hidden by default (minimal UI), toggled here. const [filtersOpen, setFiltersOpen] = useState(false); const updateRhythm = (updates: Partial) => { onUpdateSettings({ ...settings, rhythm: { ...settings.rhythm, ...updates } }); }; const inPhraseMode = settings.gameMode === 'phrase'; const pf = getPracticeFilter(settings); const activeFilterCount = (pf.keyEnabled ? 1 : 0) + (pf.strings.length > 0 ? 1 : 0) + (pf.fretWindowEnabled ? 1 : 0); // Phrase Mode hosts the filter inside its Setup panel (above the // notation) — no footer filter button there. const showFilterButton = !inPhraseMode; const shouldShowFilters = showFilterButton && filtersOpen; return (
{/* Note filter: collapsed behind a button — visible only when needed */} {showFilterButton && (
)} {shouldShowFilters && } {/* Bottom Section: Tools Grid (stacked in all modes) */}
{/* Tool 1: Tuner */}
{settings.showTuningMeter && (
)}
{/* Tool 2: Metronome (all modes) */}
); };