* wip
This commit is contained in:
parent
b5c446dd04
commit
cc3bf2ce1f
|
|
@ -316,6 +316,9 @@ SQL
|
|||
#ensure that there is no active claimed recording if the owner of that recording left the session
|
||||
conn.exec("UPDATE active_music_sessions set claimed_recording_id = NULL, claimed_recording_initiator_id = NULL where claimed_recording_initiator_id = $1 and id = $2",
|
||||
[user_id, previous_music_session_id])
|
||||
|
||||
conn.exec("UPDATE active_music_sessions set jam_track_id = NULL, jam_track_initiator_id = NULL where jam_track_initiator_id = $1 and id = $2",
|
||||
[user_id, previous_music_session_id])
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -64,8 +64,7 @@ module JamRuby
|
|||
start = start.to_i || 0
|
||||
|
||||
query = JamTrack.joins(:jam_track_tracks)
|
||||
.offset(start)
|
||||
.limit(limit)
|
||||
.paginate(page: 1 + start/limit, per_page: limit)
|
||||
|
||||
if options[:show_purchased_only]
|
||||
query = query.joins(:jam_track_rights)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,130 @@
|
|||
(function(context,$) {
|
||||
|
||||
"use strict";
|
||||
context.JK = context.JK || {};
|
||||
context.JK.OpenJamTrackDialog = 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 $templateOpenJamTrackRow = null;
|
||||
var $downloadedTrackHelp = null;
|
||||
var $whatAreJamTracks = null;
|
||||
|
||||
|
||||
function emptyList() {
|
||||
$tbody.empty();
|
||||
}
|
||||
|
||||
function resetPagination() {
|
||||
$dialog.find('.paginator').remove();
|
||||
}
|
||||
|
||||
function beforeShow() {
|
||||
emptyList();
|
||||
resetPagination();
|
||||
showing = true;
|
||||
getPurchasedJamTracks(0)
|
||||
.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 getPurchasedJamTracks(targetPage);
|
||||
}
|
||||
|
||||
function getPurchasedJamTracks(page) {
|
||||
return rest.getPurchasedJamTracks({page:page + 1, per_page:10})
|
||||
.done(function(purchasedJamTracks) {
|
||||
|
||||
emptyList();
|
||||
|
||||
$.each(purchasedJamTracks.jamtracks, function(index, jamTrack) {
|
||||
|
||||
var options = {}
|
||||
options.jamTrackState = null;
|
||||
options.jamTrackId = jamTrack.id;
|
||||
options.name = jamTrack.name;
|
||||
options.artist = jamTrack.original_artist;
|
||||
options.downloaded = 'Yes'
|
||||
|
||||
var $tr = $(context._.template($templateOpenJamTrackRow.html(), options, { variable: 'data' }));
|
||||
$tr.data('server-model', jamTrack);
|
||||
$tbody.append($tr);
|
||||
});
|
||||
})
|
||||
.fail(function(jqXHR, textStatus, errorMessage) {
|
||||
app.ajaxError(jqXHR, textStatus, errorMessage);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function registerStaticEvents() {
|
||||
$tbody.on('click', 'tr', function(e) {
|
||||
var jamTrack = $(this).data('server-model');
|
||||
|
||||
// tell the server we are about to start a recording
|
||||
rest.openJamTrack({id: context.JK.CurrentSessionModel.id(), jam_track_id: jamTrack.id})
|
||||
.done(function(response) {
|
||||
var result = context.jamClient.JamTrackPlay('t');
|
||||
|
||||
logger.debug("JamTrackPlay response: %o", result);
|
||||
|
||||
if(result) {
|
||||
app.layout.closeDialog('open-jam-track-dialog');
|
||||
}
|
||||
else {
|
||||
logger.error("unable to open jam track")
|
||||
}
|
||||
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
app.notifyServerError(jqXHR, "Unable to Open JamTrack For Playback");
|
||||
})
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
context.JK.helpBubble($downloadedTrackHelp, 'downloaded-jamtrack', {}, {width:'400px'})
|
||||
$downloadedTrackHelp.on('click', false)
|
||||
|
||||
context.JK.helpBubble($whatAreJamTracks, 'no help yet for this topic', {}, {positions:['bottom'], offsetParent: $dialog})
|
||||
$whatAreJamTracks.on('click', false) // no help yet
|
||||
}
|
||||
|
||||
function initialize(){
|
||||
var dialogBindings = {
|
||||
'beforeShow' : beforeShow,
|
||||
'afterHide': afterHide
|
||||
};
|
||||
|
||||
app.bindDialog('open-jam-track-dialog', dialogBindings);
|
||||
|
||||
$dialog = $('#open-jam-track-dialog');
|
||||
$tbody = $dialog.find('table.open-jam-tracks tbody');
|
||||
$paginatorHolder = $dialog.find('.paginator-holder');
|
||||
$templateOpenJamTrackRow = $('#template-jam-track-row')
|
||||
$downloadedTrackHelp = $dialog.find('.downloaded-jamtrack-help')
|
||||
$whatAreJamTracks = $dialog.find('.what-are-jamtracks')
|
||||
|
||||
registerStaticEvents();
|
||||
};
|
||||
|
||||
|
||||
this.initialize = initialize;
|
||||
this.isShowing = function isShowing() { return showing; }
|
||||
}
|
||||
|
||||
return this;
|
||||
})(window,jQuery);
|
||||
|
|
@ -1157,6 +1157,34 @@
|
|||
})
|
||||
}
|
||||
|
||||
function openJamTrack(options) {
|
||||
var musicSessionId = options["id"];
|
||||
var jamTrackId = options["jam_track_id"];
|
||||
delete options["id"];
|
||||
delete options["jam_track_id"];
|
||||
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
url: "/api/sessions/" + musicSessionId + "/jam_tracks/" + jamTrackId + "/open",
|
||||
data: JSON.stringify(options)
|
||||
})
|
||||
}
|
||||
|
||||
function closeJamTrack(options) {
|
||||
var musicSessionId = options["id"];
|
||||
delete options["id"];
|
||||
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
url: "/api/sessions/" + musicSessionId + "/jam_tracks/close",
|
||||
data: JSON.stringify(options)
|
||||
})
|
||||
}
|
||||
|
||||
function discardRecording(options) {
|
||||
var recordingId = options["id"];
|
||||
|
||||
|
|
@ -1319,6 +1347,15 @@
|
|||
});
|
||||
}
|
||||
|
||||
function getPurchasedJamTracks(options) {
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
url: '/api/jamtracks/purchased?' + $.param(options),
|
||||
dataType: "json",
|
||||
contentType: 'application/json'
|
||||
});
|
||||
}
|
||||
|
||||
function addJamtrackToShoppingCart(options) {
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
|
|
@ -1515,6 +1552,8 @@
|
|||
this.claimRecording = claimRecording;
|
||||
this.startPlayClaimedRecording = startPlayClaimedRecording;
|
||||
this.stopPlayClaimedRecording = stopPlayClaimedRecording;
|
||||
this.openJamTrack = openJamTrack;
|
||||
this.closeJamTrack = closeJamTrack;
|
||||
this.discardRecording = discardRecording;
|
||||
this.putTrackSyncChange = putTrackSyncChange;
|
||||
this.createBand = createBand;
|
||||
|
|
@ -1543,6 +1582,7 @@
|
|||
this.getLatencyTester = getLatencyTester;
|
||||
this.updateAudioLatency = updateAudioLatency;
|
||||
this.getJamtracks = getJamtracks;
|
||||
this.getPurchasedJamTracks = getPurchasedJamTracks;
|
||||
this.addJamtrackToShoppingCart = addJamtrackToShoppingCart;
|
||||
this.getShoppingCarts = getShoppingCarts;
|
||||
this.removeShoppingCart = removeShoppingCart;
|
||||
|
|
|
|||
|
|
@ -1658,7 +1658,7 @@
|
|||
}
|
||||
|
||||
function bailOut() {
|
||||
promptLeave = false;
|
||||
promptLeave = false;
|
||||
context.window.location = '/client#/home';
|
||||
}
|
||||
|
||||
|
|
@ -1796,6 +1796,22 @@
|
|||
.fail(app.ajaxError);
|
||||
}
|
||||
|
||||
function openJamTrack(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 jam track while creating a recording.",
|
||||
"icon_url": "/assets/content/icon_alert_big.png"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
app.layout.showDialog('open-jam-track-dialog');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function openRecording(e) {
|
||||
// just ignore the click if they are currently recording for now
|
||||
if(sessionModel.recordingModel.isRecording()) {
|
||||
|
|
@ -1814,6 +1830,36 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
function closeOpenMedia() {
|
||||
if(sessionModel.recordedTracks()) {
|
||||
closeRecording();
|
||||
}
|
||||
else if(sessionModel.jamTrack()) {
|
||||
closeJamTrack();
|
||||
}
|
||||
else {
|
||||
logger.error("don't know how to close open media (backing track?)");
|
||||
}
|
||||
}
|
||||
|
||||
function closeJamTrack() {
|
||||
rest.closeJamTrack({id: sessionModel.id()})
|
||||
.done(function() {
|
||||
sessionModel.refreshCurrentSession();
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
app.notify({
|
||||
"title": "Couldn't Close JamTrack",
|
||||
"text": "Couldn't inform the server to close JamTrack. msg=" + jqXHR.responseText,
|
||||
"icon_url": "/assets/content/icon_alert_big.png"
|
||||
});
|
||||
});
|
||||
|
||||
context.jamClient.JamTrackStopPlay();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function closeRecording() {
|
||||
rest.stopPlayClaimedRecording({id: sessionModel.id(), claimed_recording_id: sessionModel.getCurrentSession().claimed_recording.id})
|
||||
.done(function() {
|
||||
|
|
@ -1857,7 +1903,7 @@
|
|||
}
|
||||
|
||||
function inviteMusicians() {
|
||||
friendInput = inviteMusiciansUtil.inviteSessionUpdate('#update-session-invite-musicians',
|
||||
friendInput = inviteMusiciansUtil.inviteSessionUpdate('#update-session-invite-musicians',
|
||||
sessionId);
|
||||
inviteMusiciansUtil.loadFriends();
|
||||
$(friendInput).show();
|
||||
|
|
@ -1892,6 +1938,7 @@
|
|||
$('#tracks').on('click', 'div[control="mute"]', toggleMute);
|
||||
$('#recording-start-stop').on('click', startStopRecording);
|
||||
$('#open-a-recording').on('click', openRecording);
|
||||
$('#open-a-jamtrack').on('click', openJamTrack);
|
||||
$('#session-invite-musicians').on('click', inviteMusicians);
|
||||
$('#session-invite-musicians2').on('click', inviteMusicians);
|
||||
$('#track-settings').click(function() {
|
||||
|
|
@ -1900,7 +1947,7 @@
|
|||
configureTrackDialog.showMusicAudioPanel(true);
|
||||
});
|
||||
|
||||
$('#close-playback-recording').on('click', closeRecording);
|
||||
$('#close-playback-recording').on('click', closeOpenMedia);
|
||||
$(playbackControls)
|
||||
.on('pause', onPause)
|
||||
.on('play', onPlay)
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@
|
|||
/**
|
||||
* Associates a help bubble on hover (by default) with the specified $element, using jquery.bt.js (BeautyTips)
|
||||
* @param $element The element that should show the help when hovered
|
||||
* @param templateName the name of the help template (without the '#template-help' prefix). Add to _help.html.erb
|
||||
* @param templateName the name of the help template (without the '#template-help' prefix). Add to _help.html.slim
|
||||
* @param data (optional) data for your template, if applicable
|
||||
* @param options (optional) You can override the default BeautyTips options: https://github.com/dillon-sellars/BeautyTips
|
||||
*/
|
||||
|
|
@ -146,7 +146,7 @@
|
|||
/**
|
||||
* Meant to show a little bubble to confirm something happened, in a way less obtrusive than a app.notify
|
||||
* @param $element The element that should show the help when hovered
|
||||
* @param templateName the name of the help template (without the '#template-help' prefix). Add to _help.html.erb
|
||||
* @param templateName the name of the help template (without the '#template-help' prefix). Add to _help.html.slim
|
||||
* @param data (optional) data for your template, if applicable
|
||||
* @param options (optional) You can override the default BeautyTips options: https://github.com/dillon-sellars/BeautyTips
|
||||
*/
|
||||
|
|
@ -167,7 +167,7 @@
|
|||
* This will open a bubble immediately and show it for 4 seconds,
|
||||
* if you call it again before the 4 second timer is up, it will renew the 4 second timer.
|
||||
* @param $element The element that should show the help when hovered
|
||||
* @param templateName the name of the help template (without the '#template-help' prefix). Add to _help.html.erb
|
||||
* @param templateName the name of the help template (without the '#template-help' prefix). Add to _help.html.slim
|
||||
* @param data (optional) data for your template, if applicable
|
||||
* @param options (optional) You can override the default BeautyTips options: https://github.com/dillon-sellars/BeautyTips
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -106,6 +106,33 @@
|
|||
top:3px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.session-recording-name-wrapper{
|
||||
position:relative;
|
||||
white-space:nowrap;
|
||||
display:none;
|
||||
|
||||
.session-add {
|
||||
margin-top:9px;
|
||||
}
|
||||
.session-add a {
|
||||
vertical-align:top;
|
||||
outline:none;
|
||||
|
||||
img {
|
||||
margin-top:-3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.session-recording-name {
|
||||
width:60%;
|
||||
overflow:hidden;
|
||||
margin-top:9px;
|
||||
margin-bottom:8px;
|
||||
font-size:16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -312,33 +339,6 @@ table.vu td {
|
|||
vertical-align:bottom;
|
||||
}
|
||||
|
||||
.session-recording-name-wrapper {
|
||||
position:relative;
|
||||
white-space:nowrap;
|
||||
display:none;
|
||||
|
||||
.session-add {
|
||||
margin-top:9px;
|
||||
}
|
||||
.session-add a {
|
||||
vertical-align:top;
|
||||
outline:none;
|
||||
|
||||
img {
|
||||
margin-top:-3px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.session-recording-name {
|
||||
width:60%;
|
||||
overflow:hidden;
|
||||
margin-top:9px;
|
||||
margin-bottom:8px;
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
.session-tracks-scroller {
|
||||
position:relative;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
@import "client/common";
|
||||
|
||||
|
||||
table.findsession-table, table.local-recordings, #account-session-detail {
|
||||
table.findsession-table, table.local-recordings, table.open-jam-tracks, #account-session-detail {
|
||||
|
||||
.latency-unacceptable {
|
||||
width: 50px;
|
||||
|
|
@ -64,7 +64,7 @@ table.findsession-table, table.local-recordings, #account-session-detail {
|
|||
text-align:center;
|
||||
}
|
||||
}
|
||||
table.findsession-table, table.local-recordings {
|
||||
table.findsession-table, table.local-recordings, table.open-jam-tracks {
|
||||
width:98%;
|
||||
height:10%;
|
||||
font-size:11px;
|
||||
|
|
@ -77,6 +77,9 @@ table.findsession-table, table.local-recordings {
|
|||
background-color:#4d4d4d;
|
||||
padding:6px;
|
||||
border-right:solid 1px #333;
|
||||
a {
|
||||
color: #fc0;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,26 @@
|
|||
@import "client/common";
|
||||
|
||||
#local-recordings-dialog {
|
||||
table.local-recordings {
|
||||
tbody {
|
||||
tr:hover {
|
||||
background-color: #400606;
|
||||
background-color: #777;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
tr[data-local-state=MISSING], tr[data-local-state=PARTIALLY_MISSING] {
|
||||
background-color:#777;
|
||||
background-color:#400606;
|
||||
color:#aaa;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
.paginator-holder {
|
||||
padding-top:3px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
@import "client/common";
|
||||
|
||||
#open-jam-track-dialog {
|
||||
table.open-jam-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-jamtrack-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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -13,6 +13,16 @@ class ApiJamTracksController < ApiController
|
|||
render "api_jam_tracks/index", :layout => nil
|
||||
end
|
||||
|
||||
def purchased
|
||||
params[:show_purchased_only] = true
|
||||
data = JamTrack.index(params, current_user)
|
||||
@jam_tracks, @next = data[0], data[1]
|
||||
|
||||
response.headers['total-entries'] = @jam_tracks.total_entries.to_s
|
||||
|
||||
render "api_jam_tracks/purchased", :layout => nil
|
||||
end
|
||||
|
||||
def downloads
|
||||
begin
|
||||
render :json => JamTrack.list_downloads(current_user, params[:limit], params[:since]), :status => 200
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
node :next do |page|
|
||||
@next
|
||||
end
|
||||
|
||||
node :jamtracks do |page|
|
||||
partial "api_jam_tracks/show_for_client", object: @jam_tracks
|
||||
end
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
object @jam_track
|
||||
|
||||
attributes :id, :name, :description, :initial_play_silence, :original_artist
|
||||
|
||||
child(:jam_track_tracks => :tracks) {
|
||||
attributes :id, :part, :instrument
|
||||
}
|
||||
|
||||
child(:jam_track_tap_ins => :tap_ins) {
|
||||
attributes :offset_time, :bpm, :tap_in_count
|
||||
}
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
<script type="text/template" id="template-help-pre-processed-track">
|
||||
This track has not yet been processed into master form and may include multiple streams from the source musician.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-refocus-rescore">
|
||||
{% if(data.validIOScore) { %}
|
||||
We have re-scored latency based on your changes.
|
||||
{% } else { %}
|
||||
We have re-scored latency and IO based on your changes.
|
||||
{% } %}
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-ftue-watch-video">
|
||||
Be sure to watch the help video.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-chat-not-enabled">
|
||||
You must first chose this option in order to activate a chat input.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-select-input">
|
||||
You still need to select an input device.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-select-output">
|
||||
Select an output device, because the current input device has no candidate output ports.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-push-resync-when-done">
|
||||
Push 'Resync' when done modifying Framesize, Buffer In, or Buffer Out.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-can-move-on">
|
||||
<div class="help-can-move-on">
|
||||
You can move to the next step now.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-tweak-asio-settings">
|
||||
Click here to try faster ASIO settings.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-session-plus-musicians">
|
||||
Plus any interested JamKazam musicians that I approve.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-minimum-output-channels">
|
||||
To be a valid output audio device, it must have at least 2 output ports.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-follower-count">
|
||||
The number of followers that this {{data.entity_type}} has.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-friend-count">
|
||||
The number of friends that this {{data.entity_type}} has.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-recording-count">
|
||||
The number of recordings that this {{data.entity_type}} has made.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-session-count">
|
||||
The number of sessions that this {{data.entity_type}} has played in.
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-musician-score-count">
|
||||
<div class="help-musician-score-count">
|
||||
<p>The score shown is the one-way latency (or delay) in milliseconds from you to this user. This score is calculated using the following three values that JamKazam gathers:</p>
|
||||
<ul>
|
||||
<li><span class="definition">Your Audio Gear Latency:</span> <span class="measurement my-gear-latency partial"><span class="measurement-value">{{data.my_gear_latency ? data.my_gear_latency + ' ms': '13 ms*'}}</span> <span class="measurement-absent">{{data.my_gear_latency ? '' : "(you have not qualified any gear, so we picked an average gear latency)"}}</span></span></li>
|
||||
<li><span class="definition">Their Audio Gear Latency:</span> <span class="measurement their-gear-latency partial"><span class="measurement-value">{{data.their_gear_latency ? data.their_gear_latency + ' ms': '13 ms*'}}</span> <span class="measurement-absent">{{data.their_gear_latency ? '' : "(they have not qualified any gear, so we picked an average gear latency)"}}</span></span></li>
|
||||
<li><span class="definition">Round-trip Internet Latency:</span> <span class="measurement internet-latency partial"><span class="measurement-value">{{data.internet_latency ? data.internet_latency + ' ms': '?'}}</span> <span class="measurement-absent">{{data.internet_latency ? '' : "(we have not scored you with this user yet)"}}</span></span></li>
|
||||
</ul>
|
||||
<p> <span class="definition">Total One-Way Latency:</span> <span class="measurement my-gear-latency"><span class="measurement-value">( {{data.my_gear_latency ? data.my_gear_latency: '13'}} + {{data.their_gear_latency ? data.their_gear_latency: '13'}} + {{data.internet_latency ? data.internet_latency: '?'}} ) / 2 = {{data.full_score ? data.full_score + ' ms' : "?"}}</span> <span class="measurement-absent">{{data.full_score ? '' : "(when we don't know internet latency, we don't try to guess your one-way latency)"}}</span></span>
|
||||
|
||||
<p>We categorize this score as good, fair, poor, unacceptable, or unknown. Those categories are defined as follows:
|
||||
<ul>
|
||||
<li><span class="definition">Good:</span> 20ms or less <img src="/assets/content/icon_green_score.png" /></li>
|
||||
<li><span class="definition">Fair:</span> 20ms to 35ms <img src="/assets/content/icon_yellow_score.png" /></li>
|
||||
<li><span class="definition">Poor:</span> 35ms to 50ms <img src="/assets/content/icon_red_score.png" /></li>
|
||||
<li><span class="definition">Unacceptable:</span> Above 50ms <img src="/assets/content/icon_blue_score.png" /></li>
|
||||
<li><span class="definition">Unknown:</span> No internet score is available between you and them. <img src="/assets/content/icon_purple_score.png" /></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-musician-score-self">
|
||||
<div class="help-musician-score-self">
|
||||
<p>You are looking at your own account.</p>
|
||||
<p>Try hovering over other user's latency score to find out your one-way latency to them.</p>
|
||||
<p><span class="definition">Your Audio Gear Latency:</span> <span class="measurement my-gear-latency"><span class="measurement-value">{{data.my_gear_latency ? data.my_gear_latency + ' ms': '13 ms*'}}</span> <span class="measurement-absent">{{data.my_gear_latency ? '' : "(you have not qualified any gear, so we picked an average gear latency)"}}</span></span></p>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-gear-wizard-inputs-changed">
|
||||
<div class='help-inputs-changed'>
|
||||
{% if(data.missingInputDevice) { %}
|
||||
<p> {{ data.missingInputDevice }} is no longer connected or malfunctioning.
|
||||
{% } %}
|
||||
{% if(data.newInputDevice) { %}
|
||||
<p> {{ data.newInputDevice }} is now available.
|
||||
{% } %}
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/template" id="template-help-gear-wizard-outputs-changed">
|
||||
<div class='help-outputs-changed'>
|
||||
{% if(data.missingOutputDevice) { %}
|
||||
<p> {{ data.missingOutputDevice }} is no longer connected or malfunctioning.
|
||||
{% } %}
|
||||
{% if(data.newOutputDevice) { %}
|
||||
<p> {{ data.newOutputDevice }} is now available.
|
||||
{% } %}
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/template" id="template-help-no-audio-profiles">
|
||||
<div class="help-no-audio-profiles">
|
||||
Click here to configure new audio gear.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-file-manager-poke">
|
||||
<div class="help-file-manager-poke">
|
||||
<p>After the session is over, your recording will synchronize with the server to make a final mix.</p>
|
||||
|
||||
<p>You can find out more by clicking <em>File Manager</em> at any time.</p>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-sync-viewer-paused">
|
||||
<div class="help-sync-viewer-paused">
|
||||
JamKazam prevents file uploads, downloads, and recording management while in a session.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-sync-viewer-retry">
|
||||
<div class="help-sync-viewer-retry">
|
||||
Your request will be attempted as soon as possible.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-recording-discarded-soon">
|
||||
<div class="help-recording-discarded-soon">
|
||||
This recording will be discarded {% $.timeago(data.discardTime) %}. If you want to keep this recording, click the (edit) link.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/template" id="template-help-command-enqueued">
|
||||
<div class="help-recording-command-enqueued">
|
||||
Your request will be executed as soon as possible.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-file-sync-delayed-deletion">
|
||||
<div class="file-sync-delayed-deletion">
|
||||
The files associated with this recording will be deleted as soon as your client has uploaded your tracks and stream mix from this recording.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-media-controls-disabled">
|
||||
{% if(data.mediaTrackOpener) { %}
|
||||
Switch <b>MIX:</b> to <b>Master</b> mode to have control over volume levels.
|
||||
{% } else { %}
|
||||
Only the person who opened the recording can control the volume levels.
|
||||
{% } %}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
script type="text/template" id="template-help-pre-processed-track"
|
||||
| This track has not yet been processed into master form and may include multiple streams from the source musician.
|
||||
|
||||
script type="text/template" id="template-help-refocus-rescore"
|
||||
| {% if(data.validIOScore) { %}
|
||||
| We have re-scored latency based on your changes.
|
||||
| {% } else { %}
|
||||
| We have re-scored latency and IO based on your changes.
|
||||
| {% } %}
|
||||
|
||||
script type="text/template" id="template-help-ftue-watch-video"
|
||||
| Be sure to watch the help video.
|
||||
|
||||
script type="text/template" id="template-help-chat-not-enabled"
|
||||
| You must first chose this option in order to activate a chat input.
|
||||
|
||||
script type="text/template" id="template-help-select-input"
|
||||
| You still need to select an input device.
|
||||
|
||||
script type="text/template" id="template-help-select-output"
|
||||
| Select an output device, because the current input device has no candidate output ports.
|
||||
|
||||
script type="text/template" id="template-help-push-resync-when-done"
|
||||
| Push 'Resync' when done modifying Framesize, Buffer In, or Buffer Out.
|
||||
|
||||
script type="text/template" id="template-help-can-move-on"
|
||||
.help-can-move-on
|
||||
| You can move to the next step now.
|
||||
|
||||
script type="text/template" id="template-help-tweak-asio-settings"
|
||||
| Click here to try faster ASIO settings.
|
||||
|
||||
script type="text/template" id="template-help-session-plus-musicians"
|
||||
| Plus any interested JamKazam musicians that I approve.
|
||||
|
||||
script type="text/template" id="template-help-minimum-output-channels"
|
||||
| To be a valid output audio device, it must have at least 2 output ports.
|
||||
|
||||
script type="text/template" id="template-help-follower-count"
|
||||
| The number of followers that this {{data.entity_type}} has.
|
||||
|
||||
script type="text/template" id="template-help-friend-count"
|
||||
| The number of friends that this {{data.entity_type}} has.
|
||||
|
||||
script type="text/template" id="template-help-recording-count"
|
||||
| The number of recordings that this {{data.entity_type}} has made.
|
||||
|
||||
script type="text/template" id="template-help-session-count"
|
||||
| The number of sessions that this {{data.entity_type}} has played in.
|
||||
|
||||
script type="text/template" id="template-help-musician-score-count"
|
||||
.help-musician-score-count
|
||||
p
|
||||
| The score shown is the one-way latency (or delay) in milliseconds from you to this user. This score is calculated using the following three values that JamKazam gathers:
|
||||
ul
|
||||
li
|
||||
span.definition
|
||||
| Your Audio Gear Latency:
|
||||
span.measurement.my-gear-latency.partial
|
||||
span.measurement-value
|
||||
| {{data.my_gear_latency ? data.my_gear_latency + ' ms': '13 ms*'}}
|
||||
span.measurement-absent
|
||||
| {{data.my_gear_latency ? '' : "(you have not qualified any gear, so we picked an average gear latency)"}}
|
||||
|
||||
li
|
||||
span.definition
|
||||
| Their Audio Gear Latency:
|
||||
span.measurement.their-gear-latency.partial
|
||||
span.measurement-value
|
||||
| {{data.their_gear_latency ? data.their_gear_latency + ' ms': '13 ms*'}}
|
||||
span.measurement-absent
|
||||
| {{data.their_gear_latency ? '' : "(they have not qualified any gear, so we picked an average gear latency)"}}
|
||||
li
|
||||
span.definition
|
||||
| Round-trip Internet Latency:
|
||||
span.measurement.internet-latency.partial
|
||||
span.measurement-value
|
||||
| {{data.internet_latency ? data.internet_latency + ' ms': '?'}}
|
||||
span.measurement-absent
|
||||
| {{data.internet_latency ? '' : "(we have not scored you with this user yet)"}}
|
||||
p
|
||||
span.definition
|
||||
| Total One-Way Latency:
|
||||
span.measurement.my-gear-latency
|
||||
span.measurement-value
|
||||
| ( {{data.my_gear_latency ? data.my_gear_latency: '13'}} + {{data.their_gear_latency ? data.their_gear_latency: '13'}} + {{data.internet_latency ? data.internet_latency: '?'}} ) / 2 = {{data.full_score ? data.full_score + ' ms' : "?"}}
|
||||
span.measurement-absent
|
||||
| {{data.full_score ? '' : "(when we don't know internet latency, we don't try to guess your one-way latency)"}}
|
||||
|
||||
p
|
||||
| We categorize this score as good, fair, poor, unacceptable, or unknown. Those categories are defined as follows:
|
||||
ul
|
||||
li
|
||||
span.definition
|
||||
| Good:
|
||||
| 20ms or less
|
||||
img src="/assets/content/icon_green_score.png"
|
||||
li
|
||||
span.definition
|
||||
| Fair:
|
||||
| 20ms to 35ms
|
||||
img src="/assets/content/icon_yellow_score.png"
|
||||
li
|
||||
span.definition
|
||||
| Poor:
|
||||
| 35ms to 50ms
|
||||
img src="/assets/content/icon_red_score.png"
|
||||
li
|
||||
span.definition
|
||||
| Unacceptable:
|
||||
| Above 50ms
|
||||
img src="/assets/content/icon_blue_score.png"
|
||||
li
|
||||
span.definition
|
||||
| Unknown:
|
||||
| No internet score is available between you and them.
|
||||
img src="/assets/content/icon_purple_score.png"
|
||||
|
||||
script type="text/template" id="template-help-musician-score-self"
|
||||
.help-musician-score-self
|
||||
p
|
||||
| You are looking at your own account.
|
||||
p
|
||||
| Try hovering over other user's latency score to find out your one-way latency to them.
|
||||
p
|
||||
span.definition
|
||||
| Your Audio Gear Latency:
|
||||
span.measurement.my-gear-latency
|
||||
span.measurement-value
|
||||
| {{data.my_gear_latency ? data.my_gear_latency + ' ms': '13 ms*'}}
|
||||
span.measurement-absent
|
||||
| {{data.my_gear_latency ? '' : "(you have not qualified any gear, so we picked an average gear latency)"}}
|
||||
|
||||
script type="text/template" id="template-help-gear-wizard-inputs-changed"
|
||||
.help-inputs-changed
|
||||
| {% if(data.missingInputDevice) { %}
|
||||
p
|
||||
| {{ data.missingInputDevice }} is no longer connected or malfunctioning.
|
||||
| {% } %}
|
||||
| {% if(data.newInputDevice) { %}
|
||||
p
|
||||
| {{ data.newInputDevice }} is now available.
|
||||
| {% } %}
|
||||
|
||||
|
||||
script type="text/template" id="template-help-gear-wizard-outputs-changed"
|
||||
.help-outputs-changed
|
||||
| {% if(data.missingOutputDevice) { %}
|
||||
p
|
||||
| {{ data.missingOutputDevice }} is no longer connected or malfunctioning.
|
||||
| {% } %}
|
||||
| {% if(data.newOutputDevice) { %}
|
||||
p
|
||||
| {{ data.newOutputDevice }} is now available.
|
||||
| {% } %}
|
||||
|
||||
|
||||
script type="text/template" id="template-help-no-audio-profiles"
|
||||
.help-no-audio-profiles
|
||||
| Click here to configure new audio gear.
|
||||
|
||||
script type="text/template" id="template-help-file-manager-poke"
|
||||
.help-file-manager-poke
|
||||
p
|
||||
| After the session is over, your recording will synchronize with the server to make a final mix.
|
||||
p
|
||||
| You can find out more by clicking
|
||||
em File Manager
|
||||
| at any time.
|
||||
|
||||
script type="text/template" id="template-help-sync-viewer-paused"
|
||||
.help-sync-viewer-paused
|
||||
| JamKazam prevents file uploads, downloads, and recording management while in a session.
|
||||
|
||||
script type="text/template" id="template-help-sync-viewer-retry"
|
||||
.help-sync-viewer-retry
|
||||
| Your request will be attempted as soon as possible.
|
||||
|
||||
script type="text/template" id="template-help-recording-discarded-soon"
|
||||
.help-recording-discarded-soon
|
||||
| This recording will be discarded {% $.timeago(data.discardTime) %}. If you want to keep this recording, click the (edit) link.
|
||||
|
||||
script type="text/template" id="template-help-command-enqueued"
|
||||
.help-recording-command-enqueued
|
||||
| Your request will be executed as soon as possible.
|
||||
|
||||
script type="text/template" id="template-help-file-sync-delayed-deletion"
|
||||
.file-sync-delayed-deletion
|
||||
| The files associated with this recording will be deleted as soon as your client has uploaded your tracks and stream mix from this recording.
|
||||
|
||||
script type="text/template" id="template-help-media-controls-disabled"
|
||||
| {% if(data.mediaTrackOpener) { %}
|
||||
| Switch
|
||||
b MIX:
|
||||
| to
|
||||
b Master
|
||||
| mode to have control over volume levels.
|
||||
| {% } else { %}
|
||||
| Only the person who opened the recording can control the volume levels.
|
||||
| {% } %}
|
||||
|
||||
script type="text/template" id="template-help-downloaded-jamtrack"
|
||||
.downloaded-jamtrack
|
||||
p When a JamTrack is first purchased, a user-specific version of it is created on the server. Once it's ready, it's then downloaded to the client.
|
||||
p However, in some cases, you may need to download the JamTrack again (if you change machines, for instance).
|
||||
p If you do not currently have it and try to open it now, we will try to download it immediately.
|
||||
|
|
@ -116,8 +116,10 @@
|
|||
<span class="open-media-file-header"><%= image_tag "content/icon_folder.png", {width:22, height:20} %> Open:</span>
|
||||
<ul class="open-media-file-options">
|
||||
<li><a href="#" id="open-a-recording">Recording</a></li>
|
||||
<!--<li>JamTrack</li>
|
||||
<li>Audio File</li>-->
|
||||
<% if Rails.application.config.jam_tracks_available %>
|
||||
<li><a href="#" id="open-a-jamtrack">JamTrack</a></li>
|
||||
<% end %>
|
||||
<!--<li>Audio File</li>-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -152,6 +152,9 @@
|
|||
var localRecordingsDialog = new JK.LocalRecordingsDialog(JK.app);
|
||||
localRecordingsDialog.initialize();
|
||||
|
||||
var openJamTrackDialog = new JK.OpenJamTrackDialog(JK.app);
|
||||
openJamTrackDialog.initialize();
|
||||
|
||||
var configureTracksDialog = new JK.ConfigureTracksDialog(JK.app);
|
||||
configureTracksDialog.initialize();
|
||||
|
||||
|
|
|
|||
|
|
@ -31,3 +31,4 @@
|
|||
= render 'dialogs/changeSearchLocationDialog'
|
||||
= render 'dialogs/allSyncsDialog'
|
||||
= render 'dialogs/adjustGearSpeedDialog'
|
||||
= render 'dialogs/openJamTrackDialog'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
<!-- Invitation Dialog -->
|
||||
<div class="dialog localRecordings-overlay ftue-overlay tall" layout="dialog" layout-id="localRecordings" id="local-recordings-dialog">
|
||||
|
||||
<div class="content-head">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
.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}}
|
||||
|
||||
|
||||
|
|
@ -193,6 +193,7 @@ SampleApp::Application.routes.draw do
|
|||
|
||||
# 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'
|
||||
match '/jamtracks/downloads' => 'api_jam_tracks#downloads', :via => :get, :as => 'api_jam_tracks_downloads'
|
||||
match '/jamtracks/download/:id' => 'api_jam_tracks#download', :via => :get, :as => 'api_jam_tracks_download'
|
||||
match '/jamtracks/keys' => 'api_jam_tracks#keys', :via => :post, :as => 'api_jam_tracks_keys'
|
||||
|
|
|
|||
|
|
@ -82,8 +82,27 @@ describe ApiJamTracksController do
|
|||
response.status.should == 202
|
||||
response.body.should =~ /not available.*/
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "purchased" do
|
||||
it "can return empty" do
|
||||
get :purchased
|
||||
response.should be_success
|
||||
json = JSON.parse(response.body)
|
||||
json['jamtracks'].length.should eq(0)
|
||||
json['next'].should eq(nil)
|
||||
end
|
||||
|
||||
it "can return single item" do
|
||||
# purchase the item for the user
|
||||
right = FactoryGirl.create(:jam_track_right, jam_track: @jam_track, user: @user)
|
||||
|
||||
get :purchased
|
||||
response.should be_success
|
||||
json = JSON.parse(response.body)
|
||||
json['jamtracks'].length.should eq(1)
|
||||
json['next'].should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "with a JamTrack" do
|
||||
|
|
|
|||
Loading…
Reference in New Issue