diff --git a/jam-ui/src/hooks/useMixerHelper.js b/jam-ui/src/hooks/useMixerHelper.js index 5e2906db7..299388bb6 100644 --- a/jam-ui/src/hooks/useMixerHelper.js +++ b/jam-ui/src/hooks/useMixerHelper.js @@ -66,6 +66,7 @@ const useMixerHelper = () => { const dispatch = useDispatch(); const allMixersRef = useRef({}); const previousMyTracksRef = useRef([]); + const previousMixerIdsRef = useRef(null); // Redux selectors - replace all useState calls const chatMixer = useSelector(selectChatMixer); @@ -108,7 +109,7 @@ const useMixerHelper = () => { const currentSession = useSelector(selectActiveSession); const inSession = useSelector(selectInSession); const { jamClient, isConnected, server } = useJamServerContext(); - const { updateVU3 } = useVuContext(); + const { updateVU3, removeVuState } = useVuContext(); const { getParticipant } = useSessionHelper(); const { trackVolumeObject, setTrackVolumeObject } = useGlobalContext(); const faderHelpers = useFaderHelpers(); @@ -316,6 +317,33 @@ const useMixerHelper = () => { } }, [isReadyRedux]); + // Cleanup VU state when mixers are removed + useEffect(() => { + // Skip if not ready or no previous mixers to compare + if (!isReadyRedux) return; + + // Get current mixer IDs from allMixers + const currentMixerIds = new Set(Object.keys(allMixers)); + + // Track previous mixer IDs using a ref + if (!previousMixerIdsRef.current) { + previousMixerIdsRef.current = currentMixerIds; + return; + } + + // Find removed mixers (in previous but not in current) + for (const mixerId of previousMixerIdsRef.current) { + if (!currentMixerIds.has(mixerId)) { + // Mixer was removed - clean up its VU state + removeVuState(mixerId); + console.debug('[useMixerHelper] Cleaned up VU state for removed mixer:', mixerId); + } + } + + // Update previous for next comparison + previousMixerIdsRef.current = currentMixerIds; + }, [allMixers, isReadyRedux, removeVuState]); + const getMixerByTrackId = useCallback((trackId, mode) => { const mixerPair = mixersByTrackId[trackId];