Files
audio-ui/lib/hooks/useEffectChain.ts

123 lines
3.2 KiB
TypeScript
Raw Permalink Normal View History

2025-11-17 20:27:08 +01:00
import { useState, useCallback, useEffect } from 'react';
import type {
EffectChain,
EffectPreset,
ChainEffect,
EffectParameters,
} from '@/lib/audio/effects/chain';
import {
createEffectChain,
addEffectToChain,
removeEffectFromChain,
toggleEffect,
updateEffectParameters,
reorderEffects,
loadPreset,
} from '@/lib/audio/effects/chain';
const STORAGE_KEY_CHAIN = 'audio-ui-effect-chain';
const STORAGE_KEY_PRESETS = 'audio-ui-effect-presets';
export function useEffectChain() {
const [chain, setChain] = useState<EffectChain>(() => {
if (typeof window === 'undefined') return createEffectChain('Main Chain');
try {
const saved = localStorage.getItem(STORAGE_KEY_CHAIN);
return saved ? JSON.parse(saved) : createEffectChain('Main Chain');
} catch {
return createEffectChain('Main Chain');
}
});
const [presets, setPresets] = useState<EffectPreset[]>(() => {
if (typeof window === 'undefined') return [];
try {
const saved = localStorage.getItem(STORAGE_KEY_PRESETS);
return saved ? JSON.parse(saved) : [];
} catch {
return [];
}
});
// Save chain to localStorage whenever it changes
useEffect(() => {
if (typeof window === 'undefined') return;
try {
localStorage.setItem(STORAGE_KEY_CHAIN, JSON.stringify(chain));
} catch (error) {
console.error('Failed to save effect chain:', error);
}
}, [chain]);
// Save presets to localStorage whenever they change
useEffect(() => {
if (typeof window === 'undefined') return;
try {
localStorage.setItem(STORAGE_KEY_PRESETS, JSON.stringify(presets));
} catch (error) {
console.error('Failed to save presets:', error);
}
}, [presets]);
const addEffect = useCallback((effect: ChainEffect) => {
setChain((prev) => addEffectToChain(prev, effect));
}, []);
const removeEffect = useCallback((effectId: string) => {
setChain((prev) => removeEffectFromChain(prev, effectId));
}, []);
const toggleEffectEnabled = useCallback((effectId: string) => {
setChain((prev) => toggleEffect(prev, effectId));
}, []);
const updateEffect = useCallback(
(effectId: string, parameters: EffectParameters) => {
setChain((prev) => updateEffectParameters(prev, effectId, parameters));
},
[]
);
const reorder = useCallback((fromIndex: number, toIndex: number) => {
setChain((prev) => reorderEffects(prev, fromIndex, toIndex));
}, []);
const clearChain = useCallback(() => {
setChain((prev) => ({ ...prev, effects: [] }));
}, []);
const savePreset = useCallback((preset: EffectPreset) => {
setPresets((prev) => [...prev, preset]);
}, []);
const loadPresetToChain = useCallback((preset: EffectPreset) => {
const loadedChain = loadPreset(preset);
setChain(loadedChain);
}, []);
const deletePreset = useCallback((presetId: string) => {
setPresets((prev) => prev.filter((p) => p.id !== presetId));
}, []);
const importPreset = useCallback((preset: EffectPreset) => {
setPresets((prev) => [...prev, preset]);
}, []);
return {
chain,
presets,
addEffect,
removeEffect,
toggleEffectEnabled,
updateEffect,
reorder,
clearChain,
savePreset,
loadPresetToChain,
deletePreset,
importPreset,
};
}