wip jamtrack page creating and playing custom jamtracks
This commit is contained in:
parent
08fafbf2de
commit
c3563a9197
|
|
@ -160,6 +160,7 @@ function JKDashboardMain() {
|
||||||
registerFriendRequest();
|
registerFriendRequest();
|
||||||
registerFriendRequestAccepted();
|
registerFriendRequestAccepted();
|
||||||
registerChatMessageCallback();
|
registerChatMessageCallback();
|
||||||
|
registerSubscriptionCallback();
|
||||||
|
|
||||||
scriptLoaded.current = true;
|
scriptLoaded.current = true;
|
||||||
};
|
};
|
||||||
|
|
@ -242,6 +243,14 @@ function JKDashboardMain() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const registerSubscriptionCallback = () => {
|
||||||
|
window.JK.JamServer.registerMessageCallback(window.JK.MessageType.SUBSCRIPTION_MESSAGE, function(header, payload) {
|
||||||
|
console.log('registerSubscriptionCallback payload', payload);
|
||||||
|
console.log('registerSubscriptionCallback header', header);
|
||||||
|
handleSubscriptionMessage(payload);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleNotification = (payload, type) => {
|
const handleNotification = (payload, type) => {
|
||||||
console.log('handleNotification', payload, type);
|
console.log('handleNotification', payload, type);
|
||||||
const notification = {
|
const notification = {
|
||||||
|
|
@ -266,6 +275,10 @@ function JKDashboardMain() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSubscriptionMessage = payload => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
useScript(`${process.env.REACT_APP_CLIENT_BASE_URL}/client_scripts`, initJKScripts);
|
useScript(`${process.env.REACT_APP_CLIENT_BASE_URL}/client_scripts`, initJKScripts);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,30 @@
|
||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { Table, Row, Col, Input, Button } from 'reactstrap';
|
import { Table, Row, Col, Input, Button } from 'reactstrap';
|
||||||
import Select from 'react-select';
|
import Select from 'react-select';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller, set } from 'react-hook-form';
|
||||||
import { createMyMixdown, addMixdown } from '../../store/features/jamTrackSlice';
|
import {
|
||||||
|
createMyMixdown,
|
||||||
|
enqueueMyMixdown,
|
||||||
|
addWatchedMixdown,
|
||||||
|
removeWatchedMixdown
|
||||||
|
} from '../../store/features/jamTrackSlice';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { Scrollbar } from 'react-scrollbars-custom';
|
import { Scrollbar } from 'react-scrollbars-custom';
|
||||||
|
import { SAMPLE_RATE } from '../../helpers/jamTracks';
|
||||||
|
import JKModalDialog from '../common/JKModalDialog';
|
||||||
|
import { createAlert } from '../../helpers/rest';
|
||||||
|
import { useAuth } from '../../context/UserAuth';
|
||||||
|
|
||||||
const JKCreateCustomMix = () => {
|
const JKCreateCustomMix = () => {
|
||||||
const MAX_MIXDOWNS = 5;
|
const MAX_MIXDOWNS = 5;
|
||||||
|
|
||||||
const [tracks, setTracks] = useState([]);
|
const [tracks, setTracks] = useState([]);
|
||||||
const [mixdowns, setMixdowns] = useState([]);
|
|
||||||
const [selectedTracks, setSelectedTracks] = useState([]);
|
const [selectedTracks, setSelectedTracks] = useState([]);
|
||||||
|
const [showQueueTime, setShowQueueTime] = useState(false);
|
||||||
|
const [enqueueTimeMessage, setEnqueueTimeMessage] = useState('');
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const scrollbar = useRef();
|
const scrollbar = useRef();
|
||||||
|
const { currentUser} = useAuth();
|
||||||
|
|
||||||
const TEMPO_OPTIONS = [
|
const TEMPO_OPTIONS = [
|
||||||
{ value: '0', label: 'Original tempo' },
|
{ value: '0', label: 'Original tempo' },
|
||||||
|
|
@ -68,7 +79,12 @@ const JKCreateCustomMix = () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
||||||
|
const mixdowns = useSelector(state => state.jamTrack.mixdowns);
|
||||||
const newMixdownLoadingStatus = useSelector(state => state.jamTrack.newMixdownLoadingStatus);
|
const newMixdownLoadingStatus = useSelector(state => state.jamTrack.newMixdownLoadingStatus);
|
||||||
|
const awaitingMixdown = useSelector(state => state.jamTrack.awaitingMixdown);
|
||||||
|
const enqueuedMixdown = useSelector(state => state.jamTrack.enqueuedMixdown);
|
||||||
|
const enqueuedMixdowns = useSelector(state => state.jamTrack.enqueuedMixdowns);
|
||||||
|
const watchedMixdowns = useSelector(state => state.jamTrack.watchedMixdowns);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
|
|
@ -114,11 +130,16 @@ const JKCreateCustomMix = () => {
|
||||||
const mixData = {
|
const mixData = {
|
||||||
jamTrackID: jamTrack.id,
|
jamTrackID: jamTrack.id,
|
||||||
name: data.mixName,
|
name: data.mixName,
|
||||||
settings: { speed: parseInt(data.tempo.value), pitch: parseInt(data.pitch.value), 'count-in': countIn, tracks: _tracks }
|
settings: {
|
||||||
|
speed: parseInt(data.tempo.value),
|
||||||
|
pitch: parseInt(data.pitch.value),
|
||||||
|
'count-in': countIn,
|
||||||
|
tracks: _tracks
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const tempMixdown = {...mixData, id: 'temp', jam_track_id: jamTrack.id};
|
//const tempMixdown = { ...mixData, id: 'temp', jam_track_id: jamTrack.id };
|
||||||
dispatch(addMixdown(tempMixdown));
|
//dispatch(addMixdown(tempMixdown));
|
||||||
|
|
||||||
dispatch(createMyMixdown(mixData));
|
dispatch(createMyMixdown(mixData));
|
||||||
};
|
};
|
||||||
|
|
@ -137,23 +158,133 @@ const JKCreateCustomMix = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (jamTrack) {
|
if (jamTrack) {
|
||||||
setTracks(jamTrack.tracks.filter(track => track.track_type === 'Track' || track.track_type === 'Click'));
|
setTracks(jamTrack.tracks.filter(track => track.track_type === 'Track' || track.track_type === 'Click'));
|
||||||
setMixdowns(jamTrack.mixdowns);
|
|
||||||
}
|
}
|
||||||
|
//reset watched mixdowns on unload
|
||||||
|
return () => {
|
||||||
|
watchedMixdowns.forEach(subscription => {
|
||||||
|
window.JK.SubscriptionUtils.unsubscribe(subscription.type, subscription.id);
|
||||||
|
});
|
||||||
|
};
|
||||||
}, [jamTrack]);
|
}, [jamTrack]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (jamTrack) {
|
if (newMixdownLoadingStatus === 'succeeded') {
|
||||||
if(newMixdownLoadingStatus === 'succeeded') {
|
setValue('mixName', '');
|
||||||
setValue('mixName', '');
|
setValue('tempo', TEMPO_OPTIONS[0]);
|
||||||
setValue('tempo', TEMPO_OPTIONS[0]);
|
setValue('pitch', PITCH_OPTIONS[0]);
|
||||||
setValue('pitch', PITCH_OPTIONS[0]);
|
setValue('mixdownTracks', []);
|
||||||
setValue('mixdownTracks', []);
|
setSelectedTracks([]);
|
||||||
setSelectedTracks([]);
|
|
||||||
setMixdowns(jamTrack.mixdowns);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [newMixdownLoadingStatus]);
|
}, [newMixdownLoadingStatus]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (awaitingMixdown) {
|
||||||
|
//enqueue the mixdown
|
||||||
|
console.log('Enqueueing mixdown', awaitingMixdown);
|
||||||
|
const options = { id: awaitingMixdown.id, file_type: 'mp3', encrypt_type: null, sample_rate: SAMPLE_RATE };
|
||||||
|
dispatch(enqueueMyMixdown(options));
|
||||||
|
}
|
||||||
|
}, [awaitingMixdown]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (enqueuedMixdown) {
|
||||||
|
showEstimatedTime();
|
||||||
|
manageWatchedMixdowns();
|
||||||
|
}
|
||||||
|
}, [enqueuedMixdown]);
|
||||||
|
|
||||||
|
const showEstimatedTime = () => {
|
||||||
|
console.log('Enqueued mixdown', enqueuedMixdown);
|
||||||
|
const time = enqueuedMixdown.queue_time;
|
||||||
|
|
||||||
|
if (time === 0) {
|
||||||
|
setEnqueueTimeMessage('Your custom mix will take about 1 minute to be created.');
|
||||||
|
} else {
|
||||||
|
const guess = Math.ceil(time / 60.0);
|
||||||
|
if (guess === 1) {
|
||||||
|
setEnqueueTimeMessage('Your custom mix will take about 1 minute to be created.');
|
||||||
|
} else {
|
||||||
|
setEnqueueTimeMessage(`Your custom mix will take about ${guess} minutes to be created.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setShowQueueTime(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const manageWatchedMixdowns = () => {
|
||||||
|
console.log('Managing watched mixdowns');
|
||||||
|
mixdowns.forEach(mixdown => {
|
||||||
|
if (mixdown.oggPackage) {
|
||||||
|
if (mixdown.oggPackage.signing_state === 'SIGNED') {
|
||||||
|
console.log('unsubscribing to mixdown', mixdown);
|
||||||
|
unsubscribe(mixdown.oggPackage);
|
||||||
|
} else {
|
||||||
|
console.log('subscribing to mixdown', mixdown);
|
||||||
|
subscribe(mixdown.oggPackage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const subscriptionKey = mixdown_package => {
|
||||||
|
return `mixdown-${mixdown_package.id}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const subscribe = mixdown_package => {
|
||||||
|
const key = subscriptionKey(mixdown_package);
|
||||||
|
console.log('watchedMixdowns', watchedMixdowns);
|
||||||
|
if (!watchedMixdowns[key]) {
|
||||||
|
window.JK.SubscriptionUtils.subscribe('mixdown', mixdown_package.id).on(
|
||||||
|
window.JK.EVENTS.SUBSCRIBE_NOTIFICATION,
|
||||||
|
onMixdownSubscriptionEvent
|
||||||
|
);
|
||||||
|
dispatch(addWatchedMixdown({ type: 'mixdown', id: mixdown_package.id }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsubscribe = mixdown_package => {
|
||||||
|
const key = subscriptionKey(mixdown_package);
|
||||||
|
if (watchedMixdowns[key]) {
|
||||||
|
window.JK.SubscriptionUtils.unsubscribe('mixdown', mixdown_package.id);
|
||||||
|
dispatch(removeWatchedMixdown({ type: 'mixdown', id: mixdown_package.id }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMixdownSubscriptionEvent = (e, data) => {
|
||||||
|
console.log("JamTrackStore: subscription notification received: type:" + data.type, data)
|
||||||
|
const mixdown_package_id = data.id;
|
||||||
|
mixdowns.forEach(mixdown => {
|
||||||
|
const mixdown_package = mixdown.packages.find(p => p.id === mixdown_package_id);
|
||||||
|
if (mixdown_package) {
|
||||||
|
mixdown_package.signing_state = data.body.signing_state
|
||||||
|
mixdown_package.packaging_steps = data.body.packaging_steps
|
||||||
|
mixdown_package.current_packaging_step = data.body.current_packaging_step
|
||||||
|
console.log("updated package with subscription notification event")
|
||||||
|
|
||||||
|
if(mixdown_package.signing_state === 'SIGNING_TIMEOUT' || mixdown_package.signing_state === 'QUEUED_TIMEOUT' || mixdown_package.signing_state === 'QUIET_TIMEOUT' || mixdown_package.signing_state === 'ERROR'){
|
||||||
|
reportError(mixdown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const reportError = (mixdown) => {
|
||||||
|
const enqueued = enqueuedMixdowns[mixdown?.id]
|
||||||
|
if (!enqueued || enqueued.marked) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
enqueued.marked = true
|
||||||
|
const data = {
|
||||||
|
value: 1,
|
||||||
|
user_id: currentUser.id,
|
||||||
|
user_name: currentUser.name,
|
||||||
|
result: `signing state: ${mixdown.oggPackage?.signing_state}, client state: ${mixdown.client_state}`,
|
||||||
|
mixdown: mixdown.id,
|
||||||
|
package: mixdown.oggPackage?.id,
|
||||||
|
detail: mixdown.oggPackage?.error_reason
|
||||||
|
}
|
||||||
|
createAlert(`Mixdown Sync failed for ${currentUser.name}`, data)
|
||||||
|
}
|
||||||
|
|
||||||
const trackName = track => {
|
const trackName = track => {
|
||||||
if (track.track_type === 'Track' || track.track_type === 'Click') {
|
if (track.track_type === 'Track' || track.track_type === 'Click') {
|
||||||
if (track.track_type === 'Click') {
|
if (track.track_type === 'Click') {
|
||||||
|
|
@ -180,30 +311,34 @@ const JKCreateCustomMix = () => {
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<Scrollbar ref={scrollbar} style={{ width: '100%', height: 300 }} mobileNative={true}>
|
<Scrollbar ref={scrollbar} style={{ width: '100%', height: 300 }} mobileNative={true}>
|
||||||
<Table striped bordered className="fs--1 mb-0">
|
<Table striped bordered className="fs--1 mb-0">
|
||||||
<thead className="bg-200 text-900">
|
<thead className="bg-200 text-900">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Tracks {tracks.length > 0 && <>({tracks.length})</>}</th>
|
<th>Tracks {tracks.length > 0 && <>({tracks.length})</>}</th>
|
||||||
<th className="text-center">Mute</th>
|
<th className="text-center">Mute</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{tracks &&
|
||||||
{tracks &&
|
tracks.map((track, index) => (
|
||||||
tracks.map((track, index) => (
|
<tr key={index}>
|
||||||
<tr key={index}>
|
<td>
|
||||||
<td>
|
<span>{trackName(track)}</span>
|
||||||
<span>{trackName(track)}</span>
|
</td>
|
||||||
</td>
|
<td className="text-center">
|
||||||
<td className="text-center">
|
<input
|
||||||
<input type="checkbox" value={track.id} onChange={toggleTrack} checked={ selectedTracks.includes(track.id)} disabled={hasExceededMax} />
|
type="checkbox"
|
||||||
</td>
|
value={track.id}
|
||||||
</tr>
|
onChange={toggleTrack}
|
||||||
))}
|
checked={selectedTracks.includes(track.id)}
|
||||||
|
disabled={hasExceededMax}
|
||||||
</tbody>
|
/>
|
||||||
</Table>
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</Table>
|
||||||
</Scrollbar>
|
</Scrollbar>
|
||||||
<Controller
|
<Controller
|
||||||
name="mixdownTracks"
|
name="mixdownTracks"
|
||||||
|
|
@ -211,7 +346,7 @@ const JKCreateCustomMix = () => {
|
||||||
rules={{
|
rules={{
|
||||||
required: 'Select at least one track to create a mix'
|
required: 'Select at least one track to create a mix'
|
||||||
}}
|
}}
|
||||||
render={({ field }) => <Input type='hidden' {...field} />}
|
render={({ field }) => <Input type="hidden" {...field} />}
|
||||||
/>
|
/>
|
||||||
{errors.mixdownTracks && (
|
{errors.mixdownTracks && (
|
||||||
<div className="text-danger">
|
<div className="text-danger">
|
||||||
|
|
@ -222,7 +357,9 @@ const JKCreateCustomMix = () => {
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<Row className="mb-3 mt-3">
|
<Row className="mb-3 mt-3">
|
||||||
<Col sm={6} md={4} lg={3}>Tempo</Col>
|
<Col sm={6} md={4} lg={3}>
|
||||||
|
Tempo
|
||||||
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<Controller
|
<Controller
|
||||||
name="tempo"
|
name="tempo"
|
||||||
|
|
@ -232,7 +369,9 @@ const JKCreateCustomMix = () => {
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row className="mb-3">
|
<Row className="mb-3">
|
||||||
<Col sm={6} md={4} lg={3}>Pitch</Col>
|
<Col sm={6} md={4} lg={3}>
|
||||||
|
Pitch
|
||||||
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<Controller
|
<Controller
|
||||||
name="pitch"
|
name="pitch"
|
||||||
|
|
@ -242,7 +381,9 @@ const JKCreateCustomMix = () => {
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row className="mb-3">
|
<Row className="mb-3">
|
||||||
<Col sm={6} md={4} lg={3}>Mix Name</Col>
|
<Col sm={6} md={4} lg={3}>
|
||||||
|
Mix Name
|
||||||
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<Controller
|
<Controller
|
||||||
name="mixName"
|
name="mixName"
|
||||||
|
|
@ -260,13 +401,23 @@ const JKCreateCustomMix = () => {
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Col className='d-flex justify-content-end'>
|
<Col className="d-flex justify-content-end">
|
||||||
<Button color="primary" disabled={newMixdownLoadingStatus === 'loading' || hasExceededMax }>
|
<Button color="primary" disabled={newMixdownLoadingStatus === 'loading' || hasExceededMax}>
|
||||||
{newMixdownLoadingStatus === 'loading' ? 'Creating Mix...' : 'Create Mix'}
|
{newMixdownLoadingStatus === 'loading' ? 'Creating Mix...' : 'Create Mix'}
|
||||||
</Button>
|
</Button>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</form>
|
</form>
|
||||||
|
<JKModalDialog
|
||||||
|
show={showQueueTime}
|
||||||
|
onToggle={() => setShowQueueTime(!showQueueTime)}
|
||||||
|
title="Mixdown Queued"
|
||||||
|
showFooter={true}
|
||||||
|
>
|
||||||
|
<div className="d-flex flex-column">
|
||||||
|
<p>{enqueueTimeMessage}</p>
|
||||||
|
</div>
|
||||||
|
</JKModalDialog>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,13 @@ import { getUserDetail, postUserEvent, userOpenedJamTrackWebPlayer } from '../..
|
||||||
import JKJamTrackPlayer from './JKJamTrackPlayer';
|
import JKJamTrackPlayer from './JKJamTrackPlayer';
|
||||||
import JKMyJamTrackMixes from './JKMyJamTrackMixes';
|
import JKMyJamTrackMixes from './JKMyJamTrackMixes';
|
||||||
import JKCreateCustomMix from './JKCreateCustomMix';
|
import JKCreateCustomMix from './JKCreateCustomMix';
|
||||||
|
import JKJamTrackResourceLinks from './JKJamTrackResourceLinks';
|
||||||
import { useAuth } from '../../context/UserAuth';
|
import { useAuth } from '../../context/UserAuth';
|
||||||
|
|
||||||
import { fetchJamTrack } from '../../store/features/jamTrackSlice';
|
import { fetchJamTrack } from '../../store/features/jamTrackSlice';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
const JKJamTrack = () => {
|
const JKJamTrack = () => {
|
||||||
console.log('JKJamTrack rendering');
|
|
||||||
|
|
||||||
const { t } = useTranslation('jamtracks');
|
const { t } = useTranslation('jamtracks');
|
||||||
const { greaterThan } = useResponsive();
|
const { greaterThan } = useResponsive();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
|
@ -25,7 +24,7 @@ const JKJamTrack = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
||||||
const jamTrackLoadingStatus = useSelector(state => state.jamTrack.status);
|
const jamTrackLoadingStatus = useSelector(state => state.jamTrack.jamTrackLoadingStatus);
|
||||||
|
|
||||||
const fetchJamTrackRecord = () => {
|
const fetchJamTrackRecord = () => {
|
||||||
dispatch(fetchJamTrack({ id }));
|
dispatch(fetchJamTrack({ id }));
|
||||||
|
|
@ -62,7 +61,7 @@ const JKJamTrack = () => {
|
||||||
<>
|
<>
|
||||||
{jamTrackLoadingStatus === 'loading' || jamTrackLoadingStatus == 'idel' ? (
|
{jamTrackLoadingStatus === 'loading' || jamTrackLoadingStatus == 'idel' ? (
|
||||||
<div>Loading...</div>
|
<div>Loading...</div>
|
||||||
) : Object.keys(jamTrack).length ? (
|
) : jamTrack ? (
|
||||||
<Row>
|
<Row>
|
||||||
<Col sm={12} md={4}>
|
<Col sm={12} md={4}>
|
||||||
<Card className="mx-auto mb-4">
|
<Card className="mx-auto mb-4">
|
||||||
|
|
@ -84,41 +83,7 @@ const JKJamTrack = () => {
|
||||||
<Card className="mx-auto">
|
<Card className="mx-auto">
|
||||||
<FalconCardHeader title={t('jamtrack.help_resources.title')} titleClass="font-weight-semi-bold" />
|
<FalconCardHeader title={t('jamtrack.help_resources.title')} titleClass="font-weight-semi-bold" />
|
||||||
<CardBody className="pt-3">
|
<CardBody className="pt-3">
|
||||||
<div className="mb-3">
|
<JKJamTrackResourceLinks jamTrack={jamTrack} />
|
||||||
<div>
|
|
||||||
<a target="_blank" href="https://jamkazam.freshdesk.com/support/solutions/articles/66000501472">
|
|
||||||
{t('jamtrack.help_resources.using_overview.title')}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{t('jamtrack.help_resources.using_overview.description')}
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
<div>
|
|
||||||
<a target="_blank" href="https://jamkazam.freshdesk.com/support/solutions/articles/66000125792">
|
|
||||||
{t('jamtrack.help_resources.using_mac_windows.title')}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{t('jamtrack.help_resources.using_mac_windows.description')}
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
<div>
|
|
||||||
<a target="_blank" href="https://www.jamkazam.com/client#/jamtrack">
|
|
||||||
{t('jamtrack.help_resources.jamtracks_home.title')}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{t('jamtrack.help_resources.jamtracks_home.description')}
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
<div>
|
|
||||||
<a target="_blank" href={`https://www.jamkazam.com/client?artist=${encodeURIComponent(
|
|
||||||
jamTrack.original_artist
|
|
||||||
)}#/jamtrack/search`}
|
|
||||||
>
|
|
||||||
{t('jamtrack.help_resources.see_more.title')}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{t('jamtrack.help_resources.see_more.description')}
|
|
||||||
</div>
|
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import FingerprintJS from '@fingerprintjs/fingerprintjs';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import JKModalDialog from '../common/JKModalDialog';
|
import JKModalDialog from '../common/JKModalDialog';
|
||||||
import { enqueueMyMixdown } from '../../store/features/jamTrackSlice';
|
import { enqueueMyMixdown } from '../../store/features/jamTrackSlice';
|
||||||
import { set } from 'react-hook-form';
|
import { SAMPLE_RATE } from '../../helpers/jamTracks';
|
||||||
|
|
||||||
const JKJamTrackPlayer = () => {
|
const JKJamTrackPlayer = () => {
|
||||||
const [options, setOptions] = useState([]);
|
const [options, setOptions] = useState([]);
|
||||||
|
|
@ -15,7 +15,6 @@ const JKJamTrackPlayer = () => {
|
||||||
const audioRef = useRef(null);
|
const audioRef = useRef(null);
|
||||||
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
||||||
const mixdownsLoadingStatus = useSelector(state => state.jamTrack.mixdownsLoadingStatus);
|
const mixdownsLoadingStatus = useSelector(state => state.jamTrack.mixdownsLoadingStatus);
|
||||||
const SAMPLE_RATE = 48;
|
|
||||||
const [retryMessage, setRetryMessage] = useState('');
|
const [retryMessage, setRetryMessage] = useState('');
|
||||||
const [showRetry, setShowRetry] = useState(false);
|
const [showRetry, setShowRetry] = useState(false);
|
||||||
const [retryDownload, setRetryDownload] = useState(false);
|
const [retryDownload, setRetryDownload] = useState(false);
|
||||||
|
|
@ -24,7 +23,7 @@ const JKJamTrackPlayer = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (jamTrack) {
|
if (jamTrack) {
|
||||||
const opts = jamTrack.mixdowns.filter(mix => mix.id !== 'temp').map(mix => ({ value: mix.id, label: mix.name }));
|
const opts = jamTrack.mixdowns.map(mix => ({ value: mix.id, label: mix.name }));
|
||||||
opts.unshift({ value: 'original', label: 'Original' });
|
opts.unshift({ value: 'original', label: 'Original' });
|
||||||
setOptions(opts);
|
setOptions(opts);
|
||||||
if (jamTrack.last_mixdown_id) {
|
if (jamTrack.last_mixdown_id) {
|
||||||
|
|
@ -55,7 +54,7 @@ const JKJamTrackPlayer = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('selectedOption', selectedOption);
|
|
||||||
if (selectedOption.value === 'original') {
|
if (selectedOption.value === 'original') {
|
||||||
const audioUrl = getOriginalTrackUrl();
|
const audioUrl = getOriginalTrackUrl();
|
||||||
setAudioUrl(audioUrl);
|
setAudioUrl(audioUrl);
|
||||||
|
|
@ -64,19 +63,17 @@ const JKJamTrackPlayer = () => {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//it's a mixdown
|
//it's a mixdown
|
||||||
//see if there is a myPackage avaialble. if it is, it means the mixdown is ready
|
console.log('_selectedOption', jamTrack);
|
||||||
//if not, it means the mixdown is still being processed
|
|
||||||
|
|
||||||
const myPackage = jamTrack.mixdowns
|
|
||||||
.find(mix => mix.id === selectedOption.value)
|
|
||||||
?.packages.find(p => p.file_type === 'mp3' && p.encrypt_type === null && p.sample_rate === SAMPLE_RATE);
|
|
||||||
|
|
||||||
console.log('_DEBUG_ myPackage', myPackage);
|
|
||||||
|
|
||||||
let retry = false;
|
let retry = false;
|
||||||
if (myPackage) {
|
if (jamTrack.mp3Package && jamTrack.mp3Package.signing_state) {
|
||||||
//let see if the mixdown is signed
|
// SIGNED - the package is ready to be downloaded
|
||||||
switch (myPackage.signing_state) {
|
// ERROR - the package was built unsuccessfully
|
||||||
|
// SIGNING_TIMEOUT - the package was kicked off to be signed, but it seems to have hung
|
||||||
|
// SIGNING - the package is currently signing
|
||||||
|
// QUEUED_TIMEOUT - the package signing job (JamTrackBuilder) was queued, but never executed
|
||||||
|
// QUEUED - the package is queued to sign
|
||||||
|
// QUIET - the jam_track_right exists, but no job has been kicked off; a job needs to be enqueued
|
||||||
|
switch (jamTrack.mp3Package.signing_state) {
|
||||||
case 'QUIET_TIMEOUT':
|
case 'QUIET_TIMEOUT':
|
||||||
setRetryMessage('Custom mix never got created. Retry?');
|
setRetryMessage('Custom mix never got created. Retry?');
|
||||||
retry = true;
|
retry = true;
|
||||||
|
|
@ -86,13 +83,17 @@ const JKJamTrackPlayer = () => {
|
||||||
retry = true;
|
retry = true;
|
||||||
break;
|
break;
|
||||||
case 'SIGNING_TIMEOUT':
|
case 'SIGNING_TIMEOUT':
|
||||||
setRetryMessage('Custom mix took took long to build. Retry?');
|
setRetryMessage('Custom mix took long to build. Retry?');
|
||||||
retry = true;
|
retry = true;
|
||||||
break;
|
break;
|
||||||
case 'ERROR':
|
case 'ERROR':
|
||||||
setRetryMessage('Custom mix failed to build. Retry?');
|
setRetryMessage('Custom mix failed to build. Retry?');
|
||||||
retry = true;
|
retry = true;
|
||||||
break;
|
break;
|
||||||
|
case 'QUIET':
|
||||||
|
setRetryMessage('Custom mix never got created. Retry?');
|
||||||
|
retry = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +103,7 @@ const JKJamTrackPlayer = () => {
|
||||||
setAudioUrl(null);
|
setAudioUrl(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (retry) {
|
if (retry) {
|
||||||
setShowRetry(true);
|
setShowRetry(true);
|
||||||
return;
|
return;
|
||||||
|
|
@ -120,6 +122,7 @@ const JKJamTrackPlayer = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (retryDownload && selectedOption) {
|
if (retryDownload && selectedOption) {
|
||||||
const options = { id: selectedOption.value, file_type: 'mp3', encrypt_type: null, sample_rate: SAMPLE_RATE };
|
const options = { id: selectedOption.value, file_type: 'mp3', encrypt_type: null, sample_rate: SAMPLE_RATE };
|
||||||
|
console.log('enqueueMyMixdown', options);
|
||||||
dispatch(enqueueMyMixdown(options));
|
dispatch(enqueueMyMixdown(options));
|
||||||
}
|
}
|
||||||
}, [retryDownload]);
|
}, [retryDownload]);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
const JKJamTrackResourceLinks = ({jamTrack}) => {
|
||||||
|
const { t } = useTranslation('jamtracks');
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="mb-3">
|
||||||
|
<div>
|
||||||
|
<a target="_blank" href="https://jamkazam.freshdesk.com/support/solutions/articles/66000501472">
|
||||||
|
{t('jamtrack.help_resources.using_overview.title')}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{t('jamtrack.help_resources.using_overview.description')}
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<div>
|
||||||
|
<a target="_blank" href="https://jamkazam.freshdesk.com/support/solutions/articles/66000125792">
|
||||||
|
{t('jamtrack.help_resources.using_mac_windows.title')}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{t('jamtrack.help_resources.using_mac_windows.description')}
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<div>
|
||||||
|
<a target="_blank" href="https://www.jamkazam.com/client#/jamtrack">
|
||||||
|
{t('jamtrack.help_resources.jamtracks_home.title')}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{t('jamtrack.help_resources.jamtracks_home.description')}
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
href={`https://www.jamkazam.com/client?artist=${encodeURIComponent(
|
||||||
|
jamTrack.original_artist
|
||||||
|
)}#/jamtrack/search`}
|
||||||
|
>
|
||||||
|
{t('jamtrack.help_resources.see_more.title')}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{t('jamtrack.help_resources.see_more.description')}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default JKJamTrackResourceLinks;
|
||||||
|
|
@ -6,30 +6,13 @@ import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
|
||||||
const JKMyJamTrackMixes = () => {
|
const JKMyJamTrackMixes = () => {
|
||||||
const [mixes, setMixes] = useState([]);
|
|
||||||
const fpPromise = FingerprintJS.load();
|
const fpPromise = FingerprintJS.load();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
||||||
|
const mixdowns = useSelector(state => state.jamTrack.mixdowns);
|
||||||
const mixdownsLoadingStatus = useSelector(state => state.jamTrack.mixdownsLoadingStatus);
|
const mixdownsLoadingStatus = useSelector(state => state.jamTrack.mixdownsLoadingStatus);
|
||||||
const deleteMixdownStatus = useSelector(state => state.jamTrack.deleteMixdownStatus);
|
const deleteMixdownStatus = useSelector(state => state.jamTrack.deleteMixdownStatus);
|
||||||
const tempMixdownLoadingStatus = useSelector(state => state.jamTrack.tempMixdownLoadingStatus);
|
|
||||||
const buildRetries = useSelector(state => state.jamTrack.buildRetries);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!jamTrack) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mixdownsLoadingStatus === 'succeeded') {
|
|
||||||
setMixes(jamTrack.mixdowns.filter(m => m.id !== 'temp'));
|
|
||||||
}
|
|
||||||
}, [mixdownsLoadingStatus]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (tempMixdownLoadingStatus === 'succeeded') {
|
|
||||||
setMixes(jamTrack.mixdowns);
|
|
||||||
}
|
|
||||||
}, [tempMixdownLoadingStatus]);
|
|
||||||
|
|
||||||
const downloadJamTrack = async () => {
|
const downloadJamTrack = async () => {
|
||||||
console.log('Downloading JamTrack');
|
console.log('Downloading JamTrack');
|
||||||
|
|
@ -47,7 +30,7 @@ const JKMyJamTrackMixes = () => {
|
||||||
|
|
||||||
const downloadMix = async mixId => {
|
const downloadMix = async mixId => {
|
||||||
console.log('Download mixdown');
|
console.log('Download mixdown');
|
||||||
const mixdown = mixes.find(m => m.id === mixId);
|
const mixdown = mixdowns.find(m => m.id === mixId);
|
||||||
const mixdownPackage = mixdown.packages.find(p => p.file_type === 'mp3');
|
const mixdownPackage = mixdown.packages.find(p => p.file_type === 'mp3');
|
||||||
if (mixdownPackage?.signing_state == 'SIGNED') {
|
if (mixdownPackage?.signing_state == 'SIGNED') {
|
||||||
const fp = await fpPromise;
|
const fp = await fpPromise;
|
||||||
|
|
@ -56,7 +39,7 @@ const JKMyJamTrackMixes = () => {
|
||||||
mixdown.id
|
mixdown.id
|
||||||
}/download.mp3?file_type=mp3&sample_rate=48&download=1&mark=${result.visitorId}`;
|
}/download.mp3?file_type=mp3&sample_rate=48&download=1&mark=${result.visitorId}`;
|
||||||
openDownload(src);
|
openDownload(src);
|
||||||
}else{
|
} else {
|
||||||
console.log('Mixdown not signed');
|
console.log('Mixdown not signed');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -75,10 +58,17 @@ const JKMyJamTrackMixes = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isMixdownBuilding = mix => {
|
const mixdownPackage = mixdown => {
|
||||||
const retry = buildRetries.find(retry => retry.mixdownId === mix.id);
|
if (!mixdown.packages || mixdown.packages.length === 0) {
|
||||||
return mix.id === 'temp' || (retry && ['queued', 'enqueuing'].includes(retry.state))
|
return null;
|
||||||
}
|
}
|
||||||
|
return mixdown.packages[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
const isMixdownPackageReady = mixdown => {
|
||||||
|
const pkg = mixdownPackage(mixdown);
|
||||||
|
return pkg && pkg.signing_state === 'SIGNED';
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -102,25 +92,36 @@ const JKMyJamTrackMixes = () => {
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{mixes.map(mix => (
|
{mixdowns.map(mixdown => (
|
||||||
<tr key={mix.id}>
|
<tr key={mixdown.id}>
|
||||||
<td>{mix.name}</td>
|
<td>
|
||||||
|
{mixdown.name} <br />
|
||||||
|
{mixdown.id} <br />
|
||||||
|
pkg-{mixdownPackage(mixdown)?.signing_state}
|
||||||
|
</td>
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
{isMixdownBuilding(mix) ? (
|
|
||||||
<FontAwesomeIcon icon="spinner" size="lg" />
|
{isMixdownPackageReady(mixdown) ? (
|
||||||
) : (
|
|
||||||
<>
|
<>
|
||||||
<a onClick={() => downloadMix(mix.id)} style={{ cursor: 'pointer' }}>
|
<a onClick={() => downloadMix(mixdown.id)} style={{ cursor: 'pointer' }}>
|
||||||
<FontAwesomeIcon icon="download" size="lg" className="mr-3" />
|
<FontAwesomeIcon icon="download" size="lg" className="mr-3" />
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
onClick={() => deleteMix(mix.id)}
|
onClick={() => deleteMix(mixdown.id)}
|
||||||
disabled={deleteMixdownStatus === 'loading'}
|
disabled={deleteMixdownStatus === 'loading'}
|
||||||
style={{ cursor: 'pointer' }}
|
style={{ cursor: 'pointer' }}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon="trash" size="lg" />
|
<FontAwesomeIcon icon="trash" size="lg" />
|
||||||
</a>
|
</a>
|
||||||
</>
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{mixdown.signing_state === 'QUEUED' || mixdown.signing_state === 'SIGNING' ? (
|
||||||
|
<FontAwesomeIcon icon="spinner" size="lg" className="mr-3" />
|
||||||
|
) : (
|
||||||
|
<FontAwesomeIcon icon="exclamation-circle" size="lg" className="mr-3" />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export const SAMPLE_RATE = 48;
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { error } from 'is_js';
|
|
||||||
import apiFetch from './apiFetch';
|
import apiFetch from './apiFetch';
|
||||||
|
|
||||||
export const getMusicians = page => {
|
export const getMusicians = page => {
|
||||||
|
|
@ -623,3 +622,14 @@ export const deleteAvatar = id => {
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const createAlert = (subject, data) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
apiFetch(`/alerts`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({subject, data})
|
||||||
|
})
|
||||||
|
.then(response => resolve(response))
|
||||||
|
.catch(error => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -1,15 +1,19 @@
|
||||||
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
||||||
import { deleteMixdown, getJamTrack, createMixdown, enqueueMixdown } from '../../helpers/rest';
|
import { deleteMixdown, getJamTrack, createMixdown, enqueueMixdown } from '../../helpers/rest';
|
||||||
|
import { SAMPLE_RATE } from '../../helpers/jamTracks';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
jamTrack: {},
|
jamTrack: null,
|
||||||
|
mixdowns: [],
|
||||||
|
awaitingMixdown: null,
|
||||||
|
enqueuedMixdown: null,
|
||||||
|
enqueuedMixdowns: [],
|
||||||
|
watchedMixdowns: [],
|
||||||
jamTrackLoadingStatus: 'idle',
|
jamTrackLoadingStatus: 'idle',
|
||||||
mixdownsLoadingStatus: 'idle',
|
mixdownsLoadingStatus: 'idle',
|
||||||
deleteMixdownStatus: 'idle',
|
deleteMixdownStatus: 'idle',
|
||||||
newMixdownLoadingStatus: 'idle',
|
newMixdownLoadingStatus: 'idle',
|
||||||
tempMixdownLoadingStatus: 'idle',
|
tempMixdownLoadingStatus: 'idle',
|
||||||
enqueueLoadingStatus: 'idle',
|
|
||||||
buildRetries: [],
|
|
||||||
error: null
|
error: null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -24,7 +28,6 @@ export const createMyMixdown = createAsyncThunk('jamTracks/createMixdown', async
|
||||||
});
|
});
|
||||||
|
|
||||||
export const removeMixdown = createAsyncThunk('jamTracks/removeMixdown', async (options, thunkAPI) => {
|
export const removeMixdown = createAsyncThunk('jamTracks/removeMixdown', async (options, thunkAPI) => {
|
||||||
console.log('removeMixdown', options);
|
|
||||||
const { id } = options;
|
const { id } = options;
|
||||||
const response = await deleteMixdown(id);
|
const response = await deleteMixdown(id);
|
||||||
return { id };
|
return { id };
|
||||||
|
|
@ -35,6 +38,10 @@ export const enqueueMyMixdown = createAsyncThunk('jamTracks/enqueueMixdown', asy
|
||||||
return response.json();
|
return response.json();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const jamTrackSlice = createSlice({
|
export const jamTrackSlice = createSlice({
|
||||||
name: 'jamTrack',
|
name: 'jamTrack',
|
||||||
initialState,
|
initialState,
|
||||||
|
|
@ -46,6 +53,26 @@ export const jamTrackSlice = createSlice({
|
||||||
state.jamTrack.mixdowns = [...jamTrack.mixdowns, payload];
|
state.jamTrack.mixdowns = [...jamTrack.mixdowns, payload];
|
||||||
state.tempMixdownLoadingStatus = 'succeeded';
|
state.tempMixdownLoadingStatus = 'succeeded';
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
addWatchedMixdown: (state, action) => {
|
||||||
|
const payload = action.payload;
|
||||||
|
state.watchedMixdowns = [...state.watchedMixdowns, payload];
|
||||||
|
},
|
||||||
|
removeWatchedMixdown: (state, action) => {
|
||||||
|
const payload = action.payload;
|
||||||
|
state.watchedMixdowns = state.watchedMixdowns.filter(mix => mix.id !== payload.id);
|
||||||
|
},
|
||||||
|
updateMixdown: (state, action) => {
|
||||||
|
const payload = action.payload;
|
||||||
|
const jamTrack = state.jamTrack;
|
||||||
|
if (jamTrack) {
|
||||||
|
state.jamTrack.mixdowns = jamTrack.mixdowns.map(mix => {
|
||||||
|
if (mix.id === payload.id) {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
return mix;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
extraReducers: builder => {
|
extraReducers: builder => {
|
||||||
|
|
@ -57,23 +84,26 @@ export const jamTrackSlice = createSlice({
|
||||||
.addCase(fetchJamTrack.fulfilled, (state, action) => {
|
.addCase(fetchJamTrack.fulfilled, (state, action) => {
|
||||||
state.jamTrack = action.payload;
|
state.jamTrack = action.payload;
|
||||||
state.jamTrackLoadingStatus = 'succeeded';
|
state.jamTrackLoadingStatus = 'succeeded';
|
||||||
|
|
||||||
if (action.payload.mixdowns) {
|
if (action.payload.mixdowns) {
|
||||||
|
state.mixdowns = action.payload.mixdowns;
|
||||||
|
assignPackages(state);
|
||||||
state.mixdownsLoadingStatus = 'succeeded';
|
state.mixdownsLoadingStatus = 'succeeded';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.addCase(fetchJamTrack.rejected, (state, action) => {
|
.addCase(fetchJamTrack.rejected, (state, action) => {
|
||||||
state.status = 'failed';
|
|
||||||
state.jamTrackLoadingStatus = 'failed';
|
state.jamTrackLoadingStatus = 'failed';
|
||||||
|
state.jamTrack = null;
|
||||||
state.mixdownsLoadingStatus = 'failed';
|
state.mixdownsLoadingStatus = 'failed';
|
||||||
|
state.mixdowns = [];
|
||||||
state.error = action.error.message;
|
state.error = action.error.message;
|
||||||
})
|
})
|
||||||
.addCase(createMyMixdown.pending, (state, action) => {
|
.addCase(createMyMixdown.pending, (state, action) => {
|
||||||
state.newMixdownLoadingStatus = 'loading';
|
state.newMixdownLoadingStatus = 'loading';
|
||||||
state.mixdownsLoadingStatus = 'loading';
|
state.tempMixdownLoadingStatus = 'loading';
|
||||||
})
|
})
|
||||||
.addCase(createMyMixdown.fulfilled, (state, action) => {
|
.addCase(createMyMixdown.fulfilled, (state, action) => {
|
||||||
state.jamTrack.mixdowns = [...state.jamTrack.mixdowns, action.payload];
|
state.mixdowns = [...state.mixdowns, action.payload];
|
||||||
|
state.awaitingMixdown = action.payload;
|
||||||
state.newMixdownLoadingStatus = 'succeeded';
|
state.newMixdownLoadingStatus = 'succeeded';
|
||||||
state.mixdownsLoadingStatus = 'succeeded';
|
state.mixdownsLoadingStatus = 'succeeded';
|
||||||
state.tempMixdownLoadingStatus = 'idle';
|
state.tempMixdownLoadingStatus = 'idle';
|
||||||
|
|
@ -88,9 +118,7 @@ export const jamTrackSlice = createSlice({
|
||||||
state.deleteMixdownStatus = 'loading';
|
state.deleteMixdownStatus = 'loading';
|
||||||
})
|
})
|
||||||
.addCase(removeMixdown.fulfilled, (state, action) => {
|
.addCase(removeMixdown.fulfilled, (state, action) => {
|
||||||
console.log('mixdown removed', action.payload);
|
const mixdowns = state.mixdowns.filter(mix => mix.id !== action.payload.id);
|
||||||
const mixdowns = state.jamTrack.mixdowns.filter(mix => mix.id !== action.payload.id);
|
|
||||||
state.jamTrack.mixdowns = mixdowns;
|
|
||||||
state.mixdowns = mixdowns;
|
state.mixdowns = mixdowns;
|
||||||
state.mixdownsLoadingStatus = 'succeeded';
|
state.mixdownsLoadingStatus = 'succeeded';
|
||||||
state.deleteMixdownStatus = 'succeeded';
|
state.deleteMixdownStatus = 'succeeded';
|
||||||
|
|
@ -100,47 +128,36 @@ export const jamTrackSlice = createSlice({
|
||||||
state.mixdownsLoadingStatus = 'failed';
|
state.mixdownsLoadingStatus = 'failed';
|
||||||
state.deleteMixdownStatus = 'failed';
|
state.deleteMixdownStatus = 'failed';
|
||||||
})
|
})
|
||||||
.addCase(enqueueMyMixdown.pending, (state, action) => {
|
|
||||||
const estimate = { mixdownId: action.meta.arg.id, state: 'enqueuing' };
|
|
||||||
if (!state.buildRetries.find(estimate => estimate.mixdownId === action.meta.arg.id)) {
|
|
||||||
state.buildRetries = [...state.buildRetries, estimate];
|
|
||||||
} else {
|
|
||||||
state.buildRetries = state.buildRetries.map(estimate => {
|
|
||||||
if (estimate.mixdownId === action.meta.arg.id) {
|
|
||||||
return { ...estimate, state: 'enqueuing' };
|
|
||||||
}
|
|
||||||
return estimate;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.addCase(enqueueMyMixdown.fulfilled, (state, action) => {
|
.addCase(enqueueMyMixdown.fulfilled, (state, action) => {
|
||||||
const estimate = { mixdownId: action.payload.id, time: action.payload.queue_time, state: 'queued' };
|
console.log('enqueueMyMixdown.fulfilled', action.payload);
|
||||||
if (!state.buildRetries.find(estimate => estimate.mixdownId === action.payload.id)) {
|
const enqueue = { queue_time: action.payload.queue_time, signing_state: action.payload.signing_state };
|
||||||
state.buildRetries = [...state.buildRetries, estimate];
|
state.enqueuedMixdown = enqueue;
|
||||||
} else {
|
state.enqueuedMixdowns = [...state.enqueuedMixdowns, enqueue];
|
||||||
state.buildRetries = state.buildRetries.map(estimate => {
|
state.mixdowns = state.mixdowns.map(mix => {
|
||||||
if (estimate.mixdownId === action.payload.id) {
|
if (mix.id === action.payload.jam_track_mixdown_id) {
|
||||||
return { ...estimate, ...action.payload, state: 'queued' };
|
return { ...mix, ...enqueue };
|
||||||
}
|
}
|
||||||
return estimate;
|
return mix;
|
||||||
});
|
});
|
||||||
}
|
assignPackages(state);
|
||||||
})
|
})
|
||||||
.addCase(enqueueMyMixdown.rejected, (state, action) => {
|
|
||||||
const estimate = { mixdownId: action.meta.arg.id, state: 'failed' };
|
|
||||||
if (!state.buildRetries.find(estimate => estimate.mixdownId === action.meta.arg.id)) {
|
|
||||||
state.buildRetries = [...state.buildRetries, estimate];
|
|
||||||
} else {
|
|
||||||
state.buildRetries = state.buildRetries.map(estimate => {
|
|
||||||
if (estimate.mixdownId === action.meta.arg.id) {
|
|
||||||
return { ...estimate, state: 'failed' };
|
|
||||||
}
|
|
||||||
return estimate;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { addMixdown } = jamTrackSlice.actions;
|
//help functions
|
||||||
|
const pickMp3Package = (mixdown) => {
|
||||||
|
return mixdown.packages.find(p => p.file_type === 'mp3' && p.encrypt_type === null && p.sample_rate === SAMPLE_RATE);
|
||||||
|
};
|
||||||
|
|
||||||
|
const pickOggPackage = (mixdown) => {
|
||||||
|
return mixdown.packages.find(p => p.file_type === 'ogg' && p.encrypt_type === null && p.sample_rate === SAMPLE_RATE);
|
||||||
|
};
|
||||||
|
|
||||||
|
const assignPackages = (state) => {
|
||||||
|
state.jamTrack.mp3Package = state.mixdowns.map(pickMp3Package).filter(p => p);
|
||||||
|
state.jamTrack.oggPackage = state.mixdowns.map(pickOggPackage).filter(p => p);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const { addMixdown, addWatchedMixdown, removeWatchedMixdown } = jamTrackSlice.actions;
|
||||||
export default jamTrackSlice.reducer;
|
export default jamTrackSlice.reducer;
|
||||||
|
|
|
||||||
|
|
@ -627,6 +627,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
server.registerMessageCallback = function (messageType, callback) {
|
server.registerMessageCallback = function (messageType, callback) {
|
||||||
|
console.log("_DEBUG_ jamserver server.registerMessageCallback", messageType, callback)
|
||||||
if (server.dispatchTable[messageType] === undefined) {
|
if (server.dispatchTable[messageType] === undefined) {
|
||||||
server.dispatchTable[messageType] = [];
|
server.dispatchTable[messageType] = [];
|
||||||
}
|
}
|
||||||
|
|
@ -818,6 +819,8 @@
|
||||||
|
|
||||||
var jsMessage = JSON.stringify(message);
|
var jsMessage = JSON.stringify(message);
|
||||||
|
|
||||||
|
console.log("server.send(" + jsMessage + ")");
|
||||||
|
|
||||||
if( isLatencyTester() && (message.type == context.JK.MessageType.HEARTBEAT || message.type == context.JK.MessageType.PEER_MESSAGE)) {
|
if( isLatencyTester() && (message.type == context.JK.MessageType.HEARTBEAT || message.type == context.JK.MessageType.PEER_MESSAGE)) {
|
||||||
logger.info("latency-tester: server.send(" + jsMessage + ")")
|
logger.info("latency-tester: server.send(" + jsMessage + ")")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -607,6 +607,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
server.registerMessageCallback = function (messageType, callback) {
|
server.registerMessageCallback = function (messageType, callback) {
|
||||||
|
console.log("_DEBUG_ jamserver_copy server.registerMessageCallback", messageType, callback)
|
||||||
if (server.dispatchTable[messageType] === undefined) {
|
if (server.dispatchTable[messageType] === undefined) {
|
||||||
server.dispatchTable[messageType] = [];
|
server.dispatchTable[messageType] = [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ class SubscriptionUtils
|
||||||
$server.on(@events.CONNECTION_DOWN, this.onConnectionDown)
|
$server.on(@events.CONNECTION_DOWN, this.onConnectionDown)
|
||||||
|
|
||||||
onSubscriptionMessage: (header, payload) =>
|
onSubscriptionMessage: (header, payload) =>
|
||||||
|
console.log("onSubscriptionMessage", payload, header)
|
||||||
key = this.genKey(payload.type, payload.id)
|
key = this.genKey(payload.type, payload.id)
|
||||||
|
|
||||||
watch = @subscriptions[key]
|
watch = @subscriptions[key]
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,6 @@ class ApiJamTrackMixdownsController < ApiController
|
||||||
end
|
end
|
||||||
|
|
||||||
def enqueue
|
def enqueue
|
||||||
debugger
|
|
||||||
if @jam_track_right.valid?
|
if @jam_track_right.valid?
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue