wip sesssion screen base functions

This commit is contained in:
Nuwan 2025-12-08 23:28:48 +05:30
parent b2f378e01e
commit baba15693b
5 changed files with 165 additions and 6 deletions

View File

@ -0,0 +1,95 @@
import React, { useState, useEffect } from 'react';
import {
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Button,
Form,
FormGroup,
Label,
Input,
} from 'reactstrap';
import { listInstruments, getInstrumentIcon45, convertClientInstrumentToServer } from '../../helpers/utils';
import { server_to_client_instrument_map } from '../../helpers/globals';
const JKSessionInstrumentModal = ({ isOpen, toggle, currentInstrument, onSave }) => {
const [selectedInstrumentId, setSelectedInstrumentId] = useState(null);
const [instruments, setInstruments] = useState([]);
useEffect(() => {
if (isOpen) {
// Get sorted list of instruments
const instrumentList = listInstruments().sort((a, b) =>
a.description.localeCompare(b.description)
);
setInstruments(instrumentList);
// Find current instrument's client ID
if (currentInstrument) {
const currentMapping = Object.values(server_to_client_instrument_map).find(
mapping => mapping.server_id === currentInstrument
);
if (currentMapping) {
setSelectedInstrumentId(currentMapping.client_id);
}
}
}
}, [isOpen, currentInstrument]);
const handleSave = () => {
if (selectedInstrumentId !== null) {
onSave(selectedInstrumentId);
toggle();
}
};
const handleCancel = () => {
toggle();
};
return (
<Modal isOpen={isOpen} toggle={handleCancel} modalClassName="theme-modal" contentClassName="border" size="md">
<ModalHeader toggle={handleCancel} className="bg-light d-flex flex-between-center border-bottom-0">
Select Instrument
</ModalHeader>
<ModalBody style={{ maxHeight: '400px', overflowY: 'auto' }}>
<Form>
{instruments.map((instrument) => (
<FormGroup key={instrument.id} className="d-flex align-items-center mb-3">
<div className="mr-3">
<img
height="45"
width="45"
src={getInstrumentIcon45(convertClientInstrumentToServer(instrument.id))}
alt={instrument.description}
/>
</div>
<Label check className="flex-grow-1 d-flex align-items-center">
<Input
type="radio"
name="instrument"
value={instrument.id}
checked={selectedInstrumentId === instrument.id}
onChange={() => setSelectedInstrumentId(instrument.id)}
className="mr-2"
/>
{instrument.description}
</Label>
</FormGroup>
))}
</Form>
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={handleCancel}>
Cancel
</Button>
<Button color="primary" onClick={handleSave} disabled={selectedInstrumentId === null}>
Save
</Button>
</ModalFooter>
</Modal>
);
};
export default JKSessionInstrumentModal;

View File

@ -60,7 +60,9 @@
}
.track-instrument {
text-align: center;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 8px;
}

View File

