VRFS-2499 - Incremental, nearly done.

This commit is contained in:
Steven Miers 2015-01-15 20:28:34 -06:00
parent 4f94444429
commit 3fb45c0dd0
14 changed files with 422 additions and 79 deletions

View File

@ -0,0 +1,137 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
context.JK.OpenBackingTrackDialog = function(app) {
var logger = context.JK.logger;
var rest = context.JK.Rest();
var showing = false;
var perPage = 10;
var $dialog = null;
var $tbody = null;
var $paginatorHolder = null;
var $templateOpenBackingTrackRow = null;
var $downloadedTrackHelp = null;
var $whatAreBackingTracks = null;
function emptyList() {
$tbody.empty();
}
function resetPagination() {
$dialog.find('.paginator').remove();
}
function beforeShow() {
emptyList();
resetPagination();
showing = true;
getBackingTracks()
.done(function(data, textStatus, jqXHR) {
// initialize pagination
var $paginator = context.JK.Paginator.create(parseInt(jqXHR.getResponseHeader('total-entries')), perPage, 0, onPageSelected)
$paginatorHolder.append($paginator);
});
}
function afterHide() {
showing = false;
}
function onPageSelected(targetPage) {
return getBackingTracks(targetPage);
}
function getBackingTracks(page) {
return rest.getBackingTracks({page:page + 1, per_page:10})
.done(function(result) {
console.log("result: ", result)
var backingTracks = result.backing_tracks
console.log("Backing Tracks: ", backingTracks)
emptyList();
$.each(backingTracks, function(index, backingTrack) {
console.log("Backing TRACK: ", backingTrack)
var options = {
backingTrackState: null,
path: backingTrack.path,
name: backingTrack.name,
length: backingTrack.length ? backingTrack.length : 0
}
console.log("options: ", options)
var $tr = $(context._.template($templateOpenBackingTrackRow.html(), options, { variable: 'data' }));
console.log("foo")
$tr.data('server-model', backingTrack);
console.log("bar")
console.log("Appending TR:")
$tbody.append($tr);
});
})
.fail(function(jqXHR, textStatus, errorMessage) {
app.ajaxError(jqXHR, textStatus, errorMessage);
});
}
function registerStaticEvents() {
$tbody.on('click', 'tr', function(e) {
var backingTrack = $(this).data('server-model');
// tell the server we are about to open a backing track:
rest.openBackingTrack({id: context.JK.CurrentSessionModel.id(), backing_track_path: backingTrack.path})
.done(function(response) {
// TODO: Client stuff available?:
// context.jamClient.BackingTrackStopPlay();
// var result = context.jamClient.BackingTrackPlay('t');
// logger.debug("BackingTrackPlay response: %o", result);
// if(result) {
// app.layout.closeDialog('open-backing-track-dialog');
// }
// else {
// logger.error("unable to open backing track")
// }
})
.fail(function(jqXHR) {
app.notifyServerError(jqXHR, "Unable to Open BackingTrack For Playback");
})
return false;
})
context.JK.helpBubble($downloadedTrackHelp, 'downloaded-backingtrack', {}, {width:'400px'})
$downloadedTrackHelp.on('click', false)
context.JK.helpBubble($whatAreBackingTracks, 'no help yet for this topic', {}, {positions:['bottom'], offsetParent: $dialog})
$whatAreBackingTracks.on('click', false) // no help yet
}
function initialize(){
var dialogBindings = {
'beforeShow' : beforeShow,
'afterHide': afterHide
};
app.bindDialog('open-backing-track-dialog', dialogBindings);
$dialog = $('#open-backing-track-dialog');
$tbody = $dialog.find('table.open-backing-tracks tbody');
$paginatorHolder = $dialog.find('.paginator-holder');
$templateOpenBackingTrackRow = $('#template-backing-track-row')
$downloadedTrackHelp = $dialog.find('.downloaded-backingtrack-help')
$whatAreBackingTracks = $dialog.find('.what-are-backingtracks')
registerStaticEvents();
};
this.initialize = initialize;
this.isShowing = function isShowing() { return showing; }
}
return this;
})(window,jQuery);

