settings and invitees dialogs in toolbar
This commit is contained in:
parent
a5e6a4644d
commit
dc98da5c58
|
|
@ -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 (
|
||||
<Modal isOpen={show} toggle={onToggle} modalClassName="theme-modal" contentClassName="border">
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<ModalHeader toggle={onToggle} className="bg-light d-flex flex-between-center border-bottom-0">
|
||||
Invite to Session
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<JKFriendsAutoComplete friends={availableFriends} onSelect={handleOnSelect} />
|
||||
{invitees.length > 0 && <JKSessionInviteesChips invitees={invitees} removeInvitee={removeInvitee} />}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="secondary" onClick={onToggle} disabled={loading}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button color="primary" type="submit" disabled={loading}>
|
||||
{loading ? 'Sending...' : 'Send'}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
export default JKSessionInviteModal;
|
||||
|
|
@ -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 (
|
||||
<Card>
|
||||
{!isConnected && <div className='d-flex align-items-center'>Connecting to backend...</div>}
|
||||
<FalconCardHeader title={`Session ${currentSessionIdRef.current}`} titleClass="font-weight-bold">
|
||||
<FalconCardHeader title="Session" titleClass="font-weight-bold">
|
||||
</FalconCardHeader>
|
||||
|
||||
<CardHeader className="bg-light border-bottom border-top py-2 border-3">
|
||||
<div className="d-flex flex-nowrap overflow-auto" style={{ gap: '0.5rem' }}>
|
||||
<Button className='btn-custom-outline' outline size="md">Settings</Button>
|
||||
<Button className='btn-custom-outline' outline size="md">Invite</Button>
|
||||
<Button className='btn-custom-outline' outline size="md" onClick={() => setShowSettingsModal(true)}>Settings</Button>
|
||||
<Button className='btn-custom-outline' outline size="md" onClick={() => setShowInviteModal(true)}>Invite</Button>
|
||||
<Button className='btn-custom-outline' outline size="md">Volume</Button>
|
||||
<Button className='btn-custom-outline' outline size="md">Video</Button>
|
||||
<Button className='btn-custom-outline' outline size="md">Record</Button>
|
||||
|
|
@ -461,7 +504,7 @@ const JKSessionScreen = () => {
|
|||
<div className='sessionMix'>
|
||||
<h5>Session Mix</h5>
|
||||
<div className='d-flex' style={{ gap: '0.5rem' }}>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -567,8 +610,94 @@ const JKSessionScreen = () => {
|
|||
<strong>Last Error:</strong> {lastError ? lastError.message : 'None'}
|
||||
</div>
|
||||
</div>
|
||||
<div className='row mt-2'>
|
||||
<div className='col-md-12'>
|
||||
<strong>Current Session:</strong> {JSON.stringify(currentSession)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
|
||||
<JKSessionSettingsModal
|
||||
isOpen={showSettingsModal}
|
||||
toggle={() => 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);
|
||||
}
|
||||
|
||||
}}
|
||||
/>
|
||||
|
||||
<JKSessionInviteModal
|
||||
currentSession={currentSession}
|
||||
show={showInviteModal}
|
||||
size="lg"
|
||||
onToggle={() => 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);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Modal isOpen={isOpen} toggle={handleCancel} modalClassName="theme-modal" contentClassName="border">
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<ModalHeader toggle={handleCancel} className="bg-light d-flex flex-between-center border-bottom-0">
|
||||
Session Settings
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<FormGroup>
|
||||
<Label className="fs-0" for="privacySelect">
|
||||
Access
|
||||
</Label>
|
||||
<Input
|
||||
type="select"
|
||||
aria-label="Session Privacy"
|
||||
name="privacy"
|
||||
value={privacy}
|
||||
onChange={e => setPrivacy(e.target.value)}
|
||||
data-testid="session-privacy"
|
||||
>
|
||||
<option value={SESSION_PRIVACY_MAP['public']}>{t('new.privacy_opt_public', { ns: 'sessions' })}</option>
|
||||
<option value={SESSION_PRIVACY_MAP['private_invite']}>
|
||||
{t('new.privacy_opt_private_invite', { ns: 'sessions' })}
|
||||
</option>
|
||||
<option value={SESSION_PRIVACY_MAP['private_approve']}>
|
||||
{t('new.privacy_opt_private_approve', { ns: 'sessions' })}
|
||||
</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label className="fs-0" for="descriptionTextarea">
|
||||
Description
|
||||
</Label>
|
||||
<Input
|
||||
type="textarea"
|
||||
name="description"
|
||||
id="descriptionTextarea"
|
||||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
rows={4}
|
||||
disabled={loading}
|
||||
/>
|
||||
</FormGroup>
|
||||
</ModalBody>
|
||||
<ModalFooter className="bg-light border-top-0">
|
||||
<Button color="secondary" onClick={handleCancel} disabled={loading}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button color="primary" type="submit" disabled={loading}>
|
||||
{loading ? 'Saving...' : 'Save'}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default JKSessionSettingsModal;
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
>
|
||||
<option value={sessionPrivacyMap['public']}>{t('new.privacy_opt_public', { ns: 'sessions' })}</option>
|
||||
<option value={sessionPrivacyMap['private_invite']}>
|
||||
<option value={SESSION_PRIVACY_MAP['public']}>{t('new.privacy_opt_public', { ns: 'sessions' })}</option>
|
||||
<option value={SESSION_PRIVACY_MAP['private_invite']}>
|
||||
{t('new.privacy_opt_private_invite', { ns: 'sessions' })}
|
||||
</option>
|
||||
<option value={sessionPrivacyMap['private_approve']}>
|
||||
<option value={SESSION_PRIVACY_MAP['private_approve']}>
|
||||
{t('new.privacy_opt_private_approve', { ns: 'sessions' })}
|
||||
</option>
|
||||
</Input>
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<CurrentSessionContext.Provider value={{
|
||||
currentSession,
|
||||
|
|
|
|||
|
|
@ -398,4 +398,16 @@ export const LATENCY = {
|
|||
UNACCEPTABLE: { description: "HIGH", style: "latency-poor", min: 100, max: 10000000 },
|
||||
UNKNOWN: { description: "UNKNOWN", style: "latency-unknown", min: -2, max: -2 },
|
||||
FAILED: { description: "N/A", style: "latency-failed", min: -3, max: -3 }
|
||||
};
|
||||
|
||||
// export const SESSION_ACCESS_LEVELS = {
|
||||
// RSVP_ONLY: 'rsvp-only',
|
||||
// MUSICIANS_APPROVAL: 'musicians-approval',
|
||||
// MUSICIANS: 'musicians',
|
||||
// }
|
||||
|
||||
export const SESSION_PRIVACY_MAP = {
|
||||
public: 1,
|
||||
private_invite: 2,
|
||||
private_approve: 3
|
||||
};
|
||||
|
|
@ -824,19 +824,6 @@ export const updatePayment = (options = {}) => {
|
|||
});
|
||||
};
|
||||
|
||||
// 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));
|
||||
});
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}, []);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
<td
|
||||
|
|
|
|||
Loading…
Reference in New Issue