$ = 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 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("/popups/jamtrack-player/" + @jamTrack.id, 'Media Controls', 'scrollbars=yes,toolbar=no,status=no,height=667,width=450') @changed() 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 BrowserMediaActions.load(@jamTrack.activeStem.id, [window.location.protocol + '//' + window.location.host + "/api/jamtracks/#{@jamTrack.id}/stems/#{@jamTrack.activeStem.id}/download.mp3?file_type=mp3"], '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 BrowserMediaActions.load(activePackage.id, [window.location.protocol + '//' + window.location.host + "/api/mixdowns/#{@jamTrack.activeMixdown.id}/download.mp3?file_type=mp3&sample_rate=48"], '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) } )