diff --git a/jam-ui/src/components/dashboard/JKDashboardMain.js b/jam-ui/src/components/dashboard/JKDashboardMain.js index 0736dcbca..53da4ab69 100644 --- a/jam-ui/src/components/dashboard/JKDashboardMain.js +++ b/jam-ui/src/components/dashboard/JKDashboardMain.js @@ -160,6 +160,7 @@ function JKDashboardMain() { registerFriendRequest(); registerFriendRequestAccepted(); registerChatMessageCallback(); + registerSubscriptionCallback(); 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) => { console.log('handleNotification', payload, type); const notification = { @@ -266,6 +275,10 @@ function JKDashboardMain() { } }; + const handleSubscriptionMessage = payload => { + + } + useScript(`${process.env.REACT_APP_CLIENT_BASE_URL}/client_scripts`, initJKScripts); return ( diff --git a/jam-ui/src/components/jamtracks/JKCreateCustomMix.js b/jam-ui/src/components/jamtracks/JKCreateCustomMix.js index 08e84a8af..ebce7e0a8 100644 --- a/jam-ui/src/components/jamtracks/JKCreateCustomMix.js +++ b/jam-ui/src/components/jamtracks/JKCreateCustomMix.js @@ -1,19 +1,30 @@ import React, { useState, useEffect, useRef } from 'react'; import { Table, Row, Col, Input, Button } from 'reactstrap'; import Select from 'react-select'; -import { useForm, Controller } from 'react-hook-form'; -import { createMyMixdown, addMixdown } from '../../store/features/jamTrackSlice'; +import { useForm, Controller, set } from 'react-hook-form'; +import { + createMyMixdown, + enqueueMyMixdown, + addWatchedMixdown, + removeWatchedMixdown +} from '../../store/features/jamTrackSlice'; import { useDispatch, useSelector } from 'react-redux'; 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 MAX_MIXDOWNS = 5; const [tracks, setTracks] = useState([]); - const [mixdowns, setMixdowns] = useState([]); const [selectedTracks, setSelectedTracks] = useState([]); + const [showQueueTime, setShowQueueTime] = useState(false); + const [enqueueTimeMessage, setEnqueueTimeMessage] = useState(''); const dispatch = useDispatch(); const scrollbar = useRef(); + const { currentUser} = useAuth(); const TEMPO_OPTIONS = [ { value: '0', label: 'Original tempo' }, @@ -68,7 +79,12 @@ const JKCreateCustomMix = () => { ]; const jamTrack = useSelector(state => state.jamTrack.jamTrack); + const mixdowns = useSelector(state => state.jamTrack.mixdowns); 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 { control, @@ -114,11 +130,16 @@ const JKCreateCustomMix = () => { const mixData = { jamTrackID: jamTrack.id, 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}; - dispatch(addMixdown(tempMixdown)); + //const tempMixdown = { ...mixData, id: 'temp', jam_track_id: jamTrack.id }; + //dispatch(addMixdown(tempMixdown)); dispatch(createMyMixdown(mixData)); }; @@ -137,23 +158,133 @@ const JKCreateCustomMix = () => { useEffect(() => { if (jamTrack) { 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]); useEffect(() => { - if (jamTrack) { - if(newMixdownLoadingStatus === 'succeeded') { - setValue('mixName', ''); - setValue('tempo', TEMPO_OPTIONS[0]); - setValue('pitch', PITCH_OPTIONS[0]); - setValue('mixdownTracks', []); - setSelectedTracks([]); - setMixdowns(jamTrack.mixdowns); - } + if (newMixdownLoadingStatus === 'succeeded') { + setValue('mixName', ''); + setValue('tempo', TEMPO_OPTIONS[0]); + setValue('pitch', PITCH_OPTIONS[0]); + setValue('mixdownTracks', []); + setSelectedTracks([]); } }, [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 => { if (track.track_type === 'Track' || track.track_type === 'Click') { if (track.track_type === 'Click') { @@ -180,30 +311,34 @@ const JKCreateCustomMix = () => {