- Bulk replace text-white → text-foreground across 116 component files (preserving text-white/ opacity variants) - Remove hover-glow-cyan, shadow-card-glow-cyan, shadow-button-primary-glow classes from all components - Replace --duration-normal/--duration-immersive/--duration-slow with --sumi-duration-normal/--sumi-duration-slow across 130+ files - Replace --ease-out/--ease-in-out with --sumi-ease-out/--sumi-ease-in-out - Replace focus:ring-blue-500 → focus:ring-primary (4 files) - Remove hover:scale-105/110 and hover:-translate-y-1/0.5 transforms (SUMI anti-pattern: no scale on hover) - Clean up stale kodo- references in comments Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
3.4 KiB
TypeScript
87 lines
3.4 KiB
TypeScript
import React from 'react';
|
|
import { X, Activity } from 'lucide-react';
|
|
import { useAudio, VisualizerSettings } from '../../context/AudioContext';
|
|
|
|
interface VisualizerSettingsModalProps {
|
|
onClose: () => void;
|
|
}
|
|
|
|
export const VisualizerSettingsModal: React.FC<
|
|
VisualizerSettingsModalProps
|
|
> = ({ onClose }) => {
|
|
const { visualizerSettings, setVisualizerSettings } = useAudio();
|
|
|
|
const updateSetting = (key: keyof VisualizerSettings, value: any) => {
|
|
setVisualizerSettings({ ...visualizerSettings, [key]: value });
|
|
};
|
|
|
|
const colors = ['#7c9dd6', '#a8a4a0', '#7a9e6c', '#c9a84c', '#d4634a'];
|
|
|
|
return (
|
|
<div className="absolute bottom-20 right-0 md:right-auto md:left-1/2 md:-translate-x-1/2 w-72 bg-card border border-border rounded-xl shadow-2xl z-50 animate-fadeIn overflow-hidden">
|
|
<div className="p-4 border-b border-border bg-muted flex justify-between items-center">
|
|
<h3 className="font-bold text-foreground flex items-center gap-2 text-sm">
|
|
<Activity className="w-4 h-4 text-muted-foreground" /> Visualizer
|
|
</h3>
|
|
<button onClick={onClose}>
|
|
<X className="w-4 h-4 text-muted-foreground hover:text-foreground" />
|
|
</button>
|
|
</div>
|
|
|
|
<div className="p-6 space-y-6">
|
|
{/* Mode */}
|
|
<div>
|
|
<label className="block text-xs font-bold text-muted-foreground uppercase mb-2">
|
|
Display Mode
|
|
</label>
|
|
<div className="grid grid-cols-2 gap-2">
|
|
{['waveform', 'spectrogram', 'bars', 'off'].map((mode) => (
|
|
<button
|
|
key={mode}
|
|
onClick={() => updateSetting('mode', mode)}
|
|
className={`px-2 py-1.5 rounded text-xs font-bold capitalize transition-all border ${visualizerSettings.mode === mode ? 'bg-primary/10 border-primary text-primary' : 'bg-muted border-transparent text-muted-foreground hover:text-foreground'}`}
|
|
>
|
|
{mode}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Sensitivity */}
|
|
<div>
|
|
<div className="flex justify-between text-xs text-muted-foreground mb-1">
|
|
<span>Sensitivity</span>
|
|
<span>{visualizerSettings.sensitivity}%</span>
|
|
</div>
|
|
<input
|
|
type="range"
|
|
min="0"
|
|
max="100"
|
|
value={visualizerSettings.sensitivity}
|
|
onChange={(e) =>
|
|
updateSetting('sensitivity', Number(e.target.value))
|
|
}
|
|
className="w-full h-1 bg-muted rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:bg-primary [&::-webkit-slider-thumb]:rounded-full"
|
|
/>
|
|
</div>
|
|
|
|
{/* Color */}
|
|
<div>
|
|
<label className="block text-xs font-bold text-muted-foreground uppercase mb-2">
|
|
Accent Color
|
|
</label>
|
|
<div className="flex gap-4">
|
|
{colors.map((c) => (
|
|
<div
|
|
key={c}
|
|
onClick={() => updateSetting('color', c)}
|
|
className={`w-6 h-6 rounded-full cursor-pointer transition-opacity hover:opacity-80 ${visualizerSettings.color === c ? 'ring-2 ring-white ring-offset-2 ring-offset-background' : ''}`}
|
|
style={{ backgroundColor: c }}
|
|
></div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|