253 lines
8.0 KiB
JavaScript
253 lines
8.0 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { Table, Row, Col, Input, Button } from 'reactstrap';
|
|
import JKInstrumentIcon from '../profile/JKInstrumentIcon';
|
|
import Select from 'react-select';
|
|
import { useForm, Controller } from 'react-hook-form';
|
|
import { createMixdown } from '../../helpers/rest';
|
|
|
|
const JKCreateCustomMix = ({ jamTrack }) => {
|
|
const [tracks, setTracks] = useState([]);
|
|
//const [selectedTracks, setSelectedTracks] = useState([]);
|
|
|
|
const TEMPO_OPTIONS = [
|
|
{ value: '0', label: 'Original tempo' },
|
|
{ value: '-5', label: 'Slower by 5%' },
|
|
{ value: '-10', label: 'Slower by 10%' },
|
|
{ value: '-15', label: 'Slower by 15%' },
|
|
{ value: '-20', label: 'Slower by 20%' },
|
|
{ value: '-25', label: 'Slower by 25%' },
|
|
{ value: '-30', label: 'Slower by 30%' },
|
|
{ value: '-35', label: 'Slower by 35%' },
|
|
{ value: '-40', label: 'Slower by 40%' },
|
|
{ value: '-45', label: 'Slower by 45%' },
|
|
{ value: '-50', label: 'Slower by 50%' },
|
|
{ value: '-60', label: 'Slower by 60%' },
|
|
{ value: '-70', label: 'Slower by 70%' },
|
|
{ value: '-80', label: 'Slower by 80%' },
|
|
{ value: '5', label: 'Faster by 5%' },
|
|
{ value: '10', label: 'Faster by 10%' },
|
|
{ value: '15', label: 'Faster by 15%' },
|
|
{ value: '20', label: 'Faster by 20%' },
|
|
{ value: '30', label: 'Faster by 30%' },
|
|
{ value: '40', label: 'Faster by 40%' },
|
|
{ value: '50', label: 'Faster by 50%' }
|
|
];
|
|
|
|
const PITCH_OPTIONS = [
|
|
{ value: '0', label: 'Original pitch' },
|
|
{ value: '-1', label: 'Down 1 semitone' },
|
|
{ value: '-2', label: 'Down 2 semitone' },
|
|
{ value: '-3', label: 'Down 3 semitone' },
|
|
{ value: '-4', label: 'Down 4 semitone' },
|
|
{ value: '-5', label: 'Down 5 semitone' },
|
|
{ value: '-6', label: 'Down 6 semitone' },
|
|
{ value: '-7', label: 'Down 7 semitone' },
|
|
{ value: '-8', label: 'Down 8 semitone' },
|
|
{ value: '-9', label: 'Down 9 semitone' },
|
|
{ value: '-10', label: 'Down 10 semitone' },
|
|
{ value: '-11', label: 'Down 11 semitone' },
|
|
{ value: '-12', label: 'Down 12 semitone' },
|
|
{ value: '1', label: 'Up 1 semitone' },
|
|
{ value: '2', label: 'Up 2 semitone' },
|
|
{ value: '3', label: 'Up 3 semitone' },
|
|
{ value: '4', label: 'Up 4 semitone' },
|
|
{ value: '5', label: 'Up 5 semitone' },
|
|
{ value: '6', label: 'Up 6 semitone' },
|
|
{ value: '7', label: 'Up 7 semitone' },
|
|
{ value: '8', label: 'Up 8 semitone' },
|
|
{ value: '9', label: 'Up 9 semitone' },
|
|
{ value: '10', label: 'Up 10 semitone' },
|
|
{ value: '11', label: 'Up 11 semitone' },
|
|
{ value: '12', label: 'Up 12 semitone' }
|
|
];
|
|
|
|
const {
|
|
control,
|
|
handleSubmit,
|
|
formState: { errors },
|
|
setValue,
|
|
getValues
|
|
} = useForm({
|
|
defaultValues: {
|
|
mixName: '',
|
|
tempo: {
|
|
value: '0',
|
|
label: 'Original tempo'
|
|
},
|
|
pitch: {
|
|
value: '0',
|
|
label: 'Original pitch'
|
|
},
|
|
mixdownTracks: []
|
|
}
|
|
});
|
|
const onSubmit = data => {
|
|
console.log('data', data);
|
|
const _tracks = [];
|
|
let countIn = false;
|
|
const selectedTracks = getValues('mixdownTracks');
|
|
tracks.forEach(track => {
|
|
const muted = selectedTracks.includes(track.id);
|
|
if (track.id === 'count-in') {
|
|
if (countIn === false) {
|
|
countIn = !muted;
|
|
}
|
|
} else {
|
|
_tracks.push({
|
|
id: track.id,
|
|
mute: selectedTracks.includes(track.id)
|
|
});
|
|
}
|
|
});
|
|
|
|
setValue('mixdownTracks', _tracks);
|
|
|
|
const mixData = {
|
|
jamTrackID: jamTrack.id,
|
|
name: data.mixName,
|
|
settings: { speed: data.tempo.value, pitch: data.pitch.value, 'count-in': countIn, tracks: _tracks }
|
|
};
|
|
|
|
console.log('mixData', mixData);
|
|
|
|
createMixdown(mixData)
|
|
.then(response => {
|
|
console.log('mixdown created', response);
|
|
//TODO: add this mixdown to global state of jamtrack mixdowns
|
|
})
|
|
.catch(error => {
|
|
console.error('mixdown create error', error);
|
|
});
|
|
};
|
|
|
|
const toggleTrack = e => {
|
|
const trackId = e.target.value;
|
|
const selectedTracks = getValues('mixdownTracks');
|
|
if (selectedTracks.includes(trackId)) {
|
|
//setSelectedTracks(selectedTracks.filter(track => track !== trackId));
|
|
setValue('mixdownTracks', selectedTracks.filter(track => track !== trackId));
|
|
} else {
|
|
//setSelectedTracks([...selectedTracks, trackId]);
|
|
setValue('mixdownTracks', [...selectedTracks, trackId]);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (jamTrack) {
|
|
setTracks(jamTrack.tracks.filter(track => track.track_type === 'Track' || track.track_type === 'Click'));
|
|
}
|
|
}, [jamTrack]);
|
|
|
|
const trackName = track => {
|
|
if (track.track_type === 'Track' || track.track_type === 'Click') {
|
|
if (track.track_type === 'Click') {
|
|
return 'Clicktrack';
|
|
} else if (track.instrument) {
|
|
const instrumentDescription = track.instrument.description;
|
|
let part = '';
|
|
if (track.part && track.part !== instrumentDescription) {
|
|
part = `(${track.part})`;
|
|
}
|
|
return `${instrumentDescription} ${part}`;
|
|
}
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<p>
|
|
Mute any tracks you like. Adjust the pitch or tempo of playback. Then give your mix a descriptive name, and
|
|
click the Create Mix button. It will take few minutes for us to create your custom mix.
|
|
</p>
|
|
|
|
<form onSubmit={handleSubmit(onSubmit)}>
|
|
<Row>
|
|
<Col>
|
|
<Table striped bordered className="fs--1">
|
|
<thead className="bg-200 text-900">
|
|
<tr>
|
|
<th>Tracks {tracks.length > 0 && <>({tracks.length})</>}</th>
|
|
<th>Mute</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{tracks &&
|
|
tracks.map((track, index) => (
|
|
<tr key={index}>
|
|
<td>
|
|
<JKInstrumentIcon instrumentId={track.instrumentId} instrumentName={trackName(track)} />
|
|
<span className="ml-1">{trackName(track)}</span>
|
|
</td>
|
|
<td>
|
|
<input type="checkbox" value={track.id} onClick={toggleTrack} />
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</Table>
|
|
<Controller
|
|
name="mixdownTracks"
|
|
control={control}
|
|
rules={{
|
|
required: 'Select at least one track to create a mix'
|
|
}}
|
|
render={({ field }) => <Input type='hidden' {...field} />}
|
|
/>
|
|
{errors.mixdownTracks && (
|
|
<div className="text-danger">
|
|
<small>{errors.mixdownTracks.message}</small>
|
|
</div>
|
|
)}
|
|
</Col>
|
|
</Row>
|
|
|
|
<Row className="mb-1">
|
|
<Col>Tempo</Col>
|
|
<Col>
|
|
<Controller
|
|
name="tempo"
|
|
control={control}
|
|
render={({ field }) => <Select {...field} options={TEMPO_OPTIONS} />}
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
<Row className="mb-1">
|
|
<Col>Pitch</Col>
|
|
<Col>
|
|
<Controller
|
|
name="pitch"
|
|
control={control}
|
|
render={({ field }) => <Select {...field} options={PITCH_OPTIONS} />}
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
<Row className="mb-1">
|
|
<Col>Mix Name</Col>
|
|
<Col>
|
|
<Controller
|
|
name="mixName"
|
|
control={control}
|
|
rules={{
|
|
required: 'Mix name is required'
|
|
}}
|
|
render={({ field }) => <Input {...field} />}
|
|
/>
|
|
{errors.mixName && (
|
|
<div className="text-danger">
|
|
<small>{errors.mixName.message}</small>
|
|
</div>
|
|
)}
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col>
|
|
<Button>Create Mix</Button>
|
|
</Col>
|
|
</Row>
|
|
</form>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default JKCreateCustomMix;
|