import { ReactiveStore } from "@luna/core"; import { LunaSettings, LunaNumberSetting, LunaSwitchSetting, LunaTextSetting } from "@luna/ui"; import React from "react"; export const settings = await ReactiveStore.getPluginStorage("AudioVisualizer", { barCount: 32, barColor: "#ffffff", barRounding: true, customColors: [] as string[] }); export const Settings = () => { const [barCount, setBarCount] = React.useState(settings.barCount); const [barColor, setBarColor] = React.useState(settings.barColor); const [barRounding, setBarRounding] = React.useState(settings.barRounding); const [showColorPicker, setShowColorPicker] = React.useState(false); const [isAnimatingIn, setIsAnimatingIn] = React.useState(false); const [shouldRender, setShouldRender] = React.useState(false); const [customInput, setCustomInput] = React.useState(settings.barColor); const [customColors, setCustomColors] = React.useState(settings.customColors); const [hoveredColorIndex, setHoveredColorIndex] = React.useState(null); const closeColorPicker = () => { setIsAnimatingIn(false); setTimeout(() => { setShowColorPicker(false); setShouldRender(false); }, 200); // Wait for animation to complete because i need to }; const openColorPicker = () => { setShowColorPicker(true); setShouldRender(true); setTimeout(() => setIsAnimatingIn(true), 10); }; React.useEffect(() => { if (showColorPicker) { setShouldRender(true); setTimeout(() => setIsAnimatingIn(true), 10); } }, [showColorPicker]); // Common color presets for cool points :D const colorPresets = [ "#ffffff", "#ff0000", "#00ff00", "#0000ff", "#ffff00", "#ff00ff", "#00ffff", "#ff8800", "#8800ff", "#0088ff", "#88ff00", "#ff0088", "#00ff88", "#444444", "#888888", "#cccccc", "#1db954", "#e22134", "#1976d2" ]; const updateColor = (color: string) => { setBarColor(color); setCustomInput(color); settings.barColor = color; (window as any).updateAudioVisualizer?.(); }; const addCustomColor = () => { if (customInput) { // Trim whitespace and convert to lowercase const trimmedInput = customInput.trim().toLowerCase(); // Validate hex color format const hexColorRegex = /^#([0-9a-f]{6}|[0-9a-f]{3})$/i; if (hexColorRegex.test(trimmedInput) && !colorPresets.includes(trimmedInput) && !customColors.includes(trimmedInput)) { const newCustomColors = [...customColors, trimmedInput]; setCustomColors(newCustomColors); settings.customColors = newCustomColors; } } }; const removeCustomColor = (colorToRemove: string) => { const newCustomColors = customColors.filter(color => color !== colorToRemove); setCustomColors(newCustomColors); settings.customColors = newCustomColors; // If the removed color was the selected color (reset to white) if (barColor === colorToRemove) { updateColor("#ffffff"); } }; const allColors = [...colorPresets, ...customColors]; return ( { setBarRounding(checked); settings.barRounding = checked; (window as any).updateAudioVisualizer?.(); }} /> { setBarCount(value); settings.barCount = value; (window as any).updateAudioVisualizer?.(); }} /> {/* YUP YOUR EYES WORK... we do be using React code in the settings..*/} {/* I'm not sure if this is a good idea, but it works & looks amazing */} {/* Sorry @Inrixia <3 */}
Bar Color
Color of the visualizer bars
{/* Custom Color Picker Modal */} {shouldRender && ( <> {/* Backdrop */}
{/* Color Picker Panel */}
Choose Color
{/* Color Grid */}
{allColors.map((color, index) => { const isCustomColor = customColors.includes(color); const isHovered = hoveredColorIndex === index; return (
setHoveredColorIndex(index)} onMouseLeave={() => setHoveredColorIndex(null)} > )}
); })}
{/* Custom Hex Input */}
Add Custom Color
setCustomInput(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { updateColor(customInput); addCustomColor(); } }} placeholder="#ffffff" style={{ flex: 1, padding: "8px 12px", borderRadius: "6px", border: "1px solid rgba(255,255,255,0.2)", background: "rgba(255,255,255,0.1)", color: "#fff", fontSize: "14px", fontFamily: "monospace", boxSizing: "border-box" }} />
{/* Close Button (Done) - Also runs when color chosen*/}
)}
); };