@ -1,17 +1,24 @@
import React, { useState, useEffect } from 'react';
import { useMixersContext } from '../../context/MixersContext';
import { useJamClient } from '../../context/JamClientContext';
import usePanHelpers from '../../hooks/usePanHelpers';
import SessionTrackVU from './SessionTrackVU';
import SessionTrackGain from './SessionTrackGain';
import TrackDiagnostics from './TrackDiagnostics';
import JKSessionInstrumentModal from './JKSessionInstrumentModal';
import { UncontrolledTooltip } from 'reactstrap';
import { getInstrumentName } from '../../helpers/utils';
import { ASSIGNMENT } from '../../helpers/globals';
import './JKSessionMyTrack.css';
const JKSessionMyTrack = ({ track, mixers, hasMixer, name, trackName, instrumentIcon, photoUrl, clientId, connStatsClientId, mode, isChat = false, isRemote = false }) => {
const mixerHelper = useMixersContext();
const jamClient = useJamClient();
const { convertPanToPercent } = usePanHelpers();
const [pan, setPan] = useState(0);
const [showMenu, setShowMenu] = useState(false);
const [showDiagnostics, setShowDiagnostics] = useState(false);
const [showInstrumentModal, setShowInstrumentModal] = useState(false);
useEffect(() => {
if (mixers?.mixer) {
@ -36,6 +43,20 @@ const JKSessionMyTrack = ({ track, mixers, hasMixer, name, trackName, instrument
/>
) : null;
const handleInstrumentClick = () => {
setShowInstrumentModal(true);
};
const handleInstrumentSave = (instrumentId) => {
// For user's own track, use TRACK1
jamClient.TrackSetInstrument(ASSIGNMENT.TRACK1, instrumentId);
setShowInstrumentModal(false);
};
const handleInstrumentModalClose = () => {
setShowInstrumentModal(false);
};
return (
<div className={trackClasses}>
<div className="disabled-track-overlay" />
@ -54,9 +75,27 @@ const JKSessionMyTrack = ({ track, mixers, hasMixer, name, trackName, instrument
>
<img src={photoUrl} alt="avatar" />
</div>
<div className="track-instrument">
<img height="45" src={instrumentIcon} width="45" alt="instrument" />
<div>
remote?: {JSON.stringify(isRemote)}
</div>
<div
className="track-instrument"
id={`instrument-tooltip-${clientId}-${track?.client_track_id || 'chat'}`}
onClick={!isRemote ? handleInstrumentClick : undefined}
style={!isRemote ? { cursor: 'pointer' } : {}}
>
<img height="45" src={instrumentIcon} width="45" alt="instrument" />
{!isRemote && <a href="#" style={{ marginLeft: '8px' }}>vst</a>}
</div>
{isRemote && (
<UncontrolledTooltip
placement="top"
target={`instrument-tooltip-${clientId}-${track?.client_track_id || 'chat'}`}
trigger="hover click"
>
{getInstrumentName(track?.instrument)}
</UncontrolledTooltip>
)}
<div className="track-controls">
<div className="vu-and-gain" style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<SessionTrackVU
@ -94,6 +133,14 @@ const JKSessionMyTrack = ({ track, mixers, hasMixer, name, trackName, instrument
</div>
<br className="clearall" />
</div>
{!isRemote && (
<JKSessionInstrumentModal
isOpen={showInstrumentModal}
toggle={handleInstrumentModalClose}
currentInstrument={track?.instrument}
onSave={handleInstrumentSave}
/>
)}
</div>
);
};

View File

@ -24,7 +24,7 @@ import { getSessionHistory, getSession, joinSession as joinSessionRest, updateSe
import { CLIENT_ROLE, RECORD_TYPE_AUDIO, RECORD_TYPE_BOTH } from '../../helpers/globals';
import { MessageType } from '../../helpers/MessageFactory.js';
import { Alert, Col, Row, Button, Card, CardBody, Modal, ModalHeader, ModalBody, ModalFooter, CardHeader, Badge } from 'reactstrap';
import { Alert, Col, Row, Button, Card, CardBody, Modal, ModalHeader, ModalBody, ModalFooter, CardHeader, Badge, UncontrolledTooltip } from 'reactstrap';
import FalconCardHeader from '../common/FalconCardHeader';
import SessionTrackVU from './SessionTrackVU.js';
import JKSessionMyTrack from './JKSessionMyTrack.js';
@ -36,6 +36,7 @@ import JKSessionVolumeModal from './JKSessionVolumeModal.js';
import JKSessionRecordingModal from './JKSessionRecordingModal.js';
import { SESSION_PRIVACY_MAP } from '../../helpers/globals.js';
import { toast } from 'react-toastify';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const JKSessionScreen = () => {
const logger = console; // Replace with another logging mechanism if needed
@ -575,7 +576,7 @@ const JKSessionScreen = () => {
<CardBody className="pl-4" style={{ backgroundColor: '#edf2f9f5' }}>
<div className='d-flex' style={{ gap: '1rem' }}>
<div className='audioInputs'>
<h5>Audio Inputs</h5>
<h5>Audio Inputs <FontAwesomeIcon icon="question-circle" id="audioInputsTooltip" className="ml-2" style={{cursor: 'pointer'}} /></h5>
<div style={{ borderRight: '1px #ddd solid', paddingRight: '1rem' }}>
<JKSessionAudioInputs
myTracks={myTracks}
@ -593,7 +594,7 @@ const JKSessionScreen = () => {
myTracks={myTracks}
chat={chat}
mixerHelper={mixerHelper}
isRemote={false}
isRemote={true}
/>
<JKSessionRemoteTracks
mixerHelper={mixerHelper}
@ -795,6 +796,13 @@ const JKSessionScreen = () => {
toggle={() => setShowRecordingModal(!showRecordingModal)}
onSubmit={handleRecordingSubmit}
/>
<UncontrolledTooltip target="audioInputsTooltip" trigger="hover click">
<div>
<p>Set the input level of your Audio Inputs for each of your tracks to a healthy level. It's important to set your input level correctly. If your level is set too high, you'll get distortion or clipping of your audio. If set too low, your audio signal will be too weak, which can cause noise and degrade your audio quality when you and others use the session mix to increase your volume in the mix.</p>
<p>For instructions on how to set your Audio Input levels, read <a href="/help/audio-input-levels" target="_blank">this help article</a>.</p>
</div>
</UncontrolledTooltip>
</Card>
)
}

View File

@ -798,6 +798,13 @@ export const getInstrumentIcon45 = (instrument) => {
return instrumentIconMap45["_default"].asset;
};
export const getInstrumentName = (instrument) => {
if (instrument in instrumentIconMap45) {
return instrumentIconMap45[instrument].name;
}
return instrumentIconMap45["_default"].name;
};
export const getInstrumentIcon256 = (instrument) => {
if (instrument in instrumentIconMap256) {
return instrumentIconMap256[instrument].asset;