diff --git a/jam-ui/src/context/VuContext.js b/jam-ui/src/context/VuContext.js index 2ac4b0115..16743ff6a 100644 --- a/jam-ui/src/context/VuContext.js +++ b/jam-ui/src/context/VuContext.js @@ -1,4 +1,5 @@ import React, { createContext, useContext } from 'react'; +import { vuStore } from '../stores/vuStore'; import useVuHelpers from '../hooks/useVuHelpers.js'; const VuContext = createContext(); @@ -6,8 +7,14 @@ const VuContext = createContext(); export const VuProvider = ({ children }) => { const vuHelpers = useVuHelpers(); + // Combine vuHelpers with vuStore for context value + const value = { + ...vuHelpers, + vuStore, + }; + return ( - + {children} ); diff --git a/jam-ui/src/hooks/useVuHelpers.js b/jam-ui/src/hooks/useVuHelpers.js index a021bba47..5201383bd 100644 --- a/jam-ui/src/hooks/useVuHelpers.js +++ b/jam-ui/src/hooks/useVuHelpers.js @@ -1,9 +1,9 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback } from 'react'; +import { vuStore } from '../stores/vuStore'; const logger = console; export default function useVuHelpers() { - const [vuStates, setVuStates] = useState({}); const createQualifiedId = useCallback(mixer => { return (mixer.mode ? 'M' : 'P') + mixer.id; @@ -93,103 +93,15 @@ export default function useVuHelpers() { } }, []); - - - // New React-like VU update function - const updateVuState = useCallback((mixerId, level, clipping = false) => { - setVuStates(prev => ({ - ...prev, - [mixerId]: { level, clipping } - })); - }, []); - - const removeVuState = useCallback((mixerId) => { - setVuStates(prev => { - const newState = { ...prev }; - delete newState[mixerId]; - return newState; - }); - }, []); - - const updateVU3 = useCallback( - (mixer, leftValue, leftClipping, rightValue, rightClipping) => { - const fqId = createQualifiedId(mixer); - //logger.debug('useVuHelpers: updateVU3', { fqId, mixer, leftValue, rightValue }); - - // Update React state for declarative rendering - updateVuState(fqId, leftValue, leftClipping); - }, - [createQualifiedId, updateVuState] - ); - - useEffect(() => { - return () => { - // Cleanup on unmount - setVuStates({}); - }; - }, []); - - // Create a proper React component that can be used outside the hook - function VuMeterComponent({ mixerId, orientation = 'vertical', lightCount = 16, lightWidth = 15, lightHeight = 10 }) { - const vuState = vuStates[mixerId] || { level: 0, clipping: false }; - const { level, clipping } = vuState; - - const lights = []; - for (let i = 0; i < lightCount; i++) { - // Calculate if this light should be on based on the level - const lightThreshold = (lightCount - i) / lightCount; - const isOn = level >= lightThreshold; - - let bgClass = 'vu-bg-secondary'; // Default off state - if (isOn) { - if (clipping) { - bgClass = 'vu-bg-danger'; // Red for clipping - } else { - const positionFromBottom = lightCount - 1 - i; - if (positionFromBottom >= Math.floor(lightCount * 0.75)) { // Red zone (top 25%) - bgClass = 'vu-bg-danger'; - } else if (positionFromBottom >= Math.floor(lightCount * 0.5)) { // Yellow zone (middle 25%) - bgClass = 'vu-bg-warning'; - } else { // Green zone (bottom 50%) - bgClass = 'vu-bg-success'; - } - } - } - - lights.push( -
- ); - } - - return ( -
-
- {lights} -
-
- ); - } - return { - // React-like components and functions - VuMeter: VuMeterComponent, - updateVuState, - removeVuState, - vuStates, + // External store methods (new) + updateVuState: vuStore.updateLevel, + removeVuState: vuStore.removeLevel, + vuStore, // Expose full store for advanced usage // Legacy functions for backward compatibility + createQualifiedId, renderVU, updateVU, - updateVU3 }; }