e.stopPropagation()}>
Settings
{/* Theme Settings */}
Theme
{[
{ id: 'light', icon: Sun, label: 'Light' },
{ id: 'dark', icon: Moon, label: 'Dark' },
{ id: 'auto', icon: Monitor, label: 'Auto' }
].map(mode => (
onUpdateSettings({ ...settings, theme: mode.id as any })}
style={{
flex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
gap: '6px',
padding: '8px',
border: 'none',
background: (settings.theme || 'auto') === mode.id ? 'var(--color-surface)' : 'transparent',
color: (settings.theme || 'auto') === mode.id ? 'var(--color-primary)' : 'var(--color-text-muted)',
borderRadius: '6px',
cursor: 'pointer',
boxShadow: (settings.theme || 'auto') === mode.id ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
fontWeight: 500,
fontSize: '13px',
transition: 'all 0.2s'
}}
>
{mode.label}
))}
{/* Animation Settings */}
Disable success animation
onUpdateSettings({ ...settings, disableAnimation: !settings.disableAnimation })}
title={settings.disableAnimation ? "Enable Animation" : "Disable Animation"}
>
Removes the "Good!" overlay to allow faster playing.
{/* Auto Play Settings */}
{settings.gameMode === 'ear_training'
? "Automatically plays the note audio (Required for Ear Training)."
: "Automatically plays the note audio when a new note appears."}
{/* Microphone Toggle */}
{isListening ? : }
Microphone
{isListening ? 'Microphone is active and listening for notes.' : 'Enable microphone to detect your playing.'}
{/* Mic Sensitivity */}
Microphone Sensitivity
Adjust if notes are not detected (increase/right) or if background noise triggers notes (decrease/left).
{/* Microphone Level Meter */}
Microphone Level
{isListening ? '(active)' : '(inactive)'}
{!isListening && (
Enable microphone to see audio levels
)}
{/* Debug Info Toggle */}
setShowDebugInfo(!showDebugInfo)}
style={{
marginTop: '16px',
background: 'transparent',
border: '1px solid rgba(255,255,255,0.2)',
borderRadius: '4px',
padding: '8px 12px',
color: 'inherit',
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
gap: '8px',
fontSize: '12px',
opacity: 0.7,
width: '100%',
justifyContent: 'center'
}}
>
{showDebugInfo ? : }
Microphone Debug Info
{/* Debug Info Panel */}
{showDebugInfo && (
Status:
{debugInfo?.isCapturing ? '✓ Capturing' :
debugInfo?.audioContextState === 'suspended' ? '⚠ Suspended' :
isListening ? '✗ Not Capturing' : '○ Inactive'}
AudioContext:
{debugInfo?.audioContextState || 'N/A'}
Sample Rate:
{debugInfo?.sampleRate ? `${debugInfo.sampleRate} Hz` : 'N/A'}
Input Device:
{debugInfo?.inputDeviceLabel || 'N/A'}
Permission:
{debugInfo?.permissionState || 'unknown'}
RMS Level:
{debugInfo?.currentRmsLevel !== undefined
? `${debugInfo.currentRmsLevel.toFixed(4)} (${Math.round(debugInfo.currentRmsDb)} dB)`
: 'N/A'}
Browser:
{typeof navigator !== 'undefined' ? navigator.userAgent.slice(0, 60) + '...' : 'N/A'}
{debugInfo?.audioContextState === 'suspended' && (
⚠ AudioContext is suspended. Try tapping the mic button again or interacting with the page.
)}
{isListening && !debugInfo?.isCapturing && debugInfo?.audioContextState === 'running' && (
✗ AudioContext is running but no audio is being captured. Check if another app is using the microphone.
)}
)}