1313 lines
59 KiB
CoffeeScript
1313 lines
59 KiB
CoffeeScript
$ = jQuery
|
|
context = window
|
|
context.JK ||= {};
|
|
|
|
context.JK.SyncViewer = class SyncViewer
|
|
constructor: (@app) ->
|
|
@EVENTS = context.JK.EVENTS
|
|
@rest = context.JK.Rest()
|
|
@logger = context.JK.logger
|
|
@recordingUtils = context.JK.RecordingUtils
|
|
@since = 0
|
|
@limit = 20
|
|
@showing = false
|
|
@downloadCommandId = null
|
|
@downloadMetadata = null
|
|
@uploadCommandId = null
|
|
@uploadMetadata = null
|
|
@cleanupCommandId = null
|
|
@cleanupMetadata = null
|
|
|
|
|
|
init: () =>
|
|
@root = $($('#template-sync-viewer').html())
|
|
@inProgress = @root.find('.in-progress')
|
|
@downloadProgress = @inProgress.find('.download-progress')
|
|
@uploadProgress = @inProgress.find('.upload-progress')
|
|
@list = @root.find('.list')
|
|
@logList = @root.find('.log-list')
|
|
@templateRecordedTrack = $('#template-sync-viewer-recorded-track')
|
|
@templateRecordedBackingTrack = $('#template-sync-viewer-recorded-backing-track')
|
|
@templateStreamMix = $('#template-sync-viewer-stream-mix')
|
|
@templateMix = $('#template-sync-viewer-mix')
|
|
@templateNoSyncs = $('#template-sync-viewer-no-syncs')
|
|
@templateRecordingWrapperDetails = $('#template-sync-viewer-recording-wrapper-details')
|
|
@templateHoverRecordedTrack = $('#template-sync-viewer-hover-recorded-track')
|
|
@templateHoverRecordedBackingTrack = $('#template-sync-viewer-hover-recorded-backing-track')
|
|
@templateHoverMix = $('#template-sync-viewer-hover-mix')
|
|
@templateDownloadReset = $('#template-sync-viewer-download-progress-reset')
|
|
@templateUploadReset = $('#template-sync-viewer-upload-progress-reset')
|
|
@templateGenericCommand = $('#template-sync-viewer-generic-command')
|
|
@templateRecordedTrackCommand = $('#template-sync-viewer-recorded-track-command')
|
|
@templateRecordedBackingTrackCommand = $('#template-sync-viewer-recorded-backing-track-command')
|
|
@templateLogItem = $('#template-sync-viewer-log-item')
|
|
@tabSelectors = @root.find('.dialog-tabs .tab')
|
|
@tabs = @root.find('.tab-content')
|
|
@logBadge = @tabSelectors.find('.badge')
|
|
@paginator = @root.find('.paginator-holder')
|
|
|
|
@uploadStates = {
|
|
unknown: 'unknown',
|
|
too_many_upload_failures: 'too-many-upload-failures',
|
|
me_upload_soon: 'me-upload-soon',
|
|
them_upload_soon: 'them-upload-soon'
|
|
missing: 'missing',
|
|
me_uploaded: 'me-uploaded',
|
|
them_uploaded: 'them-uploaded',
|
|
not_mine: 'not-mine'
|
|
}
|
|
@clientStates = {
|
|
unknown: 'unknown',
|
|
too_many_uploads: 'too-many-downloads',
|
|
hq: 'hq',
|
|
sq: 'sq',
|
|
missing: 'missing',
|
|
discarded: 'discarded',
|
|
not_mine: 'not-mine'
|
|
}
|
|
|
|
throw "no sync-viewer" if not @root.exists()
|
|
throw "no in-progress" if not @inProgress.exists()
|
|
throw "no list" if not @list.exists()
|
|
throw "no recorded track template" if not @templateRecordedTrack.exists()
|
|
throw "no stream mix template" if not @templateStreamMix.exists()
|
|
throw "no empty syncs template" if not @templateNoSyncs.exists()
|
|
|
|
$(document).on(@EVENTS.FILE_MANAGER_CMD_START, this.fileManagerCmdStart)
|
|
$(document).on(@EVENTS.FILE_MANAGER_CMD_STOP, this.fileManagerCmdStop)
|
|
$(document).on(@EVENTS.FILE_MANAGER_CMD_PROGRESS, this.fileManagerCmdProgress)
|
|
$(document).on(@EVENTS.FILE_MANAGER_CMD_ASAP_UPDATE, this.fileManagerAsapCommandStatus)
|
|
|
|
@tabSelectors.click((e) =>
|
|
$tabSelected = $(e.target).closest('a.tab')
|
|
purpose = $tabSelected.attr('purpose')
|
|
|
|
$otherTabSelectors = @tabSelectors.not('[purpose="' + purpose + '"]')
|
|
$otherTabs = @tabs.not('[purpose="' + purpose + '"]')
|
|
$tab = @tabs.filter('[purpose="' + purpose + '"]')
|
|
|
|
$otherTabs.hide();
|
|
$tab.show()
|
|
|
|
$otherTabSelectors.removeClass('selected');
|
|
$tabSelected.addClass('selected');
|
|
|
|
if purpose == 'log'
|
|
@logBadge.hide()
|
|
)
|
|
|
|
onShow: () =>
|
|
@showing = true
|
|
this.load()
|
|
|
|
onHide: () =>
|
|
@showing = false
|
|
#$(document).off(@EVENTS.FILE_MANAGER_CMD_START, this.fileManagerCmdStart)
|
|
#$(document).off(@EVENTS.FILE_MANAGER_CMD_STOP, this.fileManagerCmdStop)
|
|
#$(document).off(@EVENTS.FILE_MANAGER_CMD_PROGRESS, this.fileManagerCmdProgress)
|
|
|
|
getUserSyncs: (page) =>
|
|
@rest.getUserSyncs({since: page * @limit, limit: @limit})
|
|
.done(this.processUserSyncs)
|
|
|
|
|
|
load: () =>
|
|
@list.empty()
|
|
@since = 0
|
|
|
|
this.renderHeader()
|
|
|
|
this.getUserSyncs(0)
|
|
.done((response) =>
|
|
$paginator = context.JK.Paginator.create(response.total_entries, @limit, 0, this.getUserSyncs)
|
|
@paginator.empty().append($paginator);
|
|
)
|
|
|
|
|
|
renderHeader: () =>
|
|
recordingManagerState = context.jamClient.GetRecordingManagerState()
|
|
if recordingManagerState.running
|
|
@uploadProgress.removeClass('quiet paused busy')
|
|
@downloadProgress.removeClass('quiet paused busy')
|
|
|
|
if recordingManagerState.current_download
|
|
@downloadProgress.addClass('busy')
|
|
else
|
|
@downloadProgress.addClass('quiet')
|
|
@downloadProgress.find('.busy').empty()
|
|
|
|
if recordingManagerState.current_upload
|
|
@uploadProgress.addClass('busy')
|
|
else
|
|
@uploadProgress.addClass('quiet')
|
|
@uploadProgress.find('.busy').empty()
|
|
else
|
|
@downloadProgress.removeClass('quiet paused busy').addClass('paused')
|
|
@uploadProgress.removeClass('quiet paused busy').addClass('paused')
|
|
@downloadProgress.find('.busy').empty()
|
|
@uploadProgress.find('.busy').empty()
|
|
|
|
updateMixState: ($mix) =>
|
|
serverInfo = $mix.data('server-info')
|
|
|
|
mixInfo = @recordingUtils.createMixInfo(serverInfo)
|
|
|
|
$mixState = $mix.find('.mix-state')
|
|
$mixStateMsg = $mixState.find('.msg')
|
|
$mixStateProgress = $mixState.find('.progress')
|
|
$mixState.removeClass('still-uploading discarded unknown mixed mixing waiting-to-mix error stream-mix').addClass(mixInfo.mixStateClass).attr('data-state', mixInfo.mixState).data('mix-state', mixInfo)
|
|
$mixStateMsg.text(mixInfo.mixStateMsg)
|
|
$mixStateProgress.css('width', '0')
|
|
|
|
updateStreamMixState: ($streamMix) =>
|
|
clientInfo = $streamMix.data('client-info')
|
|
serverInfo = $streamMix.data('server-info')
|
|
|
|
# determine client state
|
|
clientStateMsg = 'UNKNOWN'
|
|
clientStateClass = 'unknown'
|
|
clientState = @clientStates.unknown
|
|
|
|
if clientInfo?
|
|
if clientInfo.local_state == 'COMPRESSED'
|
|
clientStateMsg = 'STREAM QUALITY'
|
|
clientStateClass = 'sq'
|
|
clientState = @clientStates.sq
|
|
else if clientInfo.local_state == 'UNCOMPRESSED'
|
|
clientStateMsg = 'STREAM QUALITY'
|
|
clientStateClass = 'sq'
|
|
clientState = @clientStates.sq
|
|
else if clientInfo.local_state == 'MISSING'
|
|
clientStateMsg = 'MISSING'
|
|
clientStateClass = 'missing'
|
|
clientState = @clientStates.missing
|
|
|
|
# determine upload state
|
|
uploadStateMsg = 'UNKNOWN'
|
|
uploadStateClass = 'unknown'
|
|
uploadState = @uploadStates.unknown
|
|
|
|
if !serverInfo.fully_uploaded
|
|
if serverInfo.upload.too_many_upload_failures
|
|
uploadStateMsg = 'UPLOAD FAILURE'
|
|
uploadStateClass = 'error'
|
|
uploadState = @uploadStates.too_many_upload_failures
|
|
else
|
|
if clientInfo?
|
|
if clientInfo.local_state == 'UNCOMPRESSED' or clientInfo.local_state == 'COMPRESSED'
|
|
uploadStateMsg = 'PENDING UPLOAD'
|
|
uploadStateClass = 'upload-soon'
|
|
uploadState = @uploadStates.me_upload_soon
|
|
else
|
|
uploadStateMsg = 'MISSING'
|
|
uploadStateClass = 'missing'
|
|
uploadState = @uploadStates.missing
|
|
else
|
|
uploadStateMsg = 'MISSING'
|
|
uploadStateClass = 'missing'
|
|
uploadState = @uploadStates.missing
|
|
else
|
|
uploadStateMsg = 'UPLOADED'
|
|
uploadStateClass = 'uploaded'
|
|
uploadState = @uploadStates.me_uploaded
|
|
|
|
$clientState = $streamMix.find('.client-state')
|
|
$clientStateMsg = $clientState.find('.msg')
|
|
$clientStateProgress = $clientState.find('.progress')
|
|
$uploadState = $streamMix.find('.upload-state')
|
|
$uploadStateMsg = $uploadState.find('.msg')
|
|
$uploadStateProgress = $uploadState.find('.progress')
|
|
|
|
$clientState.removeClass('discarded missing sq hq unknown error').addClass(clientStateClass).attr('data-state', clientState).data('custom-class', clientStateClass)
|
|
$clientStateMsg.text(clientStateMsg)
|
|
$clientStateProgress.css('width', '0')
|
|
$uploadState.removeClass('upload-soon error unknown missing uploaded').addClass(uploadStateClass).attr('data-state', uploadState).data('custom-class', uploadStateClass)
|
|
$uploadStateMsg.text(uploadStateMsg)
|
|
$uploadStateProgress.css('width', '0')
|
|
|
|
updateTrackState: ($track) =>
|
|
clientInfo = $track.data('client-info')
|
|
serverInfo = $track.data('server-info')
|
|
myTrack = serverInfo.user.id == context.JK.currentUserId
|
|
|
|
# determine client state
|
|
clientStateMsg = 'UNKNOWN'
|
|
clientStateClass = 'unknown'
|
|
clientState = @clientStates.unknown
|
|
|
|
if serverInfo.download.should_download
|
|
if serverInfo.download.too_many_downloads
|
|
clientStateMsg = 'EXCESS DOWNLOADS'
|
|
clientStateClass = 'error'
|
|
clientState = @clientStates.too_many_uploads
|
|
else
|
|
if clientInfo?
|
|
if clientInfo.local_state == 'HQ'
|
|
clientStateMsg = 'HIGHEST QUALITY'
|
|
clientStateClass = 'hq'
|
|
clientState = @clientStates.hq
|
|
else
|
|
clientStateMsg = 'STREAM QUALITY'
|
|
clientStateClass = 'sq'
|
|
clientState = @clientStates.sq
|
|
else
|
|
clientStateMsg = 'MISSING'
|
|
clientStateClass = 'missing'
|
|
clientState = @clientStates.missing
|
|
else
|
|
clientStateMsg = 'DISCARDED'
|
|
clientStateClass = 'discarded'
|
|
clientState = @clientStates.discarded
|
|
|
|
# determine upload state
|
|
uploadStateMsg = 'UNKNOWN'
|
|
uploadStateClass = 'unknown'
|
|
uploadState = @uploadStates.unknown
|
|
|
|
if !serverInfo.fully_uploaded
|
|
if serverInfo.upload.too_many_upload_failures
|
|
uploadStateMsg = 'UPLOAD FAILURE'
|
|
uploadStateClass = 'error'
|
|
uploadState = @uploadStates.too_many_upload_failures
|
|
else
|
|
if myTrack
|
|
if clientInfo?
|
|
if clientInfo.local_state == 'HQ'
|
|
uploadStateMsg = 'PENDING UPLOAD'
|
|
uploadStateClass = 'upload-soon'
|
|
uploadState = @uploadStates.me_upload_soon
|
|
else
|
|
uploadStateMsg = 'MISSING'
|
|
uploadStateClass = 'missing'
|
|
uploadState = @uploadStates.missing
|
|
else
|
|
uploadStateMsg = 'MISSING'
|
|
uploadStateClass = 'missing'
|
|
uploadState = @uploadStates.missing
|
|
else
|
|
uploadStateMsg = 'PENDING UPLOAD'
|
|
uploadStateClass = 'upload-soon'
|
|
uploadState = @uploadStates.them_upload_soon
|
|
else
|
|
uploadStateMsg = 'UPLOADED'
|
|
uploadStateClass = 'uploaded'
|
|
if myTrack
|
|
uploadState = @uploadStates.me_uploaded
|
|
else
|
|
uploadState = @uploadStates.them_uploaded
|
|
|
|
$clientState = $track.find('.client-state')
|
|
$clientStateMsg = $clientState.find('.msg')
|
|
$clientStateProgress = $clientState.find('.progress')
|
|
$uploadState = $track.find('.upload-state')
|
|
$uploadStateMsg = $uploadState.find('.msg')
|
|
$uploadStateProgress = $uploadState.find('.progress')
|
|
|
|
$clientState.removeClass('discarded missing sq hq unknown error').addClass(clientStateClass).attr('data-state', clientState).data('custom-class', clientStateClass)
|
|
$clientStateMsg.text(clientStateMsg)
|
|
$clientStateProgress.css('width', '0')
|
|
$uploadState.removeClass('upload-soon error unknown missing uploaded').addClass(uploadStateClass).attr('data-state', uploadState).data('custom-class', uploadStateClass)
|
|
$uploadStateMsg.text(uploadStateMsg)
|
|
$uploadStateProgress.css('width', '0')
|
|
|
|
# this allows us to make styling decisions based on the combination of both client and upload state.
|
|
$track.addClass("clientState-#{clientStateClass}").addClass("uploadState-#{uploadStateClass}")
|
|
|
|
$clientRetry = $clientState.find('.retry')
|
|
$uploadRetry = $uploadState.find('.retry')
|
|
|
|
if gon.isNativeClient
|
|
# handle client state
|
|
|
|
# only show RETRY button if you have a SQ or if it's missing, and it's been uploaded already
|
|
if (clientState == @clientStates.sq or clientState == @clientStates.missing) and (uploadState == @uploadStates.me_uploaded or uploadState == @uploadStates.them_uploaded)
|
|
$clientRetry.show()
|
|
else
|
|
$clientRetry.hide()
|
|
|
|
# only show RETRY button if you have the HQ track, it's your track, and the server doesn't yet have it
|
|
if myTrack and @clientStates.hq and (uploadState == @uploadStates.error or uploadState == @uploadStates.me_upload_soon)
|
|
$uploadRetry.show()
|
|
else
|
|
$uploadRetry.hide()
|
|
else
|
|
$clientRetry.hide()
|
|
$uploadRetry.hide()
|
|
|
|
updateBackingTrackState: ($track) =>
|
|
clientInfo = $track.data('client-info')
|
|
serverInfo = $track.data('server-info')
|
|
myTrack = serverInfo.user.id == context.JK.currentUserId
|
|
|
|
# determine client state
|
|
clientStateMsg = 'UNKNOWN'
|
|
clientStateClass = 'unknown'
|
|
clientState = @clientStates.unknown
|
|
|
|
if serverInfo.mine
|
|
if serverInfo.download.should_download
|
|
if serverInfo.download.too_many_downloads
|
|
clientStateMsg = 'EXCESS DOWNLOADS'
|
|
clientStateClass = 'error'
|
|
clientState = @clientStates.too_many_uploads
|
|
else
|
|
if clientInfo?
|
|
if clientInfo.local_state == 'HQ'
|
|
clientStateMsg = 'HIGHEST QUALITY'
|
|
clientStateClass = 'hq'
|
|
clientState = @clientStates.hq
|
|
else if clientInfo.local_state == 'MISSING'
|
|
clientStateMsg = 'MISSING'
|
|
clientStateClass = 'missing'
|
|
clientState = @clientStates.missing
|
|
else
|
|
clientStateMsg = 'MISSING'
|
|
clientStateClass = 'missing'
|
|
clientState = @clientStates.missing
|
|
else
|
|
clientStateMsg = 'DISCARDED'
|
|
clientStateClass = 'discarded'
|
|
clientState = @clientStates.discarded
|
|
else
|
|
clientStateMsg = 'NOT MINE'
|
|
clientStateClass = 'not_mine'
|
|
clientState = @clientStates.not_mine
|
|
|
|
# determine upload state
|
|
uploadStateMsg = 'UNKNOWN'
|
|
uploadStateClass = 'unknown'
|
|
uploadState = @uploadStates.unknown
|
|
|
|
if serverInfo.mine
|
|
if !serverInfo.fully_uploaded
|
|
if serverInfo.upload.too_many_upload_failures
|
|
uploadStateMsg = 'UPLOAD FAILURE'
|
|
uploadStateClass = 'error'
|
|
uploadState = @uploadStates.too_many_upload_failures
|
|
else
|
|
if myTrack
|
|
if clientInfo?
|
|
if clientInfo.local_state == 'HQ'
|
|
uploadStateMsg = 'PENDING UPLOAD'
|
|
uploadStateClass = 'upload-soon'
|
|
uploadState = @uploadStates.me_upload_soon
|
|
else
|
|
uploadStateMsg = 'MISSING'
|
|
uploadStateClass = 'missing'
|
|
uploadState = @uploadStates.missing
|
|
else
|
|
uploadStateMsg = 'MISSING'
|
|
uploadStateClass = 'missing'
|
|
uploadState = @uploadStates.missing
|
|
else
|
|
uploadStateMsg = 'PENDING UPLOAD'
|
|
uploadStateClass = 'upload-soon'
|
|
uploadState = @uploadStates.them_upload_soon
|
|
else
|
|
uploadStateMsg = 'UPLOADED'
|
|
uploadStateClass = 'uploaded'
|
|
if myTrack
|
|
uploadState = @uploadStates.me_uploaded
|
|
else
|
|
uploadState = @uploadStates.them_uploaded
|
|
else
|
|
uploadStateMsg = 'NOT MINE'
|
|
uploadStateClass = 'not_mine'
|
|
uploadState = @uploadStates.not_mine
|
|
|
|
|
|
$clientState = $track.find('.client-state')
|
|
$clientStateMsg = $clientState.find('.msg')
|
|
$clientStateProgress = $clientState.find('.progress')
|
|
$uploadState = $track.find('.upload-state')
|
|
$uploadStateMsg = $uploadState.find('.msg')
|
|
$uploadStateProgress = $uploadState.find('.progress')
|
|
|
|
$clientState.removeClass('discarded missing hq unknown error not-mine').addClass(clientStateClass).attr('data-state', clientState).data('custom-class', clientStateClass)
|
|
$clientStateMsg.text(clientStateMsg)
|
|
$clientStateProgress.css('width', '0')
|
|
$uploadState.removeClass('upload-soon error unknown missing uploaded not-mine').addClass(uploadStateClass).attr('data-state', uploadState).data('custom-class', uploadStateClass)
|
|
$uploadStateMsg.text(uploadStateMsg)
|
|
$uploadStateProgress.css('width', '0')
|
|
|
|
# this allows us to make styling decisions based on the combination of both client and upload state.
|
|
$track.addClass("clientState-#{clientStateClass}").addClass("uploadState-#{uploadStateClass}")
|
|
|
|
$clientRetry = $clientState.find('.retry')
|
|
$uploadRetry = $uploadState.find('.retry')
|
|
|
|
if gon.isNativeClient
|
|
# handle client state
|
|
|
|
# only show RETRY button if you have a SQ or if it's missing, and it's been uploaded already
|
|
if (clientState == @clientStates.missing) and (uploadState == @uploadStates.me_uploaded or uploadState == @uploadStates.them_uploaded)
|
|
$clientRetry.show()
|
|
else
|
|
$clientRetry.hide()
|
|
|
|
# only show RETRY button if you have the HQ track, it's your track, and the server doesn't yet have it
|
|
if myTrack and @clientStates.hq and (uploadState == @uploadStates.error or uploadState == @uploadStates.me_upload_soon)
|
|
$uploadRetry.show()
|
|
else
|
|
$uploadRetry.hide()
|
|
else
|
|
$clientRetry.hide()
|
|
$uploadRetry.hide()
|
|
|
|
|
|
associateClientInfo: (recording) =>
|
|
for clientInfo in recording.local_tracks
|
|
$track = @list.find(".recorded-track[data-recording-id='#{recording.recording_id}'][data-client-track-id='#{clientInfo.client_track_id}']")
|
|
$track.data('client-info', clientInfo)
|
|
$track.data('total-size', recording.size)
|
|
|
|
for clientInfo in recording.backing_tracks
|
|
$track = @list.find(".recorded-backing-track[data-recording-id='#{recording.recording_id}'][data-client-track-id='#{clientInfo.client_track_id}']")
|
|
$track.data('client-info', clientInfo)
|
|
$track.data('total-size', recording.size)
|
|
|
|
$track = @list.find(".mix[data-recording-id='#{recording.recording_id}']")
|
|
$track.data('client-info', recording.mix)
|
|
$track.data('total-size', recording.size)
|
|
|
|
$track = @list.find(".stream-mix[data-recording-id='#{recording.recording_id}']")
|
|
$track.data('client-info', recording.stream_mix)
|
|
$track.data('total-size', recording.size)
|
|
|
|
displayStreamMixHover: ($streamMix) =>
|
|
$clientState = $streamMix.find('.client-state')
|
|
$clientStateMsg = $clientState.find('.msg')
|
|
clientStateClass = $clientState.data('custom-class')
|
|
clientState = $clientState.attr('data-state')
|
|
clientInfo = $streamMix.data('client-info')
|
|
|
|
$uploadState = $streamMix.find('.upload-state')
|
|
$uploadStateMsg = $uploadState.find('.msg')
|
|
uploadStateClass = $uploadState.data('custom-class')
|
|
uploadState = $uploadState.attr('data-state')
|
|
serverInfo = $streamMix.data('server-info')
|
|
|
|
# decide on special case strings first
|
|
|
|
summary = ''
|
|
if clientState == @clientStates.sq && uploadState == @uploadStates.me_upload_soon
|
|
summary = "We will attempt to upload your stream mix so that others can hear the recording on the JamKazam site, even before the final mix is done. It will upload shortly."
|
|
else if clientState == @clientStates.sq && uploadState == @uploadStates.me_uploaded
|
|
# we have the SQ version, and the other user has uploaded the HQ version... it's coming soon!
|
|
summary = "We already uploaded your stream mix so that others can hear the recording on the JamKazam site, even before the final mix is done. Since it's uploaded, there is nothing else left to do with the stream mix... you're all done!"
|
|
else if clientState == @clientStates.missing
|
|
summary = "You do not have the stream mix on your computer anymore. This can happen if you change the computer that you run JamKazam on. It's important to note that once a final mix for the recording is available, there is no value in the stream mix."
|
|
|
|
clientStateDefinition = switch clientState
|
|
when @clientStates.sq then "The stream mix is always STREAM QUALITY, because it's the version of the recording that you heard in your earphones as you made the recording."
|
|
when @clientStates.missing then "MISSING means you do not have the stream mix anymore."
|
|
else 'There is no help for this state'
|
|
|
|
uploadStateDefinition = switch uploadState
|
|
when @uploadStates.too_many_upload_failures then "Failed attempts at uploading this stream mix has happened an unusually large times. No more uploads will be attempted."
|
|
when @uploadStates.me_upload_soon then "PENDING UPLOAD means your JamKazam application will upload this stream mix soon."
|
|
when @uploadStates.me_uploaded then "UPLOADED means you have already uploaded this stream mix."
|
|
when @uploadStates.missing then "MISSING means your JamKazam application does not have this stream mix, and the server does not either."
|
|
|
|
context._.template(@templateHoverRecordedTrack.html(),
|
|
{summary: summary,
|
|
clientStateDefinition: clientStateDefinition,
|
|
uploadStateDefinition: uploadStateDefinition,
|
|
clientStateMsg: $clientStateMsg.text(),
|
|
uploadStateMsg: $uploadStateMsg.text(),
|
|
clientStateClass: clientStateClass,
|
|
uploadStateClass: uploadStateClass}
|
|
{variable: 'data'})
|
|
|
|
displayTrackHover: ($recordedTrack) =>
|
|
$clientState = $recordedTrack.find('.client-state')
|
|
$clientStateMsg = $clientState.find('.msg')
|
|
clientStateClass = $clientState.data('custom-class')
|
|
clientState = $clientState.attr('data-state')
|
|
clientInfo = $recordedTrack.data('client-info')
|
|
|
|
$uploadState = $recordedTrack.find('.upload-state')
|
|
$uploadStateMsg = $uploadState.find('.msg')
|
|
uploadStateClass = $uploadState.data('custom-class')
|
|
uploadState = $uploadState.attr('data-state')
|
|
serverInfo = $recordedTrack.data('server-info')
|
|
|
|
# decide on special case strings first
|
|
|
|
summary = ''
|
|
if clientState == @clientStates.sq && uploadState == @uploadStates.them_upload_soon
|
|
# we have the SQ version, and the other user hasn't uploaded it yet
|
|
summary = "#{serverInfo.user.name} has not yet uploaded the high-quality version of this track. Once he or she does, JamKazam will download it and replace your stream-quality version."
|
|
else if clientState == @clientStates.missing && uploadState == @uploadStates.them_upload_soon
|
|
# we don't have any version of the track at all, and the other user hasn't uploaded it yet
|
|
summary = "#{serverInfo.user.name} has not yet uploaded the high-quality version of this track. Once he or she does, JamKazam will download it and this track will no longer be missing."
|
|
else if clientState == @clientStates.sq && uploadState == @uploadStates.them_uploaded
|
|
# we have the SQ version, and the other user has uploaded the HQ version... it's coming soon!
|
|
summary = "#{serverInfo.user.name} has uploaded the high-quality version of this track. JamKazam will soon download it and replace your stream-quality version."
|
|
else if clientState == @clientStates.missing && uploadState == @uploadStates.them_uploaded
|
|
# we have no version of the track at all, and the other user has uploaded the HQ version... it's coming soon!
|
|
summary = "#{serverInfo.user.name} has uploaded the high-quality version of this track. JamKazam will soon restore it and then this track will no longer be missing."
|
|
else if clientState == @clientStates.sq && uploadState == @uploadStates.me_uploaded
|
|
# we have the SQ version, and the other user has uploaded the HQ version... it's coming soon!
|
|
summary = "You have previously uploaded the high-quality version of this track. JamKazam will soon restore it and replace your stream-quality version."
|
|
else if clientState == @clientStates.missing && uploadState == @uploadStates.me_uploaded
|
|
# we have no version of the track at all, and the other user has uploaded the HQ version... it's coming soon!
|
|
summary = "You have previously uploaded the high-quality version of this track. JamKazam will soon restore it and then this track will no longer be missing."
|
|
else if clientState == @clientStates.discarded && (uploadState == @uploadStates.me_uploaded or uploadState == @uploadStates.them_uploaded)
|
|
# we decided not to keep the recording... so it's important to clarify why they are seeing it at all
|
|
summary = "When this recording was made, you elected to not keep it. JamKazam already uploaded your high-quality tracks for the recording, because at least one other person decided to keep the recording and needs your tracks to make a high-quality mix."
|
|
else if clientState == @clientStates.discarded
|
|
# we decided not to keep the recording... so it's important to clarify why they are seeing it at all
|
|
summary = "When this recording was made, you elected to not keep it. JamKazam will still try to upload your high-quality tracks for the recording, because at least one other person decided to keep the recording and needs your tracks to make a high-quality mix."
|
|
else if clientState == @clientStates.hq and ( uploadState == @uploadStates.them_uploaded or uploadState == @uploadStates.me_uploaded )
|
|
summary = "Both you and the JamKazam server have the high-quality version of this track. Once all the other tracks for this recording are also synchronized, then the final mix can be made."
|
|
|
|
clientStateDefinition = switch clientState
|
|
when @clientStates.too_many_downloads then "This track has been downloaded an unusually large number of times. No more downloads are allowed."
|
|
when @clientStates.hq then "HIGHEST QUALITY means you have the original version of this track, as recorded by the user that made it."
|
|
when @clientStates.sq then "STREAM QUALITY means you have the version of the track that you received over the internet in real-time."
|
|
when @clientStates.missing then "MISSING means you do not have this track anymore."
|
|
when @clientStates.discarded then "DISCARDED means you chose to not keep this recording when the recording was over."
|
|
else 'There is no help for this state'
|
|
|
|
uploadStateDefinition = switch uploadState
|
|
when @uploadStates.too_many_upload_failures then "Failed attempts at uploading this track has happened an unusually large times. No more uploads will be attempted."
|
|
when @uploadStates.me_upload_soon then "PENDING UPLOAD means your JamKazam application will upload this track soon."
|
|
when @uploadStates.them_up_soon then "PENDING UPLOAD means #{serverInfo.user.name} will upload this track soon."
|
|
when @uploadStates.me_uploaded then "UPLOADED means you have already uploaded this track."
|
|
when @uploadStates.them_uploaded then "UPLOADED means #{serverInfo.user.name} has already uploaded this track."
|
|
when @uploadStates.missing then "MISSING means your JamKazam application does not have this track, and the server does not either."
|
|
|
|
context._.template(@templateHoverRecordedTrack.html(),
|
|
{summary: summary,
|
|
clientStateDefinition: clientStateDefinition,
|
|
uploadStateDefinition: uploadStateDefinition,
|
|
clientStateMsg: $clientStateMsg.text(),
|
|
uploadStateMsg: $uploadStateMsg.text(),
|
|
clientStateClass: clientStateClass,
|
|
uploadStateClass: uploadStateClass}
|
|
{variable: 'data'})
|
|
|
|
displayBackingTrackHover: ($recordedTrack) =>
|
|
$clientState = $recordedTrack.find('.client-state')
|
|
$clientStateMsg = $clientState.find('.msg')
|
|
clientStateClass = $clientState.data('custom-class')
|
|
clientState = $clientState.attr('data-state')
|
|
clientInfo = $recordedTrack.data('client-info')
|
|
|
|
$uploadState = $recordedTrack.find('.upload-state')
|
|
$uploadStateMsg = $uploadState.find('.msg')
|
|
uploadStateClass = $uploadState.data('custom-class')
|
|
uploadState = $uploadState.attr('data-state')
|
|
serverInfo = $recordedTrack.data('server-info')
|
|
|
|
# decide on special case strings first
|
|
|
|
summary = ''
|
|
if clientState == @clientStates.not_mine && @uploadStates.them_uploaded
|
|
# this is not our backing track
|
|
summary = "#{serverInfo.user.name} opened this backing track. Due to legal concerns, we can not distribute it to you."
|
|
else if clientState == @clientStates.not_mine && @uploadStates.them_upload_soon
|
|
# this is not our backing track
|
|
summary = "#{serverInfo.user.name} has not yet uploaded their backing track."
|
|
else if clientState == @clientStates.missing && uploadState == @uploadStates.me_uploaded
|
|
# we have no version of the track at all, and the other user has uploaded the HQ version... it's coming soon!
|
|
summary = "You have previously uploaded the high-quality version of this track. JamKazam will soon restore it and then this backing track will no longer be missing."
|
|
else if clientState == @clientStates.discarded && (uploadState == @uploadStates.me_uploaded or uploadState == @uploadStates.them_uploaded)
|
|
# we decided not to keep the recording... so it's important to clarify why they are seeing it at all
|
|
summary = "When this recording was made, you elected to not keep it. JamKazam already uploaded your high-quality backing track for the recording, because at least one other person decided to keep the recording and needs your backing track to make a high-quality mix."
|
|
else if clientState == @clientStates.discarded
|
|
# we decided not to keep the recording... so it's important to clarify why they are seeing it at all
|
|
summary = "When this recording was made, you elected to not keep it. JamKazam will still try to upload your high-quality backing track for the recording, because at least one other person decided to keep the recording and needs your backing track to make a high-quality mix."
|
|
else if clientState == @clientStates.hq and ( uploadState == @uploadStates.me_uploaded )
|
|
summary = "Both you and the JamKazam server have the high-quality version of this track. Once all the other tracks for this recording are also synchronized, then the final mix can be made."
|
|
|
|
clientStateDefinition = switch clientState
|
|
when @clientStates.too_many_downloads then "This backing track has been downloaded an unusually large number of times. No more downloads are allowed."
|
|
when @clientStates.hq then "HIGHEST QUALITY means you have the original version of this backing track."
|
|
when @clientStates.missing then "MISSING means you do not have this backing track anymore."
|
|
when @clientStates.discarded then "DISCARDED means you chose to not keep this recording when the recording was over."
|
|
when @clientStates.not_mine then "NOT MINE means someone else opened and played this backing track."
|
|
else 'There is no help for this state'
|
|
|
|
uploadStateDefinition = switch uploadState
|
|
when @uploadStates.too_many_upload_failures then "Failed attempts at uploading this backing track has happened an unusually large times. No more uploads will be attempted."
|
|
when @uploadStates.me_upload_soon then "PENDING UPLOAD means your JamKazam application will upload this backing track soon."
|
|
when @uploadStates.them_up_soon then "PENDING UPLOAD means #{serverInfo.user.name} will upload this backing track soon."
|
|
when @uploadStates.me_uploaded then "UPLOADED means you have already uploaded this backing track."
|
|
when @uploadStates.them_uploaded then "UPLOADED means #{serverInfo.user.name} has already uploaded this backing track."
|
|
when @uploadStates.missing then "MISSING means your JamKazam application does not have this backing track, and the server does not either."
|
|
when @uploadStates.not_mine then "NOT MINE means someone else opened and played this backing track."
|
|
|
|
context._.template(@templateHoverRecordedBackingTrack.html(),
|
|
{summary: summary,
|
|
clientStateDefinition: clientStateDefinition,
|
|
uploadStateDefinition: uploadStateDefinition,
|
|
clientStateMsg: $clientStateMsg.text(),
|
|
uploadStateMsg: $uploadStateMsg.text(),
|
|
clientStateClass: clientStateClass,
|
|
uploadStateClass: uploadStateClass}
|
|
{variable: 'data'})
|
|
|
|
onTrackHoverOfStateIndicator: () ->
|
|
$recordedTrack = $(this).closest('.recorded-track.sync')
|
|
self = $recordedTrack.data('sync-viewer')
|
|
self.displayTrackHover($recordedTrack)
|
|
|
|
onBackingTrackHoverOfStateIndicator: () ->
|
|
$recordedTrack = $(this).closest('.recorded-backing-track.sync')
|
|
self = $recordedTrack.data('sync-viewer')
|
|
self.displayBackingTrackHover($recordedTrack)
|
|
|
|
onStreamMixHover: () ->
|
|
$streamMix = $(this).closest('.stream-mix.sync')
|
|
self = $streamMix.data('sync-viewer')
|
|
self.displayStreamMixHover($streamMix)
|
|
|
|
resetDownloadProgress: () =>
|
|
@downloadProgress
|
|
|
|
resetUploadProgress: () =>
|
|
@uploadProgress
|
|
|
|
sendCommand: ($retry, cmd) =>
|
|
|
|
if context.SessionStore.inSession()
|
|
context.JK.ackBubble($retry, 'sync-viewer-paused', {}, {offsetParent: $retry.closest('.dialog')})
|
|
else
|
|
context.jamClient.OnTrySyncCommand(cmd)
|
|
context.JK.ackBubble($retry, 'sync-viewer-retry', {}, {offsetParent: $retry.closest('.dialog')})
|
|
|
|
|
|
retryDownloadRecordedTrack: (e) =>
|
|
$retry = $(e.target)
|
|
$track = $retry.closest('.recorded-track')
|
|
serverInfo = $track.data('server-info')
|
|
|
|
this.sendCommand($retry, {
|
|
type: 'recorded_track',
|
|
action: 'download'
|
|
queue: 'download',
|
|
recording_id: serverInfo.recording_id
|
|
track_id: serverInfo.client_track_id
|
|
})
|
|
|
|
return false
|
|
|
|
retryUploadRecordedTrack: (e) =>
|
|
$retry = $(e.target)
|
|
$track = $retry.closest('.recorded-track')
|
|
serverInfo = $track.data('server-info')
|
|
|
|
this.sendCommand($retry, {
|
|
type: 'recorded_track',
|
|
action: 'upload'
|
|
queue: 'upload',
|
|
recording_id: serverInfo.recording_id
|
|
track_id: serverInfo.client_track_id
|
|
})
|
|
|
|
return false
|
|
|
|
retryDownloadRecordedBackingTrack: (e) =>
|
|
$retry = $(e.target)
|
|
$track = $retry.closest('.recorded-backing-track')
|
|
serverInfo = $track.data('server-info')
|
|
|
|
console.log("track serverInfo", $track, serverInfo)
|
|
this.sendCommand($retry, {
|
|
type: 'recorded_backing_track',
|
|
action: 'download'
|
|
queue: 'download',
|
|
recording_id: serverInfo.recording_id
|
|
track_id: serverInfo.client_track_id
|
|
})
|
|
|
|
return false
|
|
|
|
retryUploadRecordedBackingTrack: (e) =>
|
|
$retry = $(e.target)
|
|
$track = $retry.closest('.recorded-backing-track')
|
|
serverInfo = $track.data('server-info')
|
|
|
|
console.log("track serverInfo", $track, serverInfo)
|
|
|
|
this.sendCommand($retry, {
|
|
type: 'recorded_backing_track',
|
|
action: 'upload'
|
|
queue: 'upload',
|
|
recording_id: serverInfo.recording_id
|
|
track_id: serverInfo.client_track_id
|
|
})
|
|
|
|
return false
|
|
|
|
createMix: (userSync) =>
|
|
recordingInfo = null
|
|
if userSync == 'fake'
|
|
recordingInfo = arguments[1]
|
|
# sift through the recorded_tracks in here; if they are marked discarded, then we can also mark this one discarded too
|
|
discarded = true
|
|
for claim in recordingInfo.claimed_recordings
|
|
if claim.user_id == context.JK.currentUserId
|
|
discarded = false
|
|
break
|
|
|
|
userSync = { recording_id: recordingInfo.id, duration: recordingInfo.duration, fake:true, discarded: discarded }
|
|
$mix = $(context._.template(@templateMix.html(), userSync, {variable: 'data'}))
|
|
else
|
|
$mix = $(context._.template(@templateMix.html(), userSync, {variable: 'data'}))
|
|
|
|
$mix.data('server-info', userSync)
|
|
$mix.data('sync-viewer', this)
|
|
$mix.data('view-context', 'sync')
|
|
$mixState = $mix.find('.mix-state')
|
|
this.updateMixState($mix)
|
|
context.JK.hoverBubble($mixState, @recordingUtils.onMixHover, {width:'450px', closeWhenOthersOpen: true, positions:['left'], trigger:['hoverIntent', 'none']})
|
|
$mix
|
|
|
|
createTrack: (userSync) =>
|
|
$track = $(context._.template(@templateRecordedTrack.html(), userSync, {variable: 'data'}))
|
|
$track.data('server-info', userSync)
|
|
$track.data('sync-viewer', this)
|
|
$clientState = $track.find('.client-state')
|
|
$uploadState = $track.find('.upload-state')
|
|
$clientStateRetry = $clientState.find('.retry')
|
|
$clientStateRetry.click(this.retryDownloadRecordedTrack)
|
|
$uploadStateRetry = $uploadState.find('.retry')
|
|
$uploadStateRetry.click(this.retryUploadRecordedTrack)
|
|
context.JK.bindHoverEvents($track)
|
|
context.JK.bindInstrumentHover($track, {positions:['top'], shrinkToFit: true});
|
|
context.JK.hoverBubble($clientState, this.onTrackHoverOfStateIndicator, {width:'450px', closeWhenOthersOpen: true, positions:['left']})
|
|
context.JK.hoverBubble($uploadState, this.onTrackHoverOfStateIndicator, {width:'450px', closeWhenOthersOpen: true, positions:['right']})
|
|
$clientState.addClass('is-native-client') if gon.isNativeClient
|
|
$uploadState.addClass('is-native-client') if gon.isNativeClient
|
|
$track
|
|
|
|
createBackingTrack: (userSync) =>
|
|
$track = $(context._.template(@templateRecordedBackingTrack.html(), userSync, {variable: 'data'}))
|
|
$track.data('server-info', userSync)
|
|
$track.data('sync-viewer', this)
|
|
$clientState = $track.find('.client-state')
|
|
$uploadState = $track.find('.upload-state')
|
|
$clientStateRetry = $clientState.find('.retry')
|
|
$clientStateRetry.click(this.retryDownloadRecordedBackingTrack)
|
|
$uploadStateRetry = $uploadState.find('.retry')
|
|
$uploadStateRetry.click(this.retryUploadRecordedBackingTrack)
|
|
context.JK.bindHoverEvents($track)
|
|
context.JK.bindInstrumentHover($track, {positions:['top'], shrinkToFit: true});
|
|
context.JK.hoverBubble($clientState, this.onBackingTrackHoverOfStateIndicator, {width:'450px', closeWhenOthersOpen: true, positions:['left']})
|
|
context.JK.hoverBubble($uploadState, this.onBackingTrackHoverOfStateIndicator, {width:'450px', closeWhenOthersOpen: true, positions:['right']})
|
|
$clientState.addClass('is-native-client') if gon.isNativeClient
|
|
$uploadState.addClass('is-native-client') if gon.isNativeClient
|
|
$track
|
|
|
|
createStreamMix: (userSync) =>
|
|
$track = $(context._.template(@templateStreamMix.html(), userSync, {variable: 'data'}))
|
|
$track.data('server-info', userSync)
|
|
$track.data('sync-viewer', this)
|
|
$clientState = $track.find('.client-state')
|
|
$uploadState = $track.find('.upload-state')
|
|
$uploadState.find('.retry').click(this.retryUploadRecordedTrack)
|
|
context.JK.hoverBubble($clientState, this.onStreamMixHover, {width:'450px', closeWhenOthersOpen: true, positions:['left']})
|
|
context.JK.hoverBubble($uploadState, this.onStreamMixHover, {width:'450px', closeWhenOthersOpen: true, positions:['right']})
|
|
$clientState.addClass('is-native-client') if gon.isNativeClient
|
|
$uploadState.addClass('is-native-client') if gon.isNativeClient
|
|
$track
|
|
|
|
exportRecording: (e) =>
|
|
$export = $(e.target)
|
|
if context.SessionStore.inSession()
|
|
context.JK.ackBubble($export, 'sync-viewer-paused', {}, {offsetParent: $export.closest('.dialog')})
|
|
return
|
|
|
|
recordingId = $export.closest('.details').attr('data-recording-id')
|
|
if !recordingId? or recordingId == ""
|
|
throw "exportRecording can't find data-recording-id"
|
|
|
|
cmd =
|
|
{ type: 'export_recording',
|
|
action: 'export',
|
|
queue: 'upload',
|
|
recording_id: recordingId}
|
|
|
|
logger.debug("enqueueing export")
|
|
context.jamClient.OnTrySyncCommand(cmd)
|
|
return false;
|
|
|
|
deleteRecording: (e) =>
|
|
$delete = $(e.target)
|
|
if context.SessionStore.inSession()
|
|
context.JK.ackBubble($delete, 'sync-viewer-paused', {}, {offsetParent: $delete.closest('.dialog')})
|
|
return
|
|
|
|
$details = $delete.closest('.details')
|
|
recordingId = $details.attr('data-recording-id')
|
|
|
|
if !recordingId? or recordingId == ""
|
|
throw "deleteRecording can't find data-recording-id"
|
|
|
|
context.JK.Banner.showYesNo({
|
|
title: "Confirm Deletion",
|
|
html: "Are you sure you want to delete this recording?",
|
|
yes: =>
|
|
@rest.deleteRecordingClaim(recordingId).done((response)=>
|
|
cmd =
|
|
{ type: 'recording_directory',
|
|
action: 'delete',
|
|
queue: 'cleanup',
|
|
recording_id: recordingId}
|
|
|
|
# now check if the sync is gone entirely, allowing us to delete it from the UI
|
|
@rest.getUserSync({user_sync_id: recordingId}).done((userSync) =>
|
|
# the user sync is still here. tell user it'll be done as soon as they've uploaded their files
|
|
context.JK.ackBubble($delete, 'file-sync-delayed-deletion', {}, {offsetParent: $delete.closest('.dialog')})
|
|
)
|
|
.fail((xhr) =>
|
|
if xhr.status == 404
|
|
# the userSync is gone; remove from file manager dynamically
|
|
$recordingHolder = $details.closest('.recording-holder')
|
|
$recordingHolder.slideUp()
|
|
else
|
|
@app.ajaxError(arguments)
|
|
)
|
|
|
|
context.jamClient.OnTrySyncCommand(cmd)
|
|
)
|
|
.fail(@app.ajaxError)
|
|
})
|
|
|
|
return false;
|
|
|
|
displaySize: (size) =>
|
|
# size is in bytes. divide by million, anxosd round to one decimal place
|
|
megs = Math.round(size * 10 / (1024 * 1024) ) / 10
|
|
"#{megs}M"
|
|
|
|
createRecordingWrapper: ($toWrap, recordingInfo) =>
|
|
totalSize = $($toWrap.get(0)).data('total-size')
|
|
recordingInfo.recording_landing_url = "/recordings/#{recordingInfo.id}"
|
|
recordingInfo.totalSize = this.displaySize(totalSize)
|
|
recordingInfo.claimedRecordingId = recordingInfo.my?.id
|
|
$wrapperDetails = $(context._.template(@templateRecordingWrapperDetails.html(), recordingInfo, {variable: 'data'}))
|
|
$wrapper = $('<div class="recording-holder"></div>')
|
|
$toWrap.wrapAll($wrapper)
|
|
$wrapper = $toWrap.closest('.recording-holder')
|
|
$wrapperDetails.prependTo($wrapper)
|
|
$mix = $wrapper.find('.mix.sync')
|
|
if $mix.length == 0
|
|
# create a virtual mix so that the UI is consistent
|
|
$wrapper.append(this.createMix('fake', recordingInfo))
|
|
|
|
$wrapper.find('a.export').click(this.exportRecording)
|
|
$wrapper.find('a.delete').click(this.deleteRecording)
|
|
|
|
separateByRecording: () =>
|
|
$recordedTracks = @list.find('.sync')
|
|
|
|
currentRecordingId = null;
|
|
|
|
queue = $([]);
|
|
|
|
for recordedTrack in $recordedTracks
|
|
$recordedTrack = $(recordedTrack)
|
|
recordingId = $recordedTrack.attr('data-recording-id')
|
|
if recordingId != currentRecordingId
|
|
if queue.length > 0
|
|
this.createRecordingWrapper(queue, $(queue.get(0)).data('server-info').recording)
|
|
queue = $([])
|
|
|
|
currentRecordingId = recordingId
|
|
queue = queue.add(recordedTrack)
|
|
|
|
if queue.length > 0
|
|
this.createRecordingWrapper(queue, $(queue.get(0)).data('server-info').recording)
|
|
|
|
processUserSyncs: (response) =>
|
|
|
|
@list.empty()
|
|
|
|
# check if no entries
|
|
if @since == 0 and response.entries.length == 0
|
|
@list.append(context._.template(@templateNoSyncs.html(), {}, {variable: 'data'}))
|
|
else
|
|
recordings = {} # collect all unique recording
|
|
for userSync in response.entries
|
|
if userSync.type == 'recorded_track'
|
|
@list.append(this.createTrack(userSync))
|
|
if userSync.type == 'recorded_backing_track'
|
|
@list.append(this.createBackingTrack(userSync))
|
|
else if userSync.type == 'mix'
|
|
@list.append(this.createMix(userSync))
|
|
else if userSync.type == 'stream_mix'
|
|
@list.append(this.createStreamMix(userSync))
|
|
|
|
recordings[userSync.recording_id] = userSync.recording
|
|
recordingsToResolve = []
|
|
# resolve each track against backend data:
|
|
for recording_id, recording of recordings
|
|
recordingsToResolve.push(recording)
|
|
|
|
clientRecordings = context.jamClient.GetLocalRecordingState(recordings: recordingsToResolve)
|
|
|
|
if clientRecordings.error?
|
|
alert(clientRecordings.error)
|
|
else
|
|
this.associateClientInfo(turp) for turp in clientRecordings.recordings
|
|
|
|
for track in @list.find('.recorded-track.sync')
|
|
this.updateTrackState($(track))
|
|
for track in @list.find('.recorded-backing-track.sync')
|
|
this.updateBackingTrackState($(track))
|
|
for streamMix in @list.find('.stream-mix.sync')
|
|
this.updateStreamMixState($(streamMix))
|
|
|
|
this.separateByRecording()
|
|
|
|
@since = response.next
|
|
|
|
resolveTrack: (commandMetadata) =>
|
|
recordingId = commandMetadata['recording_id']
|
|
clientTrackId = commandMetadata['track_id']
|
|
|
|
matchingTrack = @list.find(".recorded-track[data-recording-id='#{recordingId}'][data-client-track-id='#{clientTrackId}']")
|
|
if matchingTrack.length == 0
|
|
return @rest.getRecordedTrack({recording_id: recordingId, track_id: clientTrackId})
|
|
else
|
|
deferred = $.Deferred();
|
|
deferred.resolve(matchingTrack.data('server-info'))
|
|
return deferred
|
|
|
|
resolveBackingTrack: (commandMetadata) =>
|
|
recordingId = commandMetadata['recording_id']
|
|
clientTrackId = commandMetadata['track_id']
|
|
|
|
matchingTrack = @list.find(".recorded-backing-track[data-recording-id='#{recordingId}'][data-client-track-id='#{clientTrackId}']")
|
|
if matchingTrack.length == 0
|
|
return @rest.getRecordedBackingTrack({recording_id: recordingId, track_id: clientTrackId})
|
|
else
|
|
deferred = $.Deferred();
|
|
deferred.resolve(matchingTrack.data('server-info'))
|
|
return deferred
|
|
|
|
renderFullUploadRecordedTrack: (serverInfo) =>
|
|
$track = $(context._.template(@templateRecordedTrackCommand.html(), $.extend(serverInfo, {action:'UPLOADING'}), {variable: 'data'}))
|
|
$busy = @uploadProgress.find('.busy')
|
|
$busy.empty().append($track)
|
|
@uploadProgress.find('.progress').css('width', '0%')
|
|
|
|
renderFullDownloadRecordedTrack: (serverInfo) =>
|
|
$track = $(context._.template(@templateRecordedTrackCommand.html(), $.extend(serverInfo, {action:'DOWNLOADING'}), {variable: 'data'}))
|
|
$busy = @downloadProgress.find('.busy')
|
|
$busy.empty().append($track)
|
|
@downloadProgress.find('.progress').css('width', '0%')
|
|
|
|
renderFullUploadRecordedBackingTrack: (serverInfo) =>
|
|
$track = $(context._.template(@templateRecordedBackingTrackCommand.html(), $.extend(serverInfo, {action:'UPLOADING'}), {variable: 'data'}))
|
|
$busy = @uploadProgress.find('.busy')
|
|
$busy.empty().append($track)
|
|
@uploadProgress.find('.progress').css('width', '0%')
|
|
|
|
renderFullDownloadRecordedBackingTrack: (serverInfo) =>
|
|
$track = $(context._.template(@templateRecordedBackingTrackCommand.html(), $.extend(serverInfo, {action:'DOWNLOADING'}), {variable: 'data'}))
|
|
$busy = @downloadProgress.find('.busy')
|
|
$busy.empty().append($track)
|
|
@downloadProgress.find('.progress').css('width', '0%')
|
|
|
|
# this will either show a generic placeholder, or immediately show the whole track
|
|
renderDownloadRecordedTrack: (commandId, commandMetadata) =>
|
|
# try to find the info in the list; if we can't find it, then resolve it
|
|
deferred = this.resolveTrack(commandMetadata)
|
|
if deferred.state() == 'pending'
|
|
this.renderGeneric(commandId, 'download', commandMetadata)
|
|
|
|
deferred.done(this.renderFullDownloadRecordedTrack).fail(()=> @logger.error("unable to fetch recorded_track info") )
|
|
|
|
|
|
renderUploadRecordedTrack: (commandId, commandMetadata) =>
|
|
# try to find the info in the list; if we can't find it, then resolve it
|
|
deferred = this.resolveTrack(commandMetadata)
|
|
if deferred.state() == 'pending'
|
|
this.renderGeneric(commandId, 'upload', commandMetadata)
|
|
|
|
deferred.done(this.renderFullUploadRecordedTrack).fail(()=> @logger.error("unable to fetch recorded_track info") )
|
|
|
|
# this will either show a generic placeholder, or immediately show the whole track
|
|
renderDownloadRecordedBackingTrack: (commandId, commandMetadata) =>
|
|
# try to find the info in the list; if we can't find it, then resolve it
|
|
deferred = this.resolveBackingTrack(commandMetadata)
|
|
if deferred.state() == 'pending'
|
|
this.renderGeneric(commandId, 'download', commandMetadata)
|
|
|
|
deferred.done(this.renderFullDownloadRecordedBackingTrack).fail(()=> @logger.error("unable to fetch recorded_backing_track info") )
|
|
|
|
renderUploadRecordedBackingTrack: (commandId, commandMetadata) =>
|
|
# try to find the info in the list; if we can't find it, then resolve it
|
|
deferred = this.resolveBackingTrack(commandMetadata)
|
|
if deferred.state() == 'pending'
|
|
this.renderGeneric(commandId, 'upload', commandMetadata)
|
|
|
|
deferred.done(this.renderFullUploadRecordedBackingTrack).fail(()=> @logger.error("unable to fetch recorded_backing_track info") )
|
|
|
|
renderGeneric: (commandId, category, commandMetadata) =>
|
|
commandMetadata.displayType = this.displayName(commandMetadata)
|
|
|
|
$generic = $(context._.template(@templateGenericCommand.html(), commandMetadata, {variable: 'data'}))
|
|
if category == 'download'
|
|
$busy = @downloadProgress.find('.busy')
|
|
$busy.empty().append($generic)
|
|
else if category == 'upload'
|
|
$busy = @uploadProgress.find('.busy')
|
|
$busy.empty().append($generic)
|
|
else
|
|
@logger.error("unknown category #{category}")
|
|
|
|
|
|
renderStartCommand: (commandId, commandType, commandMetadata) =>
|
|
|
|
#console.log("renderStartCommand", arguments)
|
|
unless commandMetadata?
|
|
managerState = context.jamClient.GetRecordingManagerState()
|
|
if commandType == 'download'
|
|
commandMetadata = managerState.current_download
|
|
else if commandType == 'upload'
|
|
commandMetadata = managerState.current_upload
|
|
else
|
|
@logger.error("unknown commandType #{commandType}")
|
|
|
|
unless commandMetadata?
|
|
# we still have no metadata. we have to give up
|
|
@logger.error("no metadata found for current command #{commandId} #{commandType}. bailing out")
|
|
return
|
|
|
|
if commandMetadata.queue == 'download'
|
|
@downloadCommandId = commandId
|
|
@downloadMetadata = commandMetadata
|
|
@downloadProgress.removeClass('quiet paused busy')
|
|
@downloadProgress.addClass('busy')
|
|
if commandMetadata.type == 'recorded_track' and commandMetadata.action == 'download'
|
|
this.renderDownloadRecordedTrack(commandId, commandMetadata)
|
|
else if commandMetadata.type == 'recorded_backing_track' and commandMetadata.action == 'download'
|
|
this.renderDownloadRecordedBackingTrack(commandId, commandMetadata)
|
|
else
|
|
this.renderGeneric(commandId, 'download', commandMetadata)
|
|
else if commandMetadata.queue == 'upload'
|
|
@uploadCommandId = commandId
|
|
@uploadMetadata = commandMetadata
|
|
@uploadProgress.removeClass('quiet paused busy')
|
|
@uploadProgress.addClass('busy')
|
|
if commandMetadata.type == 'recorded_track' and commandMetadata.action == 'upload'
|
|
this.renderUploadRecordedTrack(commandId, commandMetadata)
|
|
else if commandMetadata.type == 'recorded_backing_track' and commandMetadata.action == 'upload'
|
|
this.renderUploadRecordedBackingTrack(commandId, commandMetadata)
|
|
else
|
|
this.renderGeneric(commandId, 'upload', commandMetadata)
|
|
else if commandMetadata.queue == 'cleanup'
|
|
@cleanupCommandId = commandId
|
|
@cleanupMetadata = commandMetadata
|
|
|
|
|
|
renderSingleRecording: (userSyncs) =>
|
|
return if userSyncs.entries.length == 0
|
|
clientRecordings = context.jamClient.GetLocalRecordingState(recordings: [userSyncs.entries[0].recording])
|
|
for userSync in userSyncs.entries
|
|
if userSync.type == 'recorded_track'
|
|
$track = @list.find(".sync[data-id='#{userSync.id}']")
|
|
continue if $track.length == 0
|
|
$track.data('server-info', userSync)
|
|
this.associateClientInfo(clientRecordings.recordings[0])
|
|
this.updateTrackState($track)
|
|
else if userSync.type == 'recorded_backing_track'
|
|
$track = @list.find(".sync[data-id='#{userSync.id}']")
|
|
continue if $track.length == 0
|
|
$track.data('server-info', userSync)
|
|
this.associateClientInfo(clientRecordings.recordings[0])
|
|
this.updateBackingTrackState($track)
|
|
else if userSync.type == 'mix'
|
|
# check if there is a virtual mix 1st; if so, update it
|
|
$mix = @list.find(".mix.virtual[data-recording-id='#{userSync.recording.id}']")
|
|
if $mix.length == 0
|
|
$mix = @list.find(".sync[data-id='#{userSync.id}']")
|
|
continue if $mix.length == 0
|
|
$newMix = this.createMix(userSync)
|
|
this.associateClientInfo(clientRecordings.recordings[0])
|
|
$mix.replaceWith($newMix)
|
|
else if userSync.type == 'stream_mix'
|
|
$streamMix = @list.find(".sync[data-id='#{userSync.id}']")
|
|
continue if $streamMix.length == 0
|
|
$streamMix.data('server-info', userSync)
|
|
this.associateClientInfo(clientRecordings.recordings[0])
|
|
this.updateStreamMixState($streamMix)
|
|
|
|
updateSingleRecording: (recording_id) =>
|
|
@rest.getUserSyncs({recording_id: recording_id}).done(this.renderSingleRecording)
|
|
|
|
updateProgressOnSync: ($track, queue, percentage) =>
|
|
state = if queue == 'upload' then '.upload-state' else '.client-state'
|
|
$progress = $track.find("#{state} .progress")
|
|
$progress.css('width', percentage + '%')
|
|
|
|
renderFinishCommand: (commandId, data) =>
|
|
|
|
reason = data.commandReason
|
|
success = data.commandSuccess
|
|
|
|
if commandId == @downloadCommandId
|
|
|
|
this.logResult(@downloadMetadata, success, reason, false)
|
|
recordingId = @downloadMetadata['recording_id']
|
|
this.updateSingleRecording(recordingId) if recordingId?
|
|
|
|
else if commandId == @uploadCommandId
|
|
|
|
this.logResult(@uploadMetadata, success, reason, false)
|
|
recordingId = @uploadMetadata['recording_id']
|
|
this.updateSingleRecording(recordingId) if recordingId?
|
|
|
|
else if commandId == @cleanupCommandId
|
|
this.logResult(@cleanupMetadata, success, reason, false)
|
|
|
|
else
|
|
@logger.error("unknown commandId in renderFinishCommand")
|
|
|
|
# refresh the header when done. we need to leave this callback to let the command fully switch to off
|
|
#setTimeout(this.renderHeader, 1)
|
|
|
|
this.renderHeader()
|
|
|
|
renderPercentage: (commandId, commandType, percentage) =>
|
|
|
|
if commandId == @downloadCommandId
|
|
$progress = @downloadProgress.find('.progress')
|
|
$progress.css('width', percentage + '%')
|
|
|
|
if @downloadMetadata.type == 'recorded_track' or @downloadMetadata.type == 'recorded_backing_track'
|
|
clientTrackId = @downloadMetadata['track_id']
|
|
recordingId = @downloadMetadata['recording_id']
|
|
$matchingTrack = @list.find(".track-item.sync[data-recording-id='#{recordingId}'][data-client-track-id='#{clientTrackId}']")
|
|
if $matchingTrack.length > 0
|
|
this.updateProgressOnSync($matchingTrack, 'download', percentage)
|
|
|
|
else if commandId == @uploadCommandId
|
|
$progress = @uploadProgress.find('.progress')
|
|
$progress.css('width', percentage + '%')
|
|
|
|
if (@uploadMetadata.type == 'recorded_track' or @uploadMetadata.type == 'recorded_backing_track') and @uploadMetadata.action == 'upload'
|
|
clientTrackId = @uploadMetadata['track_id']
|
|
recordingId = @uploadMetadata['recording_id']
|
|
$matchingTrack = @list.find(".track-item.sync[data-recording-id='#{recordingId}'][data-client-track-id='#{clientTrackId}']")
|
|
if $matchingTrack.length > 0
|
|
this.updateProgressOnSync($matchingTrack, 'upload', percentage)
|
|
else if @uploadMetadata.type == 'stream_mix' and @uploadMetadata.action == 'upload'
|
|
recordingId = @uploadMetadata['recording_id']
|
|
$matchingStreamMix = @list.find(".stream-mix.sync[data-recording-id='#{recordingId}']")
|
|
if $matchingStreamMix.length > 0
|
|
this.updateProgressOnSync($matchingStreamMix, 'upload', percentage)
|
|
else if commandId == @cleanupCommandId
|
|
# ignore
|
|
else
|
|
@logger.error("unknown commandId in renderFinishCommand")
|
|
|
|
|
|
fileManagerCmdStart: (e, data) =>
|
|
#console.log("fileManagerCmdStart", data)
|
|
commandId = data['commandId']
|
|
commandType = data['commandType']
|
|
commandMetadata = data['commandMetadata']
|
|
|
|
category = commandMetadata.queue
|
|
|
|
if category == 'download' && (@downloadCommandId != null && @downloadCommandId != commandId)
|
|
@logger.warn("received command-start for download but previous command did not send stop")
|
|
this.renderFinishCommand(commandId, category)
|
|
else if @uploadCommandId != null && @uploadCommandId != commandId
|
|
@logger.warn("received command-start for upload but previous command did not send stop")
|
|
this.renderFinishCommand(commandId, category)
|
|
|
|
this.renderStartCommand(commandId, commandType, commandMetadata)
|
|
|
|
fileManagerCmdStop: (e, data) =>
|
|
#console.log("fileManagerCmdStop", data)
|
|
commandId = data['commandId']
|
|
|
|
if commandId == @downloadCommandId
|
|
this.renderFinishCommand(commandId, data)
|
|
@downloadCommandId = null
|
|
@downloadMetadata = null;
|
|
else if commandId == @uploadCommandId
|
|
this.renderFinishCommand(commandId, data)
|
|
@uploadCommandId = null
|
|
@uploadMetadata = null
|
|
else if commandId == @cleanupCommandId
|
|
this.renderFinishCommand(commandId, data)
|
|
@cleanupCommandId = null
|
|
@cleanupMetadata = null
|
|
|
|
else
|
|
@logger.warn("received command-stop for unknown command: #{commandId} #{@downloadCommandId} #{@uploadCommandId} #{@cleanupCommandId}" )
|
|
|
|
fileManagerCmdProgress: (e, data) =>
|
|
#console.log("fileManagerCmdProgress", data)
|
|
commandId = data['commandId']
|
|
|
|
if commandId == @downloadCommandId
|
|
category = 'download'
|
|
this.renderPercentage(commandId, category, data.percentage)
|
|
|
|
else if commandId == @uploadCommandId
|
|
category = 'upload'
|
|
this.renderPercentage(commandId, category, data.percentage)
|
|
else if commandId == @cleanupCommandId
|
|
# do nothing
|
|
else
|
|
@logger.warn("received command-percentage for unknown command")
|
|
|
|
fileManagerAsapCommandStatus: (e, data) =>
|
|
this.logResult(data.commandMetadata, false, data.commandReason, true)
|
|
|
|
displayName: (metadata) =>
|
|
if (metadata.type == 'recorded_track' || metadata.type == 'recorded_backing_track') && metadata.action == 'download'
|
|
return 'DOWNLOADING TRACK'
|
|
else if (metadata.type == 'recorded_track' || metadata.type == 'recorded_backing_track') && metadata.action == 'upload'
|
|
return 'UPLOADING TRACK'
|
|
else if metadata.type == 'mix' && metadata.action == 'download'
|
|
return 'DOWNLOADING MIX'
|
|
else if (metadata.type == 'recorded_track' || metadata.type == 'recorded_backing_track') && metadata.action == 'convert'
|
|
return 'COMPRESSING TRACK'
|
|
else if (metadata.type == 'recorded_track' || metadata.type == 'recorded_backing_track') && metadata.action == 'delete'
|
|
return 'CLEANUP TRACK'
|
|
else if metadata.type == 'stream_mix' && metadata.action == 'upload'
|
|
return 'UPLOADING STREAM MIX'
|
|
else if metadata.type == 'recording_directory' && metadata.action == 'delete'
|
|
return 'DELETE RECORDING'
|
|
else
|
|
return "#{metadata.action} #{metadata.type}".toUpperCase()
|
|
|
|
|
|
shownTab: () =>
|
|
@tabSelectors.filter('.selected')
|
|
|
|
# create a log in the Log tab
|
|
logResult: (metadata, success, reason, isAsap) =>
|
|
|
|
# if an error comes in, and the log tab is not already showing, increment the badge
|
|
if not success and (!@showing || this.shownTab().attr('purpose') != 'log')
|
|
@logBadge.css('display', 'inline-block')
|
|
if @showing # don't do animation unless user can see it
|
|
@logBadge.pulse({'background-color' : '#868686'}, {pulses: 2}, () => @logBadge.css('background-color', '#980006'))
|
|
|
|
displayReason = switch reason
|
|
when 'no-match-in-queue' then 'restart JamKazam'
|
|
when 'already-done' then 'ignored, already done'
|
|
when 'failed-convert' then 'failed previously'
|
|
when 'minimum-protection-time' then 'too soon to delete'
|
|
else reason
|
|
|
|
displaySuccess = if success then 'yes' else 'no'
|
|
$log = context._.template(@templateLogItem.html(), {isAsap: isAsap, command: this.displayName(metadata), success: success, displaySuccess: displaySuccess, detail: displayReason, when: new Date()}, {variable: 'data'})
|
|
|
|
@logList.prepend($log)
|
|
|
|
|
|
|