View File

@ -1157,6 +1157,32 @@
})
}
function openBackingTrack(options) {
var musicSessionId = options["id"];
delete options["id"];
return $.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/" + musicSessionId + "/backing_tracks/open",
data: JSON.stringify(options)
})
}
function closeBackingTrack(options) {
var musicSessionId = options["id"];
delete options["id"];
return $.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/" + musicSessionId + "/backing_tracks/close",
data: JSON.stringify(options)
})
}
function openJamTrack(options) {
var musicSessionId = options["id"];
var jamTrackId = options["jam_track_id"];
@ -1367,6 +1393,15 @@
});
}
function getBackingTracks(options) {
return $.ajax({
type: "GET",
url: '/api/backing_tracks?' + $.param(options),
dataType: "json",
contentType: 'application/json'
});
}
function addJamtrackToShoppingCart(options) {
return $.ajax({
type: "POST",
@ -1564,6 +1599,7 @@
this.startPlayClaimedRecording = startPlayClaimedRecording;
this.stopPlayClaimedRecording = stopPlayClaimedRecording;
this.openJamTrack = openJamTrack;
this.openBackingTrack = openBackingTrack;
this.closeJamTrack = closeJamTrack;
this.discardRecording = discardRecording;
this.putTrackSyncChange = putTrackSyncChange;
@ -1595,6 +1631,7 @@
this.updateAudioLatency = updateAudioLatency;
this.getJamtracks = getJamtracks;
this.getPurchasedJamTracks = getPurchasedJamTracks;
this.getBackingTracks = getBackingTracks;
this.addJamtrackToShoppingCart = addJamtrackToShoppingCart;
this.getShoppingCarts = getShoppingCarts;
this.removeShoppingCart = removeShoppingCart;

View File

@ -880,7 +880,96 @@
function renderBackingTracks(backingTrackMixers) {
logger.error("do not know how to draw backing tracks yet")
log.debug("rendering backing tracks")
var backingTracksPath = sessionModel.backingTrack();
// pluck the 1st mixer, and assume that all other mixers in this group are of the same type (between JamTrack vs Peer)
// if it's a locally opened track (MediaTrackGroup), then we can say this person is the opener
var isOpener = backingTrackMixers[0].group_id == ChannelGroupIds.MediaTrackGroup;
// using the server's info in conjuction with the client's, draw the recording tracks
if(backingTracksPath) {
$('.session-recording-name').text(sessionModel.getCurrentSession().backing_track_path);
var noCorrespondingTracks = false;
$.each(backingTrackMixers, function(index, mixer) {
var preMasteredClass = "";
// find the track or tracks that correspond to the mixer
var correspondingTracks = []
console.log("mixer", mixer)
if(mixer.id.indexOf("L") == 0) {
if(mixer.id.substring(1) == backingTrack.id) {
correspondingTracks.push(backingTrack);
} else {
// this should not be possible
alert("Invalid state: the recorded track had neither persisted_track_id or persisted_client_id");
}
}
if(correspondingTracks.length == 0) {
noCorrespondingTracks = true;
app.notify({
title: "Unable to Open BackingTrack",
text: "Could not correlate server and client tracks",
icon_url: "/assets/content/icon_alert_big.png"});
return false;
}
// prune found recorded tracks
backingTracks = $.grep(backingTracks, function(value) {
return $.inArray(value, correspondingTracks) < 0;
});
var oneOfTheTracks = correspondingTracks[0];
var instrumentIcon = context.JK.getInstrumentIcon45(oneOfTheTracks.instrument_id);
var photoUrl = "/assets/content/icon_recording.png";
var name = oneOfTheTracks.part
if (!name) {
name = oneOfTheTracks.instrument;
}
// Default trackData to participant + no Mixer state.
var trackData = {
trackId: oneOfTheTracks.id,
clientId: oneOfTheTracks.client_id,
name: name,
instrumentIcon: instrumentIcon,
avatar: photoUrl,
latency: "good",
gainPercent: 0,
muteClass: 'muted',
mixerId: "",
avatarClass : 'avatar-recording',
preMasteredClass: ""
};
var gainPercent = percentFromMixerValue(
mixer.range_low, mixer.range_high, mixer.volume_left);
var muteClass = "enabled";
if (mixer.mute) {
muteClass = "muted";
}
trackData.gainPercent = gainPercent;
trackData.muteClass = muteClass;
trackData.mixerId = mixer.id; // the master mixer controls the volume control for recordings (no personal controls in either master or personal mode)
trackData.vuMixerId = mixer.id; // the master mixer controls the VUs for recordings (no personal controls in either master or personal mode)
trackData.muteMixerId = mixer.id; // the master mixer controls the mute for recordings (no personal controls in either master or personal mode)
if(sessionModel.isPersonalMixMode() || !isOpener) {
trackData.mediaControlsDisabled = true;
trackData.mediaTrackOpener = isOpener;
}
_addRecordingTrack(trackData);
});
if(!noCorrespondingTracks && backingTracks.length > 0) {
logger.error("unable to find all backing tracks against client tracks");
app.notify({title:"All tracks not found",
text: "Some tracks in the backing tracks are not present in the playback",
icon_url: "/assets/content/icon_alert_big.png"})
}
}
}
function renderJamTracks(jamTrackMixers) {
@ -908,7 +997,7 @@
}
else {
// this should not be possible
alert("Invalid state: the recorded track had neither persisted_track_id or persisted_client_id");
alert("Invalid state: the backing track had neither persisted_track_id or persisted_client_id");
}
}
});
@ -1894,6 +1983,22 @@
.fail(app.ajaxError);
}
function openBackingTrack(e) {
// just ignore the click if they are currently recording for now
if(sessionModel.recordingModel.isRecording()) {
app.notify({
"title": "Currently Recording",
"text": "You can't open a backing track while creating a recording.",
"icon_url": "/assets/content/icon_alert_big.png"
});
return false;
}
app.layout.showDialog('open-backing-track-dialog');
return false;
}
function openJamTrack(e) {
// just ignore the click if they are currently recording for now
if(sessionModel.recordingModel.isRecording()) {
@ -1910,6 +2015,23 @@
return false;
}
function openMetronome(e) {
// just ignore the click if they are currently recording for now
if(sessionModel.recordingModel.isRecording()) {
app.notify({
"title": "Currently Recording",
"text": "You can't open a metronome while creating a recording.",
"icon_url": "/assets/content/icon_alert_big.png"
});
return false;
}
// TODO:
// Start metronome:
return false;
}
function openRecording(e) {
// just ignore the click if they are currently recording for now
if(sessionModel.recordingModel.isRecording()) {
@ -1940,6 +2062,26 @@
}
}
function closeBackingTrack() {
rest.closeBackingTrack({id: sessionModel.id()})
.done(function() {
sessionModel.refreshCurrentSession();
})
.fail(function(jqXHR) {
app.notify({
"title": "Couldn't Close BackingTrack",
"text": "Couldn't inform the server to close BackingTrack. msg=" + jqXHR.responseText,
"icon_url": "/assets/content/icon_alert_big.png"
});
});
context.jamClient.closeBackingTrackFile();
return false;
}
function closeJamTrack() {
rest.closeJamTrack({id: sessionModel.id()})
.done(function() {
@ -1958,6 +2100,8 @@
return false;
}
function closeRecording() {
rest.stopPlayClaimedRecording({id: sessionModel.id(), claimed_recording_id: sessionModel.getCurrentSession().claimed_recording.id})
.done(function() {
@ -2037,6 +2181,8 @@
$('#recording-start-stop').on('click', startStopRecording);
$('#open-a-recording').on('click', openRecording);
$('#open-a-jamtrack').on('click', openJamTrack);
$('#open-a-backingtrack').on('click', openBackingTrack);
$('#open-a-metronome').on('click', openMetronome);
$('#session-invite-musicians').on('click', inviteMusicians);
$('#session-invite-musicians2').on('click', inviteMusicians);
$('#track-settings').click(function() {

View File

@ -87,18 +87,18 @@
}
}
function backingTracks() {
function backingTrack() {
if(currentSession) {
return currentSession.backing_tracks
return currentSession.backing_track_path
}
else {
return null;
}
}
function metronomeTracks() {
function metronomeActive() {
if(currentSession) {
return currentSession.metronome_tracks
return currentSession.metronome_active
}
else {
return null;

View File

@ -1,7 +1,7 @@
@import "client/common";
table.findsession-table, table.local-recordings, table.open-jam-tracks, #account-session-detail {
table.findsession-table, table.local-recordings, table.open-jam-tracks, table.open-backing-tracks, #account-session-detail {
.latency-unacceptable {
width: 50px;
@ -64,7 +64,7 @@ table.findsession-table, table.local-recordings, table.open-jam-tracks, #account
text-align:center;
}
}
table.findsession-table, table.local-recordings, table.open-jam-tracks {
table.findsession-table, table.local-recordings, table.open-jam-tracks, table.open-backing-tracks {
width:98%;
height:10%;
font-size:11px;

View File

@ -0,0 +1,44 @@
@import "client/common";
#open-backing-track-dialog {
table.open-backing-tracks {
tbody {
tr:hover {
background-color: #777;
cursor:pointer;
}
tr[data-local-state=MISSING], tr[data-local-state=PARTIALLY_MISSING] {
background-color:#777;
color:#aaa;
}
}
}
.downloaded-backingtrack-help {
margin-left:15px;
}
.right {
margin-right:10px;
}
.help-links {
text-align: center;
position: absolute;
margin: 0 auto;
width: 70%;
left: 15%;
font-size: 12px;
padding-top:5px;
a {
margin:0 10px;
}
}
.paginator-holder {
padding-top:3px;
}
}

View File

@ -0,0 +1,17 @@
class ApiBackingTracksController < ApiController
# have to be signed in currently to see this screen
before_filter :api_signed_in_user
respond_to :json
def index
tracks = [
{:name=>'foo',:path=>"foobar.mp3", :length=>4283},
{:name=>'bar',:path=>"foo.mp3",:length=>3257}
]
@backing_tracks, @next = tracks, nil
render "api_backing_tracks/index", :layout => nil
end
end # class ApiJamTracksController

View File

@ -0,0 +1,7 @@
node :next do |page|
@next
end
node :backing_tracks do |page|
@backing_tracks
end

View File

@ -119,7 +119,7 @@
<% if Rails.application.config.jam_tracks_available %>
<li><a href="#" id="open-a-jamtrack">JamTrack</a></li>
<% end %>
<li><a href="#" id="open-backing-track">Audio File</a></li>
<li><a href="#" id="open-a-backingtrack">Audio File</a></li>
</ul>
</div>
<br clear="all" />

View File

@ -155,6 +155,9 @@
var openJamTrackDialog = new JK.OpenJamTrackDialog(JK.app);
openJamTrackDialog.initialize();
var openBackingTrackDialog = new JK.OpenBackingTrackDialog(JK.app);
openBackingTrackDialog.initialize();
var configureTracksDialog = new JK.ConfigureTracksDialog(JK.app);
configureTracksDialog.initialize();

View File

@ -33,3 +33,4 @@
= render 'dialogs/allSyncsDialog'
= render 'dialogs/adjustGearSpeedDialog'
= render 'dialogs/openJamTrackDialog'
= render 'dialogs/openBackingTrackDialog'

View File

@ -1,50 +1,48 @@
.dialog.openJamTrackDialog-overlay.ftue-overlay.tall#open-jam-track-dialog layout="dialog" layout-id="open-jam-track-dialog"
.dialog.openBackingTrackDialog-overlay.ftue-overlay.tall#open-backing-track-dialog layout="dialog" layout-id="open-backing-track-dialog"
.content-head
= image_tag "content/icon_add.png", {:width => 19, :height => 19, :class => 'content-icon' }
h1
| open a jamtrack
| open an audio file
.dialog-inner
.recording-wrapper
table.open-jam-tracks cellspacing="0" cellpadding="0" border="0"
table.open-backing-tracks cellspacing="0" cellpadding="0" border="0"
thead
tr
th align="left"
| NAME
th align="left"
| ORIGINAL ARTIST
| PATH
th align="left"
| DOWNLOADED
a.downloaded-jamtrack-help href="#"
| ?
| LENGTH
/ th align="left"
/ | ORIGINAL ARTIST
/ th align="left"
/ | DOWNLOADED
/ a.downloaded-backingtrack-help href="#"
/ | ?
tbody
br
.left.paginator-holder
.help-links
a.what-are-jamtracks href='#'
| What are JamTracks?
a href='/client#/jamtrack' rel="external"
| Shop for JamTracks
a.what-are-backingtracks href='#'
| What are Backing Tracks?
.right
a href="#" class="button-grey" layout-action="close"
| CANCEL
br clear="all"
script#template-jam-track-row type="text/template"
tr data-recording-id="{{data.jamTrackId}}" data-local-state="{{data.jamTrackState}}"
script#template-backing-track-row type="text/template"
tr data-recording-id="{{data.backingTrackId}}" data-local-state="{{data.backingTrackState}}"
td
| {{data.name}}
td
| {{data.artist}}
| {{data.path}}
td
| {{data.downloaded}}
| {{data.length}}

View File

@ -1,50 +0,0 @@
.dialog.openJamTrackDialog-overlay.ftue-overlay.tall#open-jam-track-dialog layout="dialog" layout-id="open-jam-track-dialog"
.content-head
= image_tag "content/icon_add.png", {:width => 19, :height => 19, :class => 'content-icon' }
h1
| open a jamtrack
.dialog-inner
.recording-wrapper
table.open-jam-tracks cellspacing="0" cellpadding="0" border="0"
thead
tr
th align="left"
| NAME
th align="left"
| ORIGINAL ARTIST
th align="left"
| DOWNLOADED
a.downloaded-jamtrack-help href="#"
| ?
tbody
br
.left.paginator-holder
.help-links
a.what-are-jamtracks href='#'
| What are JamTracks?
a href='/client#/jamtrack' rel="external"
| Shop for JamTracks
.right
a href="#" class="button-grey" layout-action="close"
| CANCEL
br clear="all"
script#template-jam-track-row type="text/template"
tr data-recording-id="{{data.jamTrackId}}" data-local-state="{{data.jamTrackState}}"
td
| {{data.name}}
td
| {{data.artist}}
td
| {{data.downloaded}}

View File

@ -178,7 +178,7 @@ SampleApp::Application.routes.draw do
match '/sessions/:id/details/comments' => 'api_music_sessions#add_session_info_comment', :via => :post
match '/sessions/:id/jam_tracks/:jam_track_id/open' => 'api_music_sessions#jam_track_open', :via => :post
match '/sessions/:id/jam_tracks/close' => 'api_music_sessions#jam_track_close', :via => :post
match '/sessions/:id/backing_tracks/:backing_track_id/open' => 'api_music_sessions#backing_track_open', :via => :post
match '/sessions/:id/backing_tracks/open' => 'api_music_sessions#backing_track_open', :via => :post
match '/sessions/:id/backing_tracks/close' => 'api_music_sessions#backing_track_close', :via => :post
match '/sessions/:id/jam_tracks/:metronome_id/open' => 'api_music_sessions#metronome_open', :via => :post
match '/sessions/:id/metronomes/close' => 'api_music_sessions#metronome_close', :via => :post
@ -195,6 +195,9 @@ SampleApp::Application.routes.draw do
match '/music_notations' => 'api_music_notations#create', :via => :post
match '/music_notations/:id' => 'api_music_notations#download', :via => :get, :as => :download_music_notation
# Backing track_show
match '/backing_tracks' => 'api_backing_tracks#index', :via => :get, :as => 'api_backing_tracks_list'
# Jamtracks
match '/jamtracks' => 'api_jam_tracks#index', :via => :get, :as => 'api_jam_tracks_list'
match '/jamtracks/purchased' => 'api_jam_tracks#purchased', :via => :get, :as => 'api_jam_tracks_purchased'