123 lines
3.2 KiB
TypeScript
123 lines
3.2 KiB
TypeScript
|
|
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,
|
||
|
|
};
|
||
|
|
}
|