jam-cloud/web/app/assets/javascripts/react-components/stores/JamTrackPlayerStore.js.coffee

482 lines
15 KiB
CoffeeScript

$ = jQuery
context = window
logger = context.JK.logger
rest = context.JK.Rest()
EVENTS = context.JK.EVENTS
JamTrackPlayerActions = @JamTrackPlayerActions
BrowserMediaStore = @BrowserMediaStore
BrowserMediaActions = @BrowserMediaActions
@JamTrackPlayerStore = Reflux.createStore(
{
listenables: JamTrackPlayerActions
jamTrack: null
previous: null
requestedSearch: null
requestedFilter: null
subscriptions: {}
enqueuedMixdowns: {}
childWindow: null
watchedMixdowns: {}
init: ->
# Register with the app store to get @app
this.listenTo(context.AppStore, this.onAppInit)
this.listenTo(context.BrowserMediaStore, this.onBrowserMediaChanged)
@browserMediaState = {}
onAppInit: (app) ->
@app = app
onBrowserMediaChanged: (browserMediaState) ->
@browserMediaState = browserMediaState
@changed()
getState: () ->
@state
onOpened: (jamTrack, popup=true) ->
@jamTrack = jamTrack
@changed()
onOpen: (jamTrack, popup=true) ->
if jamTrack.id == @jamTrack?.id && @childWindow?
logger.info("JamTrackPlayerStore: request to open already-opened JamTrack; ignoring")
return
@enqueuedMixdowns = {}
@jamTrack = jamTrack
sampleRate = 48
@sampleRate = if sampleRate == 48 then 48 else 44
if popup
if @childWindow?
@childWindow.close()
logger.debug("opening JamTrackPlayer window")
@childWindow = window.open(@createPopupUrl(jamTrack), 'Media Controls', 'scrollbars=yes,toolbar=no,status=no,height=667,width=450')
@changed()
createPopupUrl: (jamTrack) ->
"/popups/jamtrack-player/" + jamTrack.id
onWindowUnloaded: () ->
BrowserMediaActions.stop()
@childWindow = null
pickMyPackage: () ->
return unless @jamTrack?
for mixdown in @jamTrack.mixdowns
myPackage = null
for mixdown_package in mixdown.packages
if mixdown_package.file_type == 'mp3' && mixdown_package.encrypt_type == null && mixdown_package.sample_rate == @sampleRate
myPackage = mixdown_package
break
mixdown.myPackage = myPackage
subscriptionKey: (mixdown_package) ->
"mixdown-#{mixdown_package.id}"
subscribe: (mixdown_package) ->
key = @subscriptionKey(mixdown_package)
if !@watchedMixdowns[key]?
# we need to register
context.JK.SubscriptionUtils.subscribe('mixdown', mixdown_package.id).on(context.JK.EVENTS.SUBSCRIBE_NOTIFICATION, this.onMixdownSubscriptionEvent)
@watchedMixdowns[key] = {type:'mixdown', id: mixdown_package.id}
unsubscribe: (mixdown_package) ->
key = @subscriptionKey(mixdown_package)
if @watchedMixdowns[key]?
context.JK.SubscriptionUtils.unsubscribe('mixdown', mixdown_package.id)
delete @watchedMixdowns[key]
manageWatchedMixdowns: () ->
if @jamTrack?
for mixdown in @jamTrack.mixdowns
if mixdown.myPackage
if mixdown.myPackage.signing_state == 'SIGNED'
@unsubscribe(mixdown.myPackage)
else
@subscribe(mixdown.myPackage)
else
for key, subscription of @watchedMixdowns
logger.debug("unsubscribing bulk", key, subscription)
context.JK.SubscriptionUtils.unsubscribe(subscription.type, subscription.id)
# we cleared them all out; clear out storage
@watchedMixdowns = {}
onMixdownSubscriptionEvent: (e, data) ->
logger.debug("JamTrackStore: subscription notification received: type:" + data.type, data)
return unless @jamTrack?
mixdown_package_id = data.id
for mixdown in @jamTrack.mixdowns
for mixdown_package in mixdown.packages
if mixdown_package.id == mixdown_package_id
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
logger.debug("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)
@changed()
break
# this drives the state engine required to get a Mixdown from 'available on the server' to
manageMixdownSynchronization: () ->
if @jamTrack
@jamTrack.activeMixdown = null
@jamTrack.activeStem = null
# let's see if we have a mixdown active?
#if !@jamTrack?.last_mixdown_id?
# logger.debug("JamTrackStore: no mixdown active")
for mixdown in @jamTrack.mixdowns
if mixdown.id == @jamTrack.last_mixdown_id
@jamTrack.activeMixdown = mixdown
#logger.debug("JamTrackStore: mixdown active:", mixdown)
break
for stem in @jamTrack.tracks
if stem.id == @jamTrack.last_stem_id
@jamTrack.activeStem = stem
break
# let's check and see if we've asked the BrowserMediaStore to load this particular file or not
if @jamTrack?.activeStem
if @browserMediaState?.id != @jamTrack.activeStem.id
new window.Fingerprint2().get((result, components) => (
BrowserMediaActions.load(@jamTrack.activeStem.id, [window.location.protocol + '//' + window.location.host + "/api/jamtracks/#{@jamTrack.id}/stems/#{@jamTrack.activeStem.id}/download.mp3?file_type=mp3&mark=#{result}"], 'jamtrack_web_player')
))
@jamTrack.activeStem.client_state = 'downloading'
else
if @browserMediaState.loaded
@jamTrack.activeStem.client_state = 'ready'
else if @browserMediaState.load_error
@jamTrack.activeStem.client_state = 'download_fail'
else
@jamTrack.activeStem.client_state = 'downloading'
else if @jamTrack?.activeMixdown
# if we don't have this on the server yet, don't engage the rest of this logic...
return if @jamTrack.activeMixdown?.myPackage?.signing_state != 'SIGNED'
activePackage = @jamTrack.activeMixdown.myPackage
if activePackage?
if @browserMediaState?.id != activePackage.id
new window.Fingerprint2().get((result, components) => (
BrowserMediaActions.load(activePackage.id, [window.location.protocol + '//' + window.location.host + "/api/mixdowns/#{@jamTrack.activeMixdown.id}/download.mp3?file_type=mp3&sample_rate=48&mark=#{result}"], 'jamtrack_web_player')
))
@jamTrack.activeMixdown.client_state = 'downloading'
else
if @browserMediaState.loaded
@jamTrack.activeMixdown.client_state = 'ready'
else if @browserMediaState.load_error
@jamTrack.activeMixdown.client_state = 'download_fail'
else
@jamTrack.activeMixdown.client_state = 'downloading'
else if @jamTrack?
masterTrack = null
for jamTrackTrack in @jamTrack.tracks
if jamTrackTrack.track_type == 'Master'
masterTrack = jamTrackTrack
break
if @browserMediaState?.id != @jamTrack.id
BrowserMediaActions.load(@jamTrack.id, [masterTrack.preview_mp3_url], 'jamtrack_web_player')
@jamTrack.client_state = 'downloading'
else
if @browserMediaState.loaded
@jamTrack.client_state = 'ready'
else if @browserMediaState.load_error
@jamTrack.client_state = 'download_fail'
else
@jamTrack.client_state = 'downloading'
else
logger.error("unknown condition when processing manageMixdownSynchronization")
changed: () ->
@pickMyPackage()
@manageWatchedMixdowns()
@manageMixdownSynchronization()
@state = {
jamTrack: @jamTrack,
opened: @previous == null && @jamTrack != null,
closed: @previous != null && @jamTrack == null,
fullTrackActivated: @previousMixdown != null && @jamTrack?.activeMixdown == null}
@previous = @jamTrack
@previousMixdown = @jamTrack?.activeMixdown
this.trigger(@state)
onCreateMixdown: (mixdown, done, fail) ->
#volumeSettings = context.jamClient.GetJamTrackSettings();
#track_settings = []
#for track in volumeSettings.tracks
# track_settings.push({id: track.id, pan: track.pan, vol: track.vol_l, mute: track.mute})
#mixdown.settings.tracks = track_settings
logger.debug("creating mixdown", mixdown)
rest.createMixdown(mixdown)
.done((created) =>
@addMixdown(created)
logger.debug("created mixdown", created)
@onEnqueueMixdown({id: created.id}, done, fail)
)
.fail((jqxhr) =>
fail(jqxhr)
)
onEditMixdown: (mixdown) ->
logger.debug("editing mixdown", mixdown)
rest.editMixdown(mixdown)
.done((updatedMixdown) =>
logger.debug("edited mixdown")
@updateMixdown(updatedMixdown)
).fail((jqxhr) =>
@app.layout.notify({title:'Unable to Edit Custom Mix', text: 'The server was unable to edit this mix.'})
)
onDeleteMixdown: (mixdown) ->
logger.debug("deleting mixdown", mixdown)
rest.deleteMixdown(mixdown)
.done(() =>
logger.debug("deleted mixdown")
@deleteMixdown(mixdown)
)
.fail((jqxhr) =>
@app.layout.notify({title:'Unable to Deleted Custom Mix', text: 'The server was unable to delete this mix.'})
)
stopPlaying: () ->
alert("stop playing")
onOpenMixdown: (mixdown) ->
if @browserMediaState.loading
logger.warn("can not activate mixdown while browser media is loading")
return
logger.debug("opening mixdown", mixdown)
# check if it's already available in the backend or not
rest.markMixdownActive({id: @jamTrack.id, mixdown_id: mixdown.id})
.done((edited) =>
logger.debug("marked mixdown as active")
@jamTrack = edited
BrowserMediaActions.stop()
@changed()
)
.fail((jqxhr) =>
@app.layout.notify({title:'Unable to Edit Mixdown', text: 'Unable to mark this mixdown as active.'})
)
onOpenStem: (stem_id) ->
if @browserMediaState.loading
logger.warn("can not activate stem while browser media is loading")
return
logger.debug("opening stem", stem_id)
# check if it's already available in the backend or not
rest.markMixdownActive({id: @jamTrack.id, mixdown_id: null, stem_id: stem_id})
.done((edited) =>
logger.debug("marked stem as active")
@jamTrack = edited
BrowserMediaActions.stop()
@changed()
)
.fail((jqxhr) =>
@app.layout.notify({title:'Unable to Edit Mixdown', text: 'Unable to mark this mixdown as active.'})
)
onActivateNoMixdown: (jamTrack) ->
if @browserMediaState.loading
logger.warn("can not activate JamTrack while browser media is loading")
return
logger.debug("activating no mixdown")
rest.markMixdownActive({id: @jamTrack.id, mixdown_id: null})
.done((edited) =>
logger.debug("marked JamTrack as active")
@jamTrack = edited
@changed()
)
.fail((jqxhr) =>
@app.layout.notify({title:'Unable to Edit Mixdown', text: 'Unable to mark this mixdown as active.'})
)
onCloseMixdown: (mixdown) ->
logger.debug("closing mixdown", mixdown)
onEnqueueMixdown: (mixdown, done, fail) ->
logger.debug("enqueuing mixdown", mixdown)
package_settings = {file_type: 'mp3', encrypt_type: null, sample_rate: @sampleRate}
package_settings.id = mixdown.id
rest.enqueueMixdown(package_settings)
.done((enqueued) =>
@enqueuedMixdowns[mixdown.id] = {}
logger.debug("enqueued mixdown package", package_settings)
@addOrUpdatePackage(enqueued)
done(enqueued) if done
)
.fail((jqxhr) =>
@app.layout.notify({title:'Unable to Create Custom Mix', text: 'Click the error icon to retry.'})
fail(jqxhr) if fail?
)
onDownloadMixdown: (mixdown) ->
logger.debug("download mixdown", mixdown)
onRefreshMixdown: (mixdown) ->
logger.debug("refresh mixdown", mixdown)
addMixdown: (mixdown) ->
if @jamTrack?
logger.debug("adding mixdown to JamTrackStore", mixdown)
@jamTrack.mixdowns.splice(0, 0, mixdown)
@changed()
else
logger.warn("no jamtrack to add mixdown to in JamTrackStore", mixdown)
deleteMixdown: (mixdown) ->
if @jamTrack?
logger.debug("deleting mixdown from JamTrackStore", mixdown)
index = null
for matchMixdown, i in @jamTrack.mixdowns
if mixdown.id == matchMixdown.id
index = i
if index?
@jamTrack.mixdowns.splice(index, 1)
if @jamTrack.activeMixdown?.id == mixdown.id
@onActivateNoMixdown(@jamTrack)
@changed()
else
logger.warn("unable to find mixdown to delete in JamTrackStore", mixdown)
else
logger.warn("no jamtrack to delete mixdown for in JamTrackStore", mixdown)
updateMixdown: (mixdown) ->
if @jamTrack?
logger.debug("editing mixdown from JamTrackStore", mixdown)
index = null
for matchMixdown, i in @jamTrack.mixdowns
if mixdown.id == matchMixdown.id
index = i
if index?
@jamTrack.mixdowns[index] = mixdown
@changed()
else
logger.warn("unable to find mixdown to edit in JamTrackStore", mixdown)
else
logger.warn("no jamtrack to edit mixdown for in JamTrackStore", mixdown)
addOrUpdatePackage: (mixdown_package) ->
if @jamTrack?
added = false
index = null
for mixdown in @jamTrack.mixdowns
existing = false
if mixdown_package.jam_track_mixdown_id == mixdown.id
for possiblePackage, i in mixdown.packages
if possiblePackage.id == mixdown_package.id
existing = true
index = i
break
if existing
mixdown.packages[index] = mixdown_package
logger.debug("replacing mixdown package in JamTrackStore", mixdown_package)
else
mixdown.packages.splice(0, 0, mixdown_package)
logger.debug("adding mixdown package in JamTrackStore")
added = true
@changed()
break
if !added
logger.debug("couldn't find the mixdown associated with package in JamTrackStore", mixdown_package)
else
logger.warn("no mixdown to add package to in JamTrackStore", mixdown_package)
reportError: (mixdown) ->
enqueued = @enqueuedMixdowns[mixdown?.id]
# don't double-report
if !enqueued? || enqueued.marked
return
enqueued.marked = true
data = {
value: 1,
user_id: context.JK.currentUserId,
user_name: context.JK.currentUserName,
result: "signing state: #{mixdown.myPackage?.signing_state}, client state: #{mixdown.client_state}",
mixdown: mixdown.id,
package: mixdown.myPackage?.id
detail: mixdown.myPackage?.error_reason
}
rest.createAlert("Mixdown Sync failed for #{context.JK.currentUserName}", data)
context.stats.write('web.mixdown.error', data)
}
)