wip volume change modal
This commit is contained in:
parent
dc98da5c58
commit
c3c0022e7e
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -26,6 +26,7 @@ import FalconCardHeader from '../common/FalconCardHeader';
|
|||
import SessionTrackVU from './SessionTrackVU.js';
|
||||
import JKSessionSettingsModal from './JKSessionSettingsModal.js';
|
||||
import JKSessionInviteModal from './JKSessionInviteModal.js';
|
||||
import JKSessionVolumeModal from './JKSessionVolumeModal.js';
|
||||
import { SESSION_PRIVACY_MAP } from '../../helpers/globals.js';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
|
|
@ -462,7 +463,7 @@ const JKSessionScreen = () => {
|
|||
<div className="d-flex flex-nowrap overflow-auto" style={{ gap: '0.5rem' }}>
|
||||
<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" onClick={() => setShowVolumeModal(true)}>Volume</Button>
|
||||
<Button className='btn-custom-outline' outline size="md">Video</Button>
|
||||
<Button className='btn-custom-outline' outline size="md">Record</Button>
|
||||
<Button className='btn-custom-outline' outline size="md">Broadcast</Button>
|
||||
|
|
@ -698,6 +699,11 @@ const JKSessionScreen = () => {
|
|||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<JKSessionVolumeModal
|
||||
isOpen={showVolumeModal}
|
||||
toggle={() => setShowVolumeModal(!showVolumeModal)}
|
||||
/>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
Button,
|
||||
Modal,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
Input,
|
||||
Row,
|
||||
Col
|
||||
} from 'reactstrap';
|
||||
import SessionTrackVU from './SessionTrackVU';
|
||||
import VolumeSlider from './VolumeSlider'
|
||||
import VuMeter from './VuMeter';
|
||||
import { useMixersContext } from '../../context/MixersContext';
|
||||
|
||||
const JKSessionVolumeModal = ({ isOpen, toggle }) => {
|
||||
const mixerHelper = useMixersContext();
|
||||
const mixers = mixerHelper.myTracks[0]?.mixers;
|
||||
|
||||
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">
|
||||
Volume
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<div className='d-flex' style={{ paddingRight: '0px', marginLeft: '0px' }}>
|
||||
|
||||
<div style={{ borderRight: '1px #ddd solid', marginRight: '1rem' }}>
|
||||
<h6>Music Volume</h6>
|
||||
<div className='d-flex'>
|
||||
<div className='mr-2'>
|
||||
<VolumeSlider initialValue={75} minValue={0} maxValue={100} />
|
||||
</div>
|
||||
{/* <div className='d-flex align-items-end mr-2'>
|
||||
<div className='vu mr-1'>
|
||||
<div className="d-flex flex-column" style={{ height: '140px' }}>
|
||||
<div className="bg-secondary" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-secondary" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='vu'>
|
||||
<div className="d-flex flex-column" style={{ height: '140px' }}>
|
||||
<div className="bg-secondary" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-secondary" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
<VuMeter />
|
||||
<div style={{ marginTop: '1.5rem' }}>
|
||||
<small className="d-block">Use this slider to control the volume of all the music in your session mix.</small>
|
||||
<small className="d-block">This will not affect the volume for other musicians in the session.</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h6>Chat Volume</h6>
|
||||
<div>
|
||||
<div className='d-flex'>
|
||||
<div className='mr-2'>
|
||||
<VolumeSlider initialValue={55} minValue={0} maxValue={100} />
|
||||
</div>
|
||||
<VuMeter />
|
||||
<div style={{ marginTop: '1.5rem' }}>
|
||||
<small className="d-block">Use this slider to control the volume of all the music in your session mix.</small>
|
||||
<small className="d-block">This will not affect the volume for other musicians in the session.</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default JKSessionVolumeModal;
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
.vertical-slider-container {
|
||||
height: 140px; /* Define the height of the slider area */
|
||||
width: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 1px 0;
|
||||
cursor: pointer; /* Makes the container clickable */
|
||||
}
|
||||
|
||||
.horizontal-slider-container {
|
||||
height: 20px; /* Define the height of the slider area */
|
||||
width: 140px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 1px;
|
||||
cursor: pointer; /* Makes the container clickable */
|
||||
}
|
||||
|
||||
.slider-track {
|
||||
width: 8px;
|
||||
height: 100%;
|
||||
background-color: #ddd;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.slider-fill {
|
||||
position: absolute;
|
||||
bottom: 0; /* Fill starts from the bottom */
|
||||
width: 100%;
|
||||
background-color: #8e9090;
|
||||
/* Height is controlled by JavaScript/React */
|
||||
}
|
||||
|
||||
.slider-fill.horizontal {
|
||||
bottom: auto;
|
||||
left: 0; /* Fill starts from the left */
|
||||
height: 100%;
|
||||
width: auto; /* Width controlled by JavaScript/React */
|
||||
}
|
||||
|
||||
.slider-thumb {
|
||||
position: absolute;
|
||||
bottom: 0; /* Thumb starts at the bottom */
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-color: #8e9090;
|
||||
border-radius: 50%;
|
||||
cursor: grab;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
transition: transform 0.1s ease; /* Optional: smooth movement */
|
||||
}
|
||||
|
||||
.slider-thumb.horizontal {
|
||||
bottom: 50%;
|
||||
left: 0; /* Thumb starts at the left */
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.slider-thumb.dragging {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
#slider-value {
|
||||
margin-top: 2px;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
||||
import './VolumeSlider.css'; // We will put the CSS here
|
||||
|
||||
const VolumeSlider = ({ initialValue = 50, minValue = 0, maxValue = 100, orientation = 'vertical' }) => {
|
||||
const [value, setValue] = useState(initialValue);
|
||||
const sliderTrackRef = useRef(null);
|
||||
const sliderThumbRef = useRef(null);
|
||||
const sliderFillRef = useRef(null);
|
||||
|
||||
// Function to calculate and update the slider's position and value
|
||||
const updateSlider = useCallback((clientPos) => {
|
||||
if (!sliderTrackRef.current) return;
|
||||
|
||||
const trackRect = sliderTrackRef.current.getBoundingClientRect();
|
||||
let positionInTrack, trackSize;
|
||||
|
||||
if (orientation === 'vertical') {
|
||||
// Calculate position from the BOTTOM of the track
|
||||
positionInTrack = trackRect.bottom - clientPos;
|
||||
trackSize = trackRect.height;
|
||||
} else {
|
||||
// Calculate position from the LEFT of the track
|
||||
positionInTrack = clientPos - trackRect.left;
|
||||
trackSize = trackRect.width;
|
||||
}
|
||||
|
||||
// Clamp the position within the valid track bounds (0 to trackSize)
|
||||
const clampedPosition = Math.max(0, Math.min(positionInTrack, trackSize));
|
||||
|
||||
// Calculate the percentage and the actual value
|
||||
const percentage = clampedPosition / trackSize;
|
||||
const newValue = Math.round(minValue + (maxValue - minValue) * percentage);
|
||||
|
||||
// Update state and UI
|
||||
setValue(newValue);
|
||||
// Directly manipulating the DOM for immediate visual updates during drag
|
||||
if (orientation === 'vertical') {
|
||||
sliderThumbRef.current.style.bottom = `${clampedPosition}px`;
|
||||
sliderFillRef.current.style.height = `${clampedPosition}px`;
|
||||
} else {
|
||||
sliderThumbRef.current.style.left = `${clampedPosition}px`;
|
||||
sliderFillRef.current.style.width = `${clampedPosition}px`;
|
||||
}
|
||||
}, [minValue, maxValue, orientation]);
|
||||
|
||||
// Mouse Move and Up Handlers (Global listeners)
|
||||
const handleMouseMove = useCallback((e) => {
|
||||
e.preventDefault(); // Prevent text selection
|
||||
updateSlider(orientation === 'vertical' ? e.clientY : e.clientX);
|
||||
}, [updateSlider, orientation]);
|
||||
|
||||
const handleMouseUp = useCallback(() => {
|
||||
window.removeEventListener('mousemove', handleMouseMove);
|
||||
window.removeEventListener('mouseup', handleMouseUp);
|
||||
if (sliderThumbRef.current) {
|
||||
sliderThumbRef.current.classList.remove('dragging');
|
||||
}
|
||||
}, [handleMouseMove]);
|
||||
|
||||
// Mouse Down Handler (Starts the drag)
|
||||
const handleMouseDown = (e) => {
|
||||
e.preventDefault();
|
||||
// Add global listeners when dragging starts
|
||||
window.addEventListener('mousemove', handleMouseMove);
|
||||
window.addEventListener('mouseup', handleMouseUp);
|
||||
if (sliderThumbRef.current) {
|
||||
sliderThumbRef.current.classList.add('dragging');
|
||||
}
|
||||
};
|
||||
|
||||
// Click on Track Handler (Jump to value)
|
||||
const handleTrackClick = (e) => {
|
||||
updateSlider(orientation === 'vertical' ? e.clientY : e.clientX);
|
||||
};
|
||||
|
||||
// Initialize the slider position when the component mounts or values change
|
||||
useEffect(() => {
|
||||
const initialPercentage = (initialValue - minValue) / (maxValue - minValue);
|
||||
if (orientation === 'vertical') {
|
||||
const trackHeight = sliderTrackRef.current.clientHeight;
|
||||
const initialClampedPosition = trackHeight * initialPercentage;
|
||||
sliderThumbRef.current.style.bottom = `${initialClampedPosition}px`;
|
||||
sliderFillRef.current.style.height = `${initialClampedPosition}px`;
|
||||
} else {
|
||||
const trackWidth = sliderTrackRef.current.clientWidth;
|
||||
const initialClampedPosition = trackWidth * initialPercentage;
|
||||
sliderThumbRef.current.style.left = `${initialClampedPosition}px`;
|
||||
sliderFillRef.current.style.width = `${initialClampedPosition}px`;
|
||||
}
|
||||
}, [initialValue, minValue, maxValue, orientation]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div id="slider-value"><small>{value}db</small></div>
|
||||
<div className={orientation === 'vertical' ? "vertical-slider-container" : "horizontal-slider-container"} onClick={handleTrackClick}>
|
||||
<div className="slider-track" ref={sliderTrackRef}>
|
||||
<div className={`slider-fill ${orientation === 'horizontal' ? 'horizontal' : ''}`} ref={sliderFillRef}></div>
|
||||
<div
|
||||
className={`slider-thumb ${orientation === 'horizontal' ? 'horizontal' : ''}`}
|
||||
ref={sliderThumbRef}
|
||||
onMouseDown={handleMouseDown}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VolumeSlider;
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
import React from 'react'
|
||||
|
||||
const VuMeter = () => {
|
||||
return (
|
||||
<div className='d-flex align-items-end mr-2'>
|
||||
<div className='vu mr-1'>
|
||||
<div className="d-flex flex-column" style={{ height: '140px' }}>
|
||||
<div className="bg-secondary" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-secondary" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='vu'>
|
||||
<div className="d-flex flex-column" style={{ height: '140px' }}>
|
||||
<div className="bg-secondary" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-secondary" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-danger" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-warning" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
<div className="bg-success" style={{ height: '10px', width: '15px', marginTop: '1px', borderRadius: '2px' }}></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default VuMeter
|
||||
Loading…
Reference in New Issue