This commit is contained in:
Seth Call 2015-02-15 22:14:30 -06:00
parent 42a2abe99c
commit afe9f65709
13 changed files with 272 additions and 56 deletions

View File

@ -578,6 +578,11 @@ module JamRuby
recorded_tracks.each do |recorded_track|
return false unless recorded_track.fully_uploaded
end
recorded_backing_tracks.each do |recorded_backing_track|
return false unless recorded_backing_track.fully_uploaded
end
true
end

View File

@ -1055,6 +1055,18 @@
});
}
function getRecordedBackingTrack(options) {
var recordingId = options["recording_id"];
var trackId = options["track_id"];
return $.ajax({
type: "GET",
dataType: "json",
contentType: 'application/json',
url: "/api/recordings/" + recordingId + "/backing_tracks/" + trackId
});
}
function getRecording(options) {
var recordingId = options["id"];
@ -1624,6 +1636,7 @@
this.stopRecording = stopRecording;
this.getRecording = getRecording;
this.getRecordedTrack = getRecordedTrack;
this.getRecordedBackingTrack = getRecordedBackingTrack;
this.getClaimedRecordings = getClaimedRecordings;
this.getClaimedRecording = getClaimedRecording;
this.updateClaimedRecording = updateClaimedRecording;

View File

@ -39,6 +39,7 @@
var startTimeDate = null;
var startingRecording = false; // double-click guard
var claimedRecording = null;
var backing_track_path = null;
var playbackControls = null;
var promptLeave = false;
var rateSessionDialog = null;
@ -435,6 +436,7 @@
var currentSession = sessionModel.getCurrentSession();
if(claimedRecording == null && (currentSession && currentSession.claimed_recording != null)) {
// this is a 'started with a claimed_recording' transition.
// we need to start a timer to watch for the state of the play session
@ -443,10 +445,18 @@
else if(claimedRecording && (currentSession == null || currentSession.claimed_recording == null)) {
playbackControls.stopMonitor();
}
claimedRecording = currentSession == null ? null : currentSession.claimed_recording;
if(backing_track_path == null && (currentSession && currentSession.backing_track_path != null)) {
playbackControls.startMonitor();
}
else if(backing_track_path && (currentSession == null || currentSession.backing_track_path == null)) {
playbackControls.stopMonitor();
}
backing_track_path = currentSession == null ? null : currentSession.backing_track_path;
}
function sessionChanged() {
handleTransitionsInRecordingPlayback();
@ -828,6 +838,9 @@
var localMediaMixers = _mixersForGroupIds([ChannelGroupIds.MediaTrackGroup, ChannelGroupIds.JamTrackGroup, ChannelGroupIds.MetronomeGroup], MIX_MODES.MASTER);
var peerLocalMediaMixers = _mixersForGroupId(ChannelGroupIds.PeerMediaTrackGroup, MIX_MODES.MASTER);
var recordedBackingTracks = sessionModel.recordedBackingTracks();
var backingTracks = sessionModel.backingTracks();
// with mixer info, we use these to decide what kind of tracks are open in the backend
// each mixer has a media_type field, which describes the type of media track it is.
@ -848,11 +861,41 @@
var metronomeTrackMixers = [];
var adhocTrackMixers = [];
function groupByType(mixers) {
function groupByType(mixers, isLocalMixer) {
context._.each(mixers, function(mixer) {
var mediaType = mixer.media_type;
var groupId = mixer.group_id;
if(mediaType == 'PeerMediaTrack' || mediaType == 'BackingTrack') {
// mediaType == null is for backwards compat with older clients. Can be removed soon
if(mediaType == null || mediaType == "" || mediaType == 'RecordingTrack') {
// additional check; if we can match an id in backing tracks or recorded backing track,
// we need to remove it from the recorded track set, but move it to the backing track set
var isBackingTrack = false
if(recordedBackingTracks) {
context._.each(recordedBackingTracks, function (recordedBackingTrack) {
if (mixer.id == 'L' + recordedBackingTrack.client_track_id) {
isBackingTrack = true;
return false; // break
}
})
}
if(backingTracks) {
context._.each(backingTracks, function (backingTrack) {
if (mixer.id == 'L' + backingTrack.client_track_id) {
isBackingTrack = true;
return false; // break
}
})
}
if(isBackingTrack) {
backingTrackMixers.push(mixer)
}
else {
recordingTrackMixers.push(mixer);
}
} else if(mediaType == 'PeerMediaTrack' || mediaType == 'BackingTrack') {
// BackingTrack
backingTrackMixers.push(mixer);
} else if(mediaType == 'MetronomeTrack' || groupId==ChannelGroupIds.MetronomeGroup) {
@ -871,8 +914,8 @@
});
}
groupByType(localMediaMixers);
groupByType(peerLocalMediaMixers);
groupByType(localMediaMixers, true);
groupByType(peerLocalMediaMixers, false);
if(recordingTrackMixers.length > 0) {
renderRecordingTracks(recordingTrackMixers)
@ -901,7 +944,7 @@
var backingTracks = []
if(sessionModel.isPlayingRecording()) {
// only return managed mixers for recorded backing tracks
backingTrackMixers = context._.filter(backingTrackMixers, function(mixer){return mixer.managed})
backingTrackMixers = context._.filter(backingTrackMixers, function(mixer){return mixer.managed || mixer.managed === undefined})
backingTracks = sessionModel.recordedBackingTracks();
}
else {
@ -910,7 +953,7 @@
backingTrackMixers = context._.filter(backingTrackMixers, function(mixer){return !mixer.managed})
if(backingTrackMixers.length > 1) {
app.notify({
title: "Multiple Backing Tracks Encounterd",
title: "Multiple Backing Tracks Encountered",
text: "Only one backing track can be open a time.",
icon_url: "/assets/content/icon_alert_big.png"
});
@ -928,7 +971,8 @@
var noCorrespondingTracks = false;
if(sessionModel.isPlayingRecording()) {
$.each(backingTracks, function (i, backingTrack) {
if(mixer.persisted_track_id == backingTrack.client_track_id) {
if(mixer.persisted_track_id == backingTrack.client_track_id || // occurs if this client is the one that opened the track
mixer.id == 'L' + backingTrack.client_track_id) { // occurs if this client is a remote participant
correspondingTracks.push(backingTrack)
}
});
@ -941,6 +985,7 @@
if (correspondingTracks.length == 0) {
noCorrespondingTracks = true;
logger.debug("renderBackingTracks: could not map backing tracks")
app.notify({
title: "Unable to Open Backing Track",
text: "Could not correlate server and client tracks",
@ -956,20 +1001,24 @@
// if it's a locally opened track (MediaTrackGroup), then we can say this person is the opener
var isOpener = mixer.group_id == ChannelGroupIds.MediaTrackGroup;
var shortFilename = context.JK.getNameOfFile(backingTrack.filename);
if(!sessionModel.isPlayingRecording()) {
// if a recording is being played back, do not set this header, because renderRecordedTracks already did
// ugly.
$('.session-recording-name').text(backingTrack.filename);
$('.session-recording-name').text(shortFilename);
}
var instrumentIcon = context.JK.getInstrumentIcon45(backingTrack.instrument_id);
var photoUrl = "/assets/content/icon_recording.png";
// Default trackData to participant + no Mixer state.
var trackData = {
trackId: backingTrack.id,
clientId: backingTrack.client_id,
name: backingTrack.filename,
name: 'Backing',
filename: backingTrack.filename,
instrumentIcon: instrumentIcon,
avatar: photoUrl,
latency: "good",
@ -997,7 +1046,7 @@
trackData.mediaControlsDisabled = true;
trackData.mediaTrackOpener = isOpener;
}
_addRecordingTrack(trackData);
_addRecordingTrack(trackData, mixer);
});
}
@ -1187,7 +1236,8 @@
//trackData.mediaControlsDisabled = true;
trackData.mediaTrackOpener = isOpener;
}
_addRecordingTrack(trackData);
_addRecordingTrack(trackData, mixer);
}// if
setFormFromMetronome()
}
@ -1196,6 +1246,7 @@
function renderRecordingTracks(recordingMixers) {
// get the server's info for the recording
var recordedTracks = sessionModel.recordedTracks();
var recordedBackingTracks = sessionModel.recordedBackingTracks();
// pluck the 1st mixer, and assume that all other mixers in this group are of the same type (between Local vs Peer)
// if it's a locally opened track (MediaTrackGroup), then we can say this person is the opener
@ -1231,6 +1282,7 @@
if(correspondingTracks.length == 0) {
noCorrespondingTracks = true;
logger.debug("unable to correlate all recorded tracks", recordingMixers, recordedTracks)
app.notify({
title: "Unable to Open Recording",
text: "Could not correlate server and client tracks",
@ -1283,7 +1335,7 @@
trackData.mediaControlsDisabled = true;
trackData.mediaTrackOpener = isOpener;
}
_addRecordingTrack(trackData);
_addRecordingTrack(trackData, mixer);
});
if(!noCorrespondingTracks && recordedTracks.length > 0) {
@ -1340,6 +1392,7 @@
var mixMode = sessionModel.getMixMode();
if(myTrack) {
// when it's your track, look it up by the backend resource ID
mixer = getMixerByTrackId(track.client_track_id, mixMode)
vuMixer = mixer;
@ -1697,7 +1750,7 @@
function _addRecordingTrack(trackData) {
function _addRecordingTrack(trackData, mixer) {
var parentSelector = '#session-recordedtracks-container';
var $destination = $(parentSelector);
@ -1716,6 +1769,8 @@
if(trackData.mediaControlsDisabled) {
$trackIconMute.data('media-controls-disabled', true).data('media-track-opener', trackData.mediaTrackOpener)
}
$trackIconMute.data('mixer', mixer).data('opposite-mixer', null)
if(trackData.showLoop) {
var $trackIconLoop = $track.find('.track-icon-loop')
@ -1723,8 +1778,8 @@
var loopBtn = $trackIconLoop.find('#loop-button')
loopBtn.on('click', function(event) {
var loop = loopBtn.is(':checked')
console.log("Looping: ", loop);
context.jamClient.SessionSetBackingTrackFileLoop(trackData.name, loop)
logger.debug("Looping: ", loop, trackData.filename);
context.jamClient.SessionSetBackingTrackFileLoop(trackData.filename, loop)
})
}
@ -1850,7 +1905,27 @@
}
}
function handleBackingTrackSelectedCallback(result) {
if(result.success) {
logger.debug("backing track selected: " + result.file);
rest.openBackingTrack({id: context.JK.CurrentSessionModel.id(), backing_track_path: result.file})
.done(function(response) {
var openResult = context.jamClient.SessionOpenBackingTrackFile(result.file, false);
console.log("BackingTrackPlay response: %o", openResult);
//context.JK.CurrentSessionModel.refreshCurrentSession(true);
sessionModel.setBackingTrack(result.file);
})
.fail(function(jqXHR) {
app.notifyServerError(jqXHR, "Unable to Open BackingTrack For Playback");
})
}
else {
logger.debug("no backing track selected")
}
}
function deleteSession(evt) {
var sessionId = $(evt.currentTarget).attr("action-id");
if (sessionId) {
@ -2180,11 +2255,13 @@
return false;
}
app.layout.showDialog('open-backing-track-dialog').one(EVENTS.DIALOG_CLOSED, function(e, data) {
if(!data.cancel && data.result){
sessionModel.setBackingTrack(data.result);
}
})
context.jamClient.ShowSelectBackingTrackDialog("window.JK.HandleBackingTrackSelectedCallback");
//app.layout.showDialog('open-backing-track-dialog').one(EVENTS.DIALOG_CLOSED, function(e, data) {
// if(!data.cancel && data.result){
// sessionModel.setBackingTrack(data.result);
// }
//})
return false;
}
@ -2566,6 +2643,7 @@
context.JK.HandleVolumeChangeCallback = handleVolumeChangeCallback;
context.JK.HandleMetronomeCallback = handleMetronomeCallback;
context.JK.HandleBridgeCallback = handleBridgeCallback;
context.JK.HandleBackingTrackSelectedCallback = handleBackingTrackSelectedCallback;
};
})(window,jQuery);

View File

@ -632,11 +632,11 @@ context.JK.SyncViewer = class SyncViewer
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 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."
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(),
@ -709,6 +709,39 @@ context.JK.SyncViewer = class SyncViewer
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'
@ -751,6 +784,24 @@ context.JK.SyncViewer = class SyncViewer
$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)
@ -884,6 +935,8 @@ context.JK.SyncViewer = class SyncViewer
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'
@ -904,6 +957,8 @@ context.JK.SyncViewer = class SyncViewer
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))
@ -923,6 +978,18 @@ context.JK.SyncViewer = class SyncViewer
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')
@ -935,6 +1002,18 @@ context.JK.SyncViewer = class SyncViewer
$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
@ -953,6 +1032,23 @@ context.JK.SyncViewer = class SyncViewer
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)
@ -991,6 +1087,8 @@ context.JK.SyncViewer = class SyncViewer
@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'
@ -1000,6 +1098,8 @@ context.JK.SyncViewer = class SyncViewer
@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'
@ -1017,6 +1117,12 @@ context.JK.SyncViewer = class SyncViewer
$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}']")
@ -1036,20 +1142,6 @@ context.JK.SyncViewer = class SyncViewer
updateSingleRecording: (recording_id) =>
@rest.getUserSyncs({recording_id: recording_id}).done(this.renderSingleRecording)
updateSingleRecordedTrack: ($track) =>
serverInfo = $track.data('server-info')
@rest.getUserSync({user_sync_id: serverInfo.id})
.done((userSync) =>
# associate new server-info with this track
$track.data('server-info', userSync)
# associate new client-info with this track
clientRecordings = context.jamClient.GetLocalRecordingState(recordings: [userSync.recording])
this.associateClientInfo(clientRecordings.recordings[0])
this.updateTrackState($track)
)
.fail(@app.ajaxError)
updateProgressOnSync: ($track, queue, percentage) =>
state = if queue == 'upload' then '.upload-state' else '.client-state'
$progress = $track.find("#{state} .progress")
@ -1089,10 +1181,10 @@ context.JK.SyncViewer = class SyncViewer
$progress = @downloadProgress.find('.progress')
$progress.css('width', percentage + '%')
if @downloadMetadata.type == 'recorded_track'
if @downloadMetadata.type == 'recorded_track' or @downloadMetadata.type == 'recorded_backing_track'
clientTrackId = @downloadMetadata['track_id']
recordingId = @downloadMetadata['recording_id']
$matchingTrack = @list.find(".recorded-track.sync[data-recording-id='#{recordingId}'][data-client-track-id='#{clientTrackId}']")
$matchingTrack = @list.find(".track-item.sync[data-recording-id='#{recordingId}'][data-client-track-id='#{clientTrackId}']")
if $matchingTrack.length > 0
this.updateProgressOnSync($matchingTrack, 'download', percentage)
@ -1100,10 +1192,10 @@ context.JK.SyncViewer = class SyncViewer
$progress = @uploadProgress.find('.progress')
$progress.css('width', percentage + '%')
if @uploadMetadata.type == 'recorded_track' and @uploadMetadata.action == 'upload'
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(".recorded-track.sync[data-recording-id='#{recordingId}'][data-client-track-id='#{clientTrackId}']")
$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'
@ -1174,15 +1266,15 @@ context.JK.SyncViewer = class SyncViewer
this.logResult(data.commandMetadata, false, data.commandReason, true)
displayName: (metadata) =>
if metadata.type == 'recorded_track' && metadata.action == 'download'
if (metadata.type == 'recorded_track' || metadata.type == 'recorded_backing_track') && metadata.action == 'download'
return 'DOWNLOADING TRACK'
else if metadata.type == 'recorded_track' && metadata.action == 'upload'
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.action == 'convert'
else if (metadata.type == 'recorded_track' || metadata.type == 'recorded_backing_track') && metadata.action == 'convert'
return 'COMPRESSING TRACK'
else if metadata.type == 'recorded_track' && metadata.action == 'delete'
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'

View File

@ -987,6 +987,15 @@
return hasFlash;
}
context.JK.getNameOfFile = function(filename) {
var index = filename.lastIndexOf('/');
if(index == -1) {
index = filename.lastIndexOf('\\');
}
return index == -1 ? filename : filename.substring(index + 1, filename.length)
}
context.JK.hasOneConfiguredDevice = function () {
var result = context.jamClient.FTUEGetGoodConfigurationList();
logger.debug("hasOneConfiguredDevice: ", result);

View File

@ -208,6 +208,10 @@ $fair: #cc9900;
background-color: $error;
}
&.not_mine {
background-color: $good;
}
&.discarded {
background-color: $unknown;
}
@ -252,6 +256,10 @@ $fair: #cc9900;
background-color: $good;
}
&.not_mine {
background-color: $good;
}
.retry {
display:none;
position:absolute;

View File

@ -44,6 +44,10 @@ class ApiRecordingsController < ApiController
@recorded_track = RecordedTrack.find_by_recording_id_and_client_track_id(params[:id], params[:track_id])
end
def show_recorded_backing_track
@recorded_backing_track = RecordedBackingTrack.find_by_recording_id_and_client_track_id(params[:id], params[:track_id])
end
def download # track
raise PermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @recorded_track.can_download?(current_user)

View File

@ -45,8 +45,8 @@ child(:recording => :recording) {
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :photo_url
}
node :mine do |user|
user == current_user
node :mine do |recorded_backing_track|
recorded_backing_track.user == current_user
end
}

View File

@ -2,6 +2,10 @@ object @recorded_backing_track
attributes :id, :fully_uploaded, :client_track_id, :client_id, :recording_id, :filename
node :mine do |recorded_backing_track|
recorded_backing_track.user == current_user
end
child(:user => :user) {
attributes :id, :first_name, :last_name, :city, :state, :country, :location, :photo_url
}

View File

@ -94,9 +94,10 @@
a#open-a-backingtrack[href="#"]
| Audio File
.when-empty.use-metronome-header
= image_tag "content/icon_metronome.png", {width:22, height:20}
a#open-a-metronome[href="#"]
| Use Metronome
- if Rails.application.config.metronome_available
= image_tag "content/icon_metronome.png", {width:22, height:20}
a#open-a-metronome[href="#"]
| Use Metronome
br[clear="all"]
= render "play_controls"
= render "configureTrack"

View File

@ -60,7 +60,7 @@ script type="text/template" id='template-sync-viewer-recorded-track'
= image_tag('content/icon_resync.png', width:12, height: 14)
script type="text/template" id='template-sync-viewer-recorded-backing-track'
.recorded-track.sync data-id="{{data.id}}" data-recording-id="{{data.recording_id}}" data-client-id="{{data.client_id}}" data-client-track-id="{{data.client_track_id}}" data-track-id="{{data.backing_track_id}}" data-fully-uploaded="{{data.fully_uploaded}}"
.recorded-backing-track.sync data-id="{{data.id}}" data-recording-id="{{data.recording_id}}" data-client-id="{{data.client_id}}" data-client-track-id="{{data.client_track_id}}" data-track-id="{{data.backing_track_id}}" data-fully-uploaded="{{data.fully_uploaded}}"
.type
span.text BACKING
a.avatar-tiny href="#" user-id="{{data.user.id}}" hoveraction="musician"
@ -233,7 +233,7 @@ script type="text/template" id="template-sync-viewer-generic-command"
| {{data.displayType}}
script type="text/template" id="template-sync-viewer-recorded-track-command"
.recorded-track.sync
.recorded-track.track-item.sync
.type
.progress
span.text
@ -243,7 +243,7 @@ script type="text/template" id="template-sync-viewer-recorded-track-command"
img.instrument-icon data-instrument-id="{{data.instrument_id}}" hoveraction="instrument" src="{{JK.getInstrumentIconMap24()[data.instrument_id].asset}}"
script type="text/template" id="template-sync-viewer-recorded-backing-track-command"
.recorded-backing-track.sync
.recorded-backing-track.track-item.sync
.type
.progress
span.text

View File

@ -312,5 +312,6 @@ if defined?(Bundler)
config.show_jamblaster_notice = true
config.show_jamblaster_kickstarter_link = true
config.metronome_available = true
end
end

View File

@ -464,6 +464,7 @@ SampleApp::Application.routes.draw do
match '/recordings/:id/stream_mix/upload_next_part' => 'api_recordings#upload_next_part_stream_mix', :via => :get
# Recordings - backing tracks
match '/recordings/:id/backing_tracks/:track_id' => 'api_recordings#show_recorded_backing_track', :via => :get, :as => 'api_recordings_show_recorded_backing_track'
match '/recordings/:id/backing_tracks/:track_id/download' => 'api_recordings#backing_track_download', :via => :get, :as => 'api_recordings_download'
match '/recordings/:id/backing_tracks/:track_id/upload_next_part' => 'api_recordings#backing_track_upload_next_part', :via => :get
match '/recordings/:id/backing_tracks/:track_id/upload_sign' => 'api_recordings#backing_track_upload_sign', :via => :get