diff --git a/jam-ui/src/components/client/JKSessionInviteModal.js b/jam-ui/src/components/client/JKSessionInviteModal.js new file mode 100644 index 000000000..452b6cbe1 --- /dev/null +++ b/jam-ui/src/components/client/JKSessionInviteModal.js @@ -0,0 +1,71 @@ +import React, { useState, useEffect } from 'react'; +import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Form } from 'reactstrap'; +import JKModalDialog from '../common/JKModalDialog'; +import JKFriendsAutoComplete from '../people/JKFriendsAutoComplete'; +import JKSessionInviteesChips from '../people/JKSessionInviteesChips'; +import { useTranslation } from 'react-i18next'; + + +//TODO: show already invited friends as chips and prevent re-inviting them +const JKSessionInviteModal = ({ currentSession, show, onToggle, friends, initialInvitees = [], onSubmit, loading }) => { + const { t } = useTranslation(); + const [availableFriends, setAvailableFriends] = useState([]); + const [invitees, setInvitees] = useState([]); + + useEffect(() => { + const filteredFriends = friends.filter(f => !initialInvitees.some(i => i.id === f.id)); + setAvailableFriends(filteredFriends); + setInvitees(initialInvitees); + }, [friends, initialInvitees, show]); + + const handleOnSelect = submittedItems => { + updateSessionInvitations(submittedItems); + }; + + const updateSessionInvitations = submittedInvitees => { + const updatedInvitees = Array.from(new Set([...invitees, ...submittedInvitees])); + setInvitees(updatedInvitees); + + const friendIds = submittedInvitees.map(si => si.id); + const updatedFriends = availableFriends.filter(f => !friendIds.includes(f.id)); + setAvailableFriends(updatedFriends); + }; + + const removeInvitee = invitee => { + const updatedInvitees = invitees.filter(i => i.id !== invitee.id); + setInvitees(updatedInvitees); + const updatedFriends = [...availableFriends, invitee]; + setAvailableFriends(updatedFriends); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + onSubmit(invitees); + onToggle(); + }; + + return ( + + + + Invite to Session + + + + {invitees.length > 0 && } + + + + Cancel + + + {loading ? 'Sending...' : 'Send'} + + + + + ); + +}; + +export default JKSessionInviteModal; diff --git a/jam-ui/src/components/client/JKSessionScreen.js b/jam-ui/src/components/client/JKSessionScreen.js index 7c2da88e8..9e4d7f595 100644 --- a/jam-ui/src/components/client/JKSessionScreen.js +++ b/jam-ui/src/components/client/JKSessionScreen.js @@ -1,5 +1,5 @@ // jam-ui/src/components/client/JKSessionScreen.js -import React, { useEffect, useContext, useState, memo } from 'react' +import React, { useEffect, useContext, useState, memo, useMemo } from 'react' import { useParams } from 'react-router-dom'; //import useJamServer, { ConnectionStatus } from '../../hooks/useJamServer' @@ -14,8 +14,9 @@ import { useCurrentSessionContext } from '../../context/CurrentSessionContext.js import { useJamServerContext } from '../../context/JamServerContext.js'; import { useJamKazamApp } from '../../context/JamKazamAppContext.js'; import { useMixersContext } from '../../context/MixersContext.js'; +import { useAuth } from '../../context/UserAuth'; -import { getSessionHistory, getSession, joinSession as joinSessionRest } from '../../helpers/rest'; +import { getSessionHistory, getSession, joinSession as joinSessionRest, updateSessionSettings, getFriends } from '../../helpers/rest'; import { CLIENT_ROLE } from '../../helpers/globals'; import { MessageType } from '../../helpers/MessageFactory.js'; @@ -23,10 +24,15 @@ import { MessageType } from '../../helpers/MessageFactory.js'; import { Alert, Col, Row, Button, Card, CardBody, Modal, ModalHeader, ModalBody, ModalFooter, CardHeader, Badge } from 'reactstrap'; import FalconCardHeader from '../common/FalconCardHeader'; import SessionTrackVU from './SessionTrackVU.js'; +import JKSessionSettingsModal from './JKSessionSettingsModal.js'; +import JKSessionInviteModal from './JKSessionInviteModal.js'; +import { SESSION_PRIVACY_MAP } from '../../helpers/globals.js'; +import { toast } from 'react-toastify'; const JKSessionScreen = () => { const logger = console; // Replace with another logging mechanism if needed const app = useJamKazamApp(); + const { currentUser } = useAuth(); const { guardAgainstInvalidConfiguration, @@ -66,6 +72,20 @@ const JKSessionScreen = () => { const [myTracks, setMyTracks] = useState([]); const [mixers, setMixers] = useState([]); + //state for settings modal + const [showSettingsModal, setShowSettingsModal] = useState(false); + const [settingsLoading, setSettingsLoading] = useState(false); + + //state for invite modal + const [friends, setFriends] = useState([]); + const [showInviteModal, setShowInviteModal] = useState(false); + const [sessionInvitees, setSessionInvitees] = useState([]); + const [inviteLoading, setInviteLoading] = useState(false); + + //state for volume level modal + const [showVolumeModal, setShowVolumeModal] = useState(false); + const [volumeLevel, setVolumeLevel] = useState(100); + useEffect(() => { if (!isConnected || !jamClient) return; console.debug("JKSessionScreen: -DEBUG- isConnected changed to true"); @@ -322,6 +342,11 @@ const JKSessionScreen = () => { const refreshCurrentSession = sessionModel.refreshCurrentSession; const updateSession = sessionModel.updateSession; + const musicianAccess = useMemo(() => { + if (!currentSession) return null; + return sessionModel.getMusicianAccess(); + }, [currentSession]); + // useEffect(() => { // if (!isConnected) return; // // validate session by fetching the session from the server @@ -409,16 +434,34 @@ const JKSessionScreen = () => { setMixers(updatedMixers); }, [mixerHelper.myTracks]) + useEffect(() => { + fetchFriends(); + }, []); + + const fetchFriends = () => { + if (currentUser) { + getFriends(currentUser.id) + .then(resp => { + if (resp.ok) { + return resp.json(); + } + }) + .then(data => { + setFriends(data); + }); + } + }; + return ( {!isConnected && Connecting to backend...} - + - Settings - Invite + setShowSettingsModal(true)}>Settings + setShowInviteModal(true)}>Invite Volume Video Record @@ -461,7 +504,7 @@ const JKSessionScreen = () => { Session Mix - + @@ -567,8 +610,94 @@ const JKSessionScreen = () => { Last Error: {lastError ? lastError.message : 'None'} + + + Current Session: {JSON.stringify(currentSession)} + + + + setShowSettingsModal(!showSettingsModal)} + currentSession={{ ...currentSession, privacy: musicianAccess }} + loading={settingsLoading} + onSave={async (payload) => { + console.log('Session settings :', payload); + try { + setSettingsLoading(true); + + switch (parseInt(payload.privacy)) { + case SESSION_PRIVACY_MAP['public']: + payload.musician_access = true; + payload.approval_required = false; + break; + case SESSION_PRIVACY_MAP['private_approve']: + payload.musician_access = true; + payload.approval_required = true; + break; + case SESSION_PRIVACY_MAP['private_invite']: + payload.musician_access = false; + payload.approval_required = false; + break; + default: + break; + } + + const response = await updateSessionSettings({ + id: currentSessionIdRef.current, + ...payload + }); + const data = await response.json(); + console.log('Updated session settings response:', data); + setCurrentSession(prev => ({ ...prev, ...data })); + setShowSettingsModal(false); + toast.success('Session settings updated successfully'); + } catch (error) { + console.error('Error updating session settings:', error); + toast.error('Failed to update session settings'); + } finally { + setSettingsLoading(false); + } + + }} + /> + + setShowInviteModal(false)} + friends={friends} + initialInvitees={sessionInvitees} + loading={inviteLoading} + onSubmit={async (invitees) => { + setSessionInvitees(invitees); + console.log('Submitted invitees:', invitees); + const inviteeIds = invitees.map(i => i.id) + const payload = { + inviteeIds: inviteeIds.join() + }; + try { + setInviteLoading(true); + const response = await updateSessionSettings({ + id: currentSessionIdRef.current, + ...payload + }); + const data = await response.json(); + console.log('Updated session settings response:', data); + setCurrentSession(prev => ({ ...prev, ...data })); + setShowInviteModal(false); + toast.success('Invitations sent successfully'); + } catch (error) { + console.error('Error updating session settings:', error); + toast.error('Failed to send invitations'); + } finally { + setInviteLoading(false); + } + }} + /> ) } diff --git a/jam-ui/src/components/client/JKSessionSettingsModal.js b/jam-ui/src/components/client/JKSessionSettingsModal.js new file mode 100644 index 000000000..0f600ff9c --- /dev/null +++ b/jam-ui/src/components/client/JKSessionSettingsModal.js @@ -0,0 +1,101 @@ +import React, { useState, useEffect } from 'react'; +import { + Button, + Modal, + ModalHeader, + ModalBody, + ModalFooter, + Form, + FormGroup, + Label, + Input, + Alert +} from 'reactstrap'; +import { SESSION_PRIVACY_MAP } from '../../helpers/globals.js'; +import { useTranslation } from 'react-i18next' + + +const JKSessionSettingsModal = ({ isOpen, toggle, currentSession, onSave, loading }) => { + const [privacy, setPrivacy] = useState(currentSession ? currentSession.privacy : SESSION_PRIVACY_MAP.private_approve); + const [description, setDescription] = useState(currentSession ? currentSession.description : ''); + + const { t } = useTranslation(); + + const handleSubmit = (e) => { + e.preventDefault(); + onSave({ privacy, description }); + }; + + useEffect(() => { + if (isOpen && currentSession) { + setPrivacy(currentSession.privacy || SESSION_PRIVACY_MAP.private_approve); + setDescription(currentSession.description || ''); + } +}, [isOpen, currentSession.privacy, currentSession.description]); + + const handleCancel = () => { + // Reset to original values + // if (currentSession) { + // setPrivacy(currentSession.privacy || SESSION_PRIVACY_MAP.private_approve); + // setDescription(currentSession.description || ''); + // } + toggle(); + }; + + return ( + + + + Session Settings + + + + + Access + + setPrivacy(e.target.value)} + data-testid="session-privacy" + > + {t('new.privacy_opt_public', { ns: 'sessions' })} + + {t('new.privacy_opt_private_invite', { ns: 'sessions' })} + + + {t('new.privacy_opt_private_approve', { ns: 'sessions' })} + + + + + + Description + + setDescription(e.target.value)} + rows={4} + disabled={loading} + /> + + + + + Cancel + + + {loading ? 'Saving...' : 'Save'} + + + + + ); +}; + +export default JKSessionSettingsModal; diff --git a/jam-ui/src/components/page/JKMusicSessionsLobby.js b/jam-ui/src/components/page/JKMusicSessionsLobby.js index d4e152579..4275c8756 100644 --- a/jam-ui/src/components/page/JKMusicSessionsLobby.js +++ b/jam-ui/src/components/page/JKMusicSessionsLobby.js @@ -9,7 +9,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { fetchOnlineMusicians } from '../../store/features/onlineMusiciansSlice'; import { fetchUserLatencies } from '../../store/features/latencySlice'; import { useAuth } from '../../context/UserAuth'; -import { sessionPrivacyMap } from '../../config'; +import { SESSION_PRIVACY_MAP } from '../../helpers/globals.js'; import jkCustomUrlScheme from '../../helpers/jkCustomUrlScheme'; import useNativeAppCheck from '../../hooks/useNativeAppCheck'; import { useNativeApp } from '../../context/NativeAppContext'; @@ -138,7 +138,7 @@ function JKMusicSessionsLobby() { const handleClick = async () => { const payload = { - privacy: sessionPrivacyMap.public, + privacy: SESSION_PRIVACY_MAP.public, description: t('list.descriptions.public_open_session', { ns: 'sessions' }), inviteeIds: selectedUsers }; diff --git a/jam-ui/src/components/page/JKNewMusicSession.js b/jam-ui/src/components/page/JKNewMusicSession.js index 36004e4db..e4f3b291b 100644 --- a/jam-ui/src/components/page/JKNewMusicSession.js +++ b/jam-ui/src/components/page/JKNewMusicSession.js @@ -12,7 +12,7 @@ import JKModalDialog from '../common/JKModalDialog'; import useNativeAppCheck from '../../hooks/useNativeAppCheck'; import { useNativeApp } from '../../context/NativeAppContext'; import { useResponsive } from '@farfetch/react-context-responsive'; -import { sessionPrivacyMap } from '../../config'; +import { SESSION_PRIVACY_MAP } from '../../helpers/globals'; import JKAppLaunch from './JKAppLaunch'; import { formatUtcTime } from '../../helpers/utils'; @@ -119,15 +119,15 @@ const JKNewMusicSession = () => { } else { switch (parseInt(payload.privacy)) { - case sessionPrivacyMap['public']: + case SESSION_PRIVACY_MAP['public']: payload.musician_access = true; payload.approval_required = false; break; - case sessionPrivacyMap['private_approve']: + case SESSION_PRIVACY_MAP['private_approve']: payload.musician_access = true; payload.approval_required = true; break; - case sessionPrivacyMap['private_invite']: + case SESSION_PRIVACY_MAP['private_invite']: payload.musician_access = false; payload.approval_required = false; break; @@ -232,11 +232,11 @@ const JKNewMusicSession = () => { onChange={e => setPrivacy(e.target.value)} data-testid="session-privacy" > - {t('new.privacy_opt_public', { ns: 'sessions' })} - + {t('new.privacy_opt_public', { ns: 'sessions' })} + {t('new.privacy_opt_private_invite', { ns: 'sessions' })} - + {t('new.privacy_opt_private_approve', { ns: 'sessions' })} diff --git a/jam-ui/src/config.js b/jam-ui/src/config.js index b3854dd76..7b847899b 100644 --- a/jam-ui/src/config.js +++ b/jam-ui/src/config.js @@ -15,9 +15,9 @@ export const settings = { isNavbarVerticalCollapsed: false, navbarStyle: 'transparent', }; -export const sessionPrivacyMap = { - public: 1, - private_invite: 2, - private_approve: 3 -}; -export default { version, navbarBreakPoint, topNavbarBreakpoint, settings, sessionPrivacyMap }; +// export const sessionPrivacyMap = { +// public: 1, +// private_invite: 2, +// private_approve: 3 +// }; +export default { version, navbarBreakPoint, topNavbarBreakpoint, settings }; diff --git a/jam-ui/src/context/CurrentSessionContext.js b/jam-ui/src/context/CurrentSessionContext.js index a730342d6..53291c3c2 100644 --- a/jam-ui/src/context/CurrentSessionContext.js +++ b/jam-ui/src/context/CurrentSessionContext.js @@ -1,6 +1,6 @@ import React, { createContext, useContext, useState, useRef, useEffect } from 'react'; -//import useMixerHelper from '../hooks/useMixerHelper'; import { useJamServerContext } from './JamServerContext'; +import { getSessionHistory } from '../helpers/rest'; const CurrentSessionContext = createContext(null); @@ -8,16 +8,6 @@ export const CurrentSessionProvider = ({ children }) => { const [currentSession, setCurrentSession] = useState({}); const currentSessionIdRef = useRef(null); - //const mixerHelper = useMixerHelper(); - // const { isConnected, - // connectionStatus, - // reconnectAttempts, - // lastError, - // jamClient, - // server, - // registerMessageCallback, - // ConnectionStatus } = useJamServerContext(); - const inSession = () => { return currentSessionIdRef.current !== null; }; @@ -27,6 +17,20 @@ export const CurrentSessionProvider = ({ children }) => { currentSessionIdRef.current = id; }; + const refreshSession = async () => { + if (currentSessionIdRef.current) { + try { + const sessionData = await getSessionHistory(currentSessionIdRef.current); + const musicSession = await sessionData.json(); + setCurrentSession(musicSession); + } catch (error) { + console.error("Failed to refresh session data:", error); + } + }else { + console.warn("No current session ID set; cannot refresh session data."); + } + }; + return ( { }); }; -// function postUpdateEmail(email, current_password) { - -// var url = "/api/users/" + context.JK.currentUserId + "/update_email"; -// return $.ajax({ -// type: "POST", -// dataType: "json", -// contentType: 'application/json', -// url: url, -// data: JSON.stringify({ update_email: email, current_password: current_password }), -// processData: false -// }); -// } - export const updateEmail = (userId, email, current_password) => { return new Promise((resolve, reject) => { apiFetch(`/users/${userId}/update_email`, { @@ -848,19 +835,6 @@ export const updateEmail = (userId, email, current_password) => { }); } -// function updateUdpReachable(options) { -// var id = getId(options); - -// return $.ajax({ -// type: "POST", -// dataType: "json", -// contentType: 'application/json', -// url: "/api/users/" + id + "/udp_reachable", -// data: JSON.stringify(options), -// processData: false -// }); -// } - export const updateUdpReachable = (options = {}) => { const { id, ...rest } = options; return new Promise((resolve, reject) => { @@ -883,23 +857,6 @@ export const deleteParticipant = (clientId) => { }); } -// function createDiagnostic(options) { -// var data = null; -// try { -// data = JSON.stringify(options) -// } -// catch (e) { -// data = JSON.stringify({data_error: "unable to JSON.stringify debug data:" + e.toString()}) -// } -// return $.ajax({ -// type: "POST", -// url: '/api/diagnostics', -// dataType: "json", -// contentType: 'application/json', -// data: data, -// }); -// } - export const createDiagnostic = (options = {}) => { let data = null; try { @@ -928,3 +885,15 @@ export const putTrackSyncChange = (options = {}) => { .catch(error => reject(error)); }); } + +export const updateSessionSettings = (options = {}) => { + const { id, ...rest } = options; + return new Promise((resolve, reject) => { + apiFetch(`/sessions/${id}`, { + method: 'PUT', + body: JSON.stringify(rest) + }) + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +} \ No newline at end of file diff --git a/jam-ui/src/hooks/useMixerHelper.js b/jam-ui/src/hooks/useMixerHelper.js index c0e8d78e1..f70224a42 100644 --- a/jam-ui/src/hooks/useMixerHelper.js +++ b/jam-ui/src/hooks/useMixerHelper.js @@ -57,7 +57,7 @@ const useMixerHelper = () => { useEffect(() => { allMixersRef.current = allMixers; - console.log("_XDEBUG_ useMixerHelper: allMixersRef updated", allMixersRef.current); + // console.log("_XDEBUG_ useMixerHelper: allMixersRef updated", allMixersRef.current); }, [allMixers]); const getMixer = (mixerId, mode) => { @@ -214,7 +214,7 @@ const useMixerHelper = () => { useEffect(() => { if (Object.keys(allMixers).length > 0 && !isReady.current) { - console.log("useMixerHelper: isReady set to true"); + // console.log("useMixerHelper: isReady set to true"); isReady.current = true; } }, [allMixers, isReady]); @@ -1162,7 +1162,7 @@ const useMixerHelper = () => { const mixer = getMixer(mixerId, mode); if (mixer) { - console.log("useMixerHelper: updateVU mixer", allMixersRef.current, mixerId, mode, mixer); + // console.log("useMixerHelper: updateVU mixer", allMixersRef.current, mixerId, mode, mixer); updateVU3(mixer, leftValue, leftClipping, rightValue, rightClipping); } }, []); diff --git a/jam-ui/src/hooks/useMixerStore.js b/jam-ui/src/hooks/useMixerStore.js index dc2426d5a..107e5619f 100644 --- a/jam-ui/src/hooks/useMixerStore.js +++ b/jam-ui/src/hooks/useMixerStore.js @@ -156,9 +156,9 @@ export default function useMixerStore() { // value is a DB value from -80 to 20. Convert to float from 0.0-1.0 //console.log('handleBridgeCallback@mixers',@mixers) - console.log("mixerHelper.isReady", mixerHelper.isReady.current); + // console.log("mixerHelper.isReady", mixerHelper.isReady.current); if (mixerHelper.isReady.current) { - console.log("mixerHelper handleBridgeCallback: ", mixerId, mode, leftValue, rightValue, leftClipping, rightClipping); + // console.log("mixerHelper handleBridgeCallback: ", mixerId, mode, leftValue, rightValue, leftClipping, rightClipping); mixerHelper.updateVU(mixerId, mode, (leftValue + 80) / 80, leftClipping, (rightValue + 80) / 80, rightClipping); } diff --git a/jam-ui/src/hooks/useSessionHelper.js b/jam-ui/src/hooks/useSessionHelper.js index 9d76ad886..9757a1214 100644 --- a/jam-ui/src/hooks/useSessionHelper.js +++ b/jam-ui/src/hooks/useSessionHelper.js @@ -162,6 +162,16 @@ const useSessionHelper = () => { return currentSession?.id || null; }; + const musicianAccess = () => { + if (!currentSession.musician_access && !currentSession.approval_required) { + return 'only-rsvp'; + }else if(currentSession.musician_access && currentSession.approval_required){ + return 'musicians-approval'; + }else if(currentSession.musician_access && !currentSession.approval_required){ + return 'musicians'; + } + }; + return { inSession: inSessionCheck, participants, @@ -182,7 +192,7 @@ const useSessionHelper = () => { recordedJamTrackName, recordingName, getParticipant, - id + id, }; }, [currentSession, inSession]); diff --git a/jam-ui/src/hooks/useSessionModel.js b/jam-ui/src/hooks/useSessionModel.js index f61031ec4..1dc859c44 100644 --- a/jam-ui/src/hooks/useSessionModel.js +++ b/jam-ui/src/hooks/useSessionModel.js @@ -8,7 +8,7 @@ import useRecordingHelpers from './useRecordingHelpers'; import useSessionUtils from './useSessionUtils'; import { joinSession as joinSessionRest, getSession, deleteParticipant } from '../helpers/rest'; import { MessageType } from '../helpers/MessageFactory'; -import { LATENCY } from '../helpers/globals'; +import { LATENCY, SESSION_PRIVACY_MAP } from '../helpers/globals'; const logger = console; @@ -237,6 +237,18 @@ export default function useSessionModel(app, server, sessionScreen) { return currentSession.user_id; }, [currentSession]); + // Get musician access + const getMusicianAccess = useCallback(() => { + if (!currentSession.musician_access && !currentSession.approval_required) { + return SESSION_PRIVACY_MAP.private_invite; + } else if (currentSession.musician_access && currentSession.approval_required) { + return SESSION_PRIVACY_MAP.private_approve; + } else if (currentSession.musician_access && !currentSession.approval_required) { + return SESSION_PRIVACY_MAP.public; + } + + }, [currentSession]); + // Check if already in session const alreadyInSession = useCallback(() => { let inSession = false; @@ -324,7 +336,7 @@ export default function useSessionModel(app, server, sessionScreen) { }); }, [getUserTracks, isNoInputProfile]); - // Duplicate declaration of SessionPageEnter removed to fix redeclaration error. + // Duplicate declaration of SessionPageEnter removed to fix redeclaration error. // Join session @@ -756,11 +768,11 @@ export default function useSessionModel(app, server, sessionScreen) { const previousMetronomeTracks = previousAllTracks.metronomeTracks; if (!(previousBackingTracks.length === 0 && backingTracksData.length === 0) && - JSON.stringify(previousBackingTracks) !== JSON.stringify(backingTracksData)) { + JSON.stringify(previousBackingTracks) !== JSON.stringify(backingTracksData)) { logger.debug("backing tracks changed", previousBackingTracks, backingTracksData); syncTracks(allTracks); } else if (!(previousMetronomeTracks.length === 0 && metronomeTracks.length === 0) && - JSON.stringify(previousMetronomeTracks) !== JSON.stringify(metronomeTracks)) { + JSON.stringify(previousMetronomeTracks) !== JSON.stringify(metronomeTracks)) { logger.debug("metronome state changed ", previousMetronomeTracks, metronomeTracks); syncTracks(allTracks); } else { @@ -1028,6 +1040,7 @@ export default function useSessionModel(app, server, sessionScreen) { getBackingTrack: () => openBackingTrack, hasShownAudioMediaMixerHelp: () => shownAudioMediaMixerHelp, markShownAudioMediaMixerHelp: () => setShownAudioMediaMixerHelp(true), + getMusicianAccess, // Audio establishment setAudioEstablished, diff --git a/jam-ui/src/hooks/useVuHelpers.js b/jam-ui/src/hooks/useVuHelpers.js index cb6c76e49..36cc4ef58 100644 --- a/jam-ui/src/hooks/useVuHelpers.js +++ b/jam-ui/src/hooks/useVuHelpers.js @@ -108,7 +108,7 @@ export default function useVuHelpers() { const updateVU3 = useCallback( (mixer, leftValue, leftClipping, rightValue, rightClipping) => { const fqId = createQualifiedId(mixer); - logger.debug('useVuHelpers: updateVU3', { fqId, mixer, leftValue, rightValue }); + //logger.debug('useVuHelpers: updateVU3', { fqId, mixer, leftValue, rightValue }); // Update React state for declarative rendering updateVuState(fqId, leftValue, leftClipping); @@ -149,7 +149,7 @@ export default function useVuHelpers() { lightClass += 'vu-off'; } - console.debug('VuMeterComponent render', { i, lightThreshold, isOn, lightClass }); + //console.debug('VuMeterComponent render', { i, lightThreshold, isOn, lightClass }); lights.push(