This commit is contained in:
Seth Call 2014-05-22 11:26:56 -05:00
parent e4da30f39e
commit fcc7130536
19 changed files with 474 additions and 100 deletions

View File

@ -4,6 +4,10 @@ module JamRuby
belongs_to :connection, class_name: 'JamRuby::Connection', foreign_key: :client_id, primary_key: :client_id
def self.select_latency_tester
LatencyTester.joins(:connection).first
end
# we need to find that latency_tester with the specified connection (and reconnect it)
# or bootstrap a new latency_tester
def self.connect(options)

View File

@ -20,7 +20,6 @@
var channelId = null;
var clientType = null;
var mode = null;
var rest = context.JK.Rest();
// heartbeat
var heartbeatInterval = null;

View File

@ -444,6 +444,7 @@
function SessionStartRecording() {}
function SessionStopPlay() {}
function SessionStopRecording() {}
function SessionRemoveAllPlayTracks(){}
function isSessionTrackPlaying() { return false; }
function SessionCurrrentPlayPosMs() { return 0; }
function SessionGetTracksPlayDurationMs() { return 0; }
@ -825,6 +826,7 @@
this.SessionStartPlay = SessionStartPlay;
this.SessionStartRecording = SessionStartRecording;
this.SessionStopPlay = SessionStopPlay;
this.SessionRemoveAllPlayTracks = SessionRemoveAllPlayTracks;
this.SessionStopRecording = SessionStopRecording;
this.isSessionTrackPlaying = isSessionTrackPlaying;
this.SessionCurrrentPlayPosMs = SessionCurrrentPlayPosMs;

View File

@ -2,11 +2,11 @@
"use strict";
context.JK = context.JK || {};
context.JK.GearWizard = function (app) {
var $dialog = null;
var wizard = null;
var $wizardSteps = null;
var $currentWizardStep = null;
var step = null;
@ -57,83 +57,6 @@
});
}
function beforeHideStep() {
if(!previousStep) {return}
var stepInfo = STEPS[previousStep];
if (!stepInfo) {
throw "unknown step: " + previousStep;
}
if(stepInfo.beforeHide) {
stepInfo.beforeHide.call(stepInfo);
}
}
function beforeShowStep($step) {
var stepInfo = STEPS[step];
if (!stepInfo) {
throw "unknown step: " + step;
}
stepInfo.beforeShow.call(stepInfo);
}
function moveToStep() {
var $nextWizardStep = $wizardSteps.filter($('[layout-wizard-step=' + step + ']'));
beforeHideStep();
$wizardSteps.hide();
$currentWizardStep = $nextWizardStep;
var $ftueSteps = $(context._.template($templateSteps.html(), {}, { variable: 'data' }));
var $activeStep = $ftueSteps.find('.ftue-stepnumber[data-step-number="' + step + '"]');
$activeStep.addClass('.active');
$activeStep.next().show(); // show the .ftue-step-title
$currentWizardStep.find('.ftuesteps').replaceWith($ftueSteps);
// update buttons
var $ftueButtonsContent = $(context._.template($templateButtons.html(), {}, {variable: 'data'}));
$btnBack = $ftueButtonsContent.find('.btn-back');
$btnNext = $ftueButtonsContent.find('.btn-next');
$btnClose = $ftueButtonsContent.find('.btn-close');
$btnCancel = $ftueButtonsContent.find('.btn-cancel');
// hide back button if 1st step or last step
if (step == 0 && step == TOTAL_STEPS - 1) {
$btnBack.hide();
}
// hide next button if not on last step
if (step == TOTAL_STEPS - 1) {
$btnNext.hide();
}
// hide close if on last step
if (step != TOTAL_STEPS - 1) {
$btnClose.hide();
}
// hide cancel if not on last step
if (step == TOTAL_STEPS - 1) {
$btnCancel.hide();
}
$btnNext.on('click', next);
$btnBack.on('click', back);
$btnClose.on('click', closeDialog);
$btnCancel.on('click', closeDialog);
$ftueButtons.empty();
$ftueButtons.append($ftueButtonsContent);
beforeShowStep($currentWizardStep);
$currentWizardStep.show();
}
function reset() {
$currentWizardStep = null;
@ -168,10 +91,7 @@
context.jamClient.FTUESetStatus(false);
findOrCreateFTUEProfile();
step = args.d1;
if (!step) step = 0;
step = parseInt(step);
moveToStep(null);
wizard.beforeShow(args);
}
function afterShow() {
@ -266,7 +186,7 @@
$dialog = $('#gear-wizard-dialog');
$wizardSteps = $dialog.find('.wizard-step');
$templateSteps = $('#template-ftuesteps');
$templateButtons = $('#template-ftue-buttons');
$templateButtons = $('#template-wizard-buttons');
$ftueButtons = $dialog.find('.ftue-buttons');
stepUnderstandGear.initialize($wizardSteps.filter($('[layout-wizard-step=0]')));

View File

@ -0,0 +1,15 @@
(function (context, $) {
"use strict";
context.JK = context.JK || {};
context.JK.LoopbackWizard = function (app) {
var $dialog = null;
var $wizardSteps = null;
}
})(window, jQuery);

View File

@ -9,6 +9,7 @@
var VOICE_CHAT = context.JK.VOICE_CHAT;
var MAX_TRACKS = context.JK.MAX_TRACKS;
var logger = context.JK.logger;
var $step = null;
var $templateAssignablePort = null;

View File

@ -7,6 +7,7 @@
var ASSIGNMENT = context.JK.ASSIGNMENT;
var VOICE_CHAT = context.JK.VOICE_CHAT;
var logger = context.JK.logger;
var $step = null;
var $reuseAudioInputRadio = null;

View File

@ -6,16 +6,88 @@
context.JK.StepDirectMonitoring = function (app) {
var $step = null;
var $directMonitoringBtn = null;
var isPlaying = false;
var playCheckInterval = null;
var trackDurationMs = null;
function checkIfPlaying() {
var currentPositionMs = context.jamClient.SessionCurrrentPlayPosMs();
var atEnd = currentPositionMs == 0 || trackDurationMs == currentPositionMs;
if(atEnd) {
context.jamClient.SessionStopPlay();
startPlay();
}
}
function startPlay() {
context.jamClient.SessionTrackSeekMs(0);
context.jamClient.SessionStartPlay(1);
$directMonitoringBtn.removeClass('playing paused').addClass('playing');
trackDurationMs = context.jamClient.SessionGetTracksPlayDurationMs();
if(!playCheckInterval) {
playCheckInterval = setInterval(checkIfPlaying, 333);
}
isPlaying = true;
}
function stopPlay() {
context.jamClient.SessionStopPlay();
$directMonitoringBtn.removeClass('playing paused').addClass('paused');
isPlaying = false;
}
function togglePlay() {
if(isPlaying) {
stopPlay();
}
else {
startPlay();
}
}
function handleNext() {
}
function newSession() {
}
function beforeShow() {
context.jamClient.SessionRemoveAllPlayTracks();
if(!context.jamClient.SessionAddPlayTrack("skin:jktest-audio.wav")) {
context.JK.alertSupportedNeeded('Unable to open test sound');
}
}
function beforeHide() {
if(isPlaying) {
stopPlay();
}
context.jamClient.SessionRemoveAllPlayTracks();
if(playCheckInterval) {
clearTimeout(playCheckInterval);
playCheckInterval = null;
}
}
function initialize(_$step) {
$step = _$step;
$directMonitoringBtn = $step.find('.test-direct-monitoring');
$directMonitoringBtn.on('click', togglePlay);
}
this.handleNext = handleNext;
this.newSession = newSession;
this.beforeShow = beforeShow;
this.beforeHide = beforeHide;
this.initialize = initialize;
return this;

View File

@ -3,21 +3,97 @@
"use strict";
context.JK = context.JK || {};
context.JK.StepNetworkTest = function (app) {
context.JK.StepNetworkTest = function (app, $dialog) {
var rest = context.JK.Rest();
var logger = context.JK.logger;
var $step = null;
var TEST_SUCCESS_CALLBACK = 'JK.HandleNetworkTestSuccess';
var TEST_TIMEOUT_CALLBACK = 'JK.HandleNetworkTestTimeout';
var $startNetworkTestBtn = null;
var $testResults = null;
var $testScore = null;
var $testText = null;
var testedSuccessfully = false;
var serverClientId = null;
var isScoring = false;
function startNetworkTest() {
isScoring = true;
rest.getLatencyTester()
.done(function(response) {
serverClientId = response.client_id;
logger.info("beginning network test against client_id: " + clientId);
context.jamClient.TestNetworkPktBwRate(serverClientId, TEST_SUCCESS_CALLBACK, TEST_TIMEOUT_CALLBACK);
})
.fail(function() {
isScoring = false;
logger.error("arguments:", arguments);
if(context.JK.isNetworkError(arguments)) {
context.JK.Banner.showAlert("Please try again latery. Your network appears down.");
}
else {
logger.error("unable to get latency tester from server");
}
})
logger.info("starting network test");
return false;
}
function networkTestSuccess() {
console.log("success arguments: ", arguments);
context.jamClient.StopNetworkTest(serverClientId);
}
function networkTestTimeout() {
console.log("timeout arguments:", arguments);
context.jamClient.StopNetworkTest(serverClientId);
}
function hasScoredNetworkSuccessfully() {
return testedSuccessfully;
}
function initializeNextButtonState() {
$dialog.setNextState(hasScoredNetworkSuccessfully());
}
function initializeBackButtonState() {
$dialog.setNextState();
}
function newSession() {
isScoring = false;
// XXX context.jamClient.stopNetworkTest();
}
function beforeShow() {
initializeNextButtonState();
}
function initialize(_$step) {
$step = _$step;
$startNetworkTestBtn = $step.find('.start-network-test');
$testResults = $step.find('.network-test-results');
$testScore = $step.find('.network-test-score');
$testText = $step.find('.network-test-text');
$startNetworkTestBtn.on('click', startNetworkTest);
}
this.newSession = newSession;
this.beforeShow = beforeShow;
this.initialize = initialize;
context.JK.HandleNetworkTestSuccess = networkTestSuccess; // pin to global for bridge callback
context.JK.HandleNetworkTestTimeout = networkTestTimeout; // pin to global for bridge callback
return this;
}
})(window, jQuery);

View File

@ -9,6 +9,7 @@
var VOICE_CHAT = context.JK.VOICE_CHAT;
var self = null;
var $step = null;
var logger = context.JK.logger;
var rest = context.JK.Rest();
var $watchVideoInput = null;
var $watchVideoOutput = null;

View File

@ -0,0 +1,121 @@
(function (context, $) {
"use strict";
context.JK = context.JK || {};
context.JK.Wizard = function (app) {
var $dialog = null;
var $templateButtons = null;
var $wizardSteps = null;
var STEPS = null;
var step = null;
var $btnNext = null;
var $btnBack = null;
var $btnClose = null;
var $btnCancel = null;
var $currentWizardStep = null;
function beforeHideStep() {
if(!previousStep) {return}
var stepInfo = STEPS[previousStep];
if (!stepInfo) {
throw "unknown step: " + previousStep;
}
if(stepInfo.beforeHide) {
stepInfo.beforeHide.call(stepInfo);
}
}
function beforeShowStep($step) {
var stepInfo = STEPS[step];
if (!stepInfo) {
throw "unknown step: " + step;
}
stepInfo.beforeShow.call(stepInfo);
}
function moveToStep() {
var $nextWizardStep = $wizardSteps.filter($('[layout-wizard-step=' + step + ']'));
beforeHideStep();
$wizardSteps.hide();
$currentWizardStep = $nextWizardStep;
var $ftueSteps = $(context._.template($templateSteps.html(), {}, { variable: 'data' }));
var $activeStep = $ftueSteps.find('.ftue-stepnumber[data-step-number="' + step + '"]');
$activeStep.addClass('.active');
$activeStep.next().show(); // show the .ftue-step-title
$currentWizardStep.find('.ftuesteps').replaceWith($ftueSteps);
// update buttons
var $wizardButtonsContent = $(context._.template($templateButtons.html(), {}, {variable: 'data'}));
$btnBack = $wizardButtonsContent.find('.btn-back');
$btnNext = $wizardButtonsContent.find('.btn-next');
$btnClose = $wizardButtonsContent.find('.btn-close');
$btnCancel = $wizardButtonsContent.find('.btn-cancel');
// hide back button if 1st step or last step
if (step == 0 && step == TOTAL_STEPS - 1) {
$btnBack.hide();
}
// hide next button if not on last step
if (step == TOTAL_STEPS - 1) {
$btnNext.hide();
}
// hide close if on last step
if (step != TOTAL_STEPS - 1) {
$btnClose.hide();
}
// hide cancel if not on last step
if (step == TOTAL_STEPS - 1) {
$btnCancel.hide();
}
$btnNext.on('click', next);
$btnBack.on('click', back);
$btnClose.on('click', closeDialog);
$btnCancel.on('click', closeDialog);
$ftueButtons.empty();
$ftueButtons.append($wizardButtonsContent);
beforeShowStep($currentWizardStep);
$currentWizardStep.show();
}
function beforeShow(args) {
step = args.d1;
if (!step) step = 0;
step = parseInt(step);
moveToStep(null);
}
function initialize(_$dialog, _$wizardSteps, _STEPS) {
$dialog = _$dialog;
$wizardSteps = _$wizardSteps;
STEPS = _STEPS;
$templateButtons = $('#template-wizard-buttons');
}
this.initialize = initialize;
}
})(window, jQuery);

View File

@ -1005,6 +1005,16 @@
});
}
function getLatencyTester(options) {
return $.ajax({
type: "GET",
url: '/api/latency_testers',
dataType: "json",
contentType: 'application/json',
data: JSON.stringify(options)
});
}
function initialize() {
return self;
}
@ -1092,6 +1102,7 @@
this.createChatMessage = createChatMessage;
this.getChatMessages = getChatMessages;
this.createDiagnostic = createDiagnostic;
this.getLatencyTester = getLatencyTester;
return this;
};

View File

@ -1544,6 +1544,10 @@
'beforeDisconnect' : beforeDisconnect,
};
app.bindScreen('session', screenBindings);
// make sure no previous plays are still going on by accident
context.jamClient.SessionStopPlay();
context.jamClient.SessionRemoveAllPlayTracks();
};

View File

@ -686,6 +686,10 @@
}
}
context.JK.isNetworkError = function(failArgs) {
return false;
}
context.JK.clientType = function () {
if (context.jamClient) {
return context.jamClient.IsNativeClient() ? 'client' : 'browser';

View File

@ -90,7 +90,7 @@
}
.wizard-step-column:last-child {
padding-right:0;
//padding-right:0;
}
p:nth-of-type(1) {
@ -581,8 +581,21 @@
.test-direct-monitoring {
margin-top:40px;
display:inline-block;
text-decoration: none;
width:90px;
span {
&.paused {
.playing {
display:none;
}
}
&.playing {
.paused {
display:none;
}
}
.direct-monitoring-btn {
padding-left:5px;
font-size:16px;
}
@ -595,10 +608,77 @@
.wizard-step[layout-wizard-step="5"] {
.wizard-step-content .wizard-step-column {
&:nth-of-type(1) {
width:25%;
}
&:nth-of-type(2) {
width:50%;
}
&:nth-of-type(3) {
width:25%;
}
}
.summary {
margin-left:20px;
margin-top:22px;
}
a.start-network-test {
margin-top:20px;
}
.network-test-score {
height:24px;
padding:10px;
color:white;
font-size:20px;
background-color:#222;
&.good {
background-color: #72a43b;
}
&.acceptable {
background-color: #D6A800;
}
&.bad {
background-color: #7B0C00;
}
}
.network-test-text {
}
.network-test-results {
height: 248px ! important;
@include border_box_sizing;
&.testing {
.network-test-score {
font-size:16px;
}
.network-test-text {
background-image: url('/assets/shared/spinner.gif');
background-repeat:no-repeat;
background-position:center;
//width:128px;
height:128px;
}
}
}
}
.wizard-step[layout-wizard-step="6"] {
.wizard-step-content .wizard-step-column {
&:nth-of-type(1) {
width:50%;
}
&:nth-of-type(2) {
width:50%;
}
}
}
p {

View File

@ -7,7 +7,7 @@ class ApiLatencyTestersController < ApiController
def match
# some day we can find the best latency tester to test against, now there is only one.
@latency_tester = LatencyTester.first
@latency_tester = LatencyTester.select_latency_tester
respond_with_model(@latency_tester)
end

View File

@ -141,13 +141,13 @@
%li Select the instrument for each track.
.center
%a.button-orange.watch-video{href:'#'} WATCH VIDEO
.wizard-step-column
.wizard-step-column.no-selection-range
%h2 Unassigned Ports
.unassigned-channels
.wizard-step-column
.wizard-step-column.no-selection-range
%h2 Track Input Port(s)
.tracks
.wizard-step-column
.wizard-step-column.no-selection-range
%h2 Instrument
.instruments
@ -200,19 +200,74 @@
If you use your audio interface for recording, and use the direct monitoring feature for recording,
please note that you will need to remember to turn this feature off every time that you use the JamKazam service.
.center
%a.ftue-box.test-direct-monitoring
%img{src:'assets/content/icon_playbutton.png', width:20, height:20, align:'top'}
%span Play
%a.ftue-box.test-direct-monitoring.paused.no-selection-range
.playing
%img{src:'assets/content/icon_pausebutton.png', width:20, height:20, align:'top'}
%span.direct-monitoring-btn Pause
.paused
%img{src:'assets/content/icon_playbutton.png', width:20, height:20, align:'top'}
%span.direct-monitoring-btn Play
.wizard-step{ 'layout-wizard-step' => "5", 'dialog-title' => "Test Router & Network", 'dialog-purpose' => "TestRouterNetwork" }
.ftuesteps
.clearall
.help-text In this step, you will test your router and Internet connection to ensure that you can play in online sessions, and to see how many musicians can be in a session with you based on your internet connection.
.wizard-step-content
.wizard-step-column
%h2 Instructions
.ftue-box.instructions
Find the Direct Monitoring control on your audio interface.<br>
%ul
%li If a button, push it into its off position
%li If a knob, turn it so that 100% of audio is from your computer, and 0% is from the direct monitor
.center
%a.button-orange.watch-video{href:'#'} WATCH VIDEO
.wizard-step-column
.summary
%p Ensure that your computer is connected to your home router using an Ethernet cable rather than using Wi-Fi wireless access. If necessary, find or purchase a long Ethernet cable, up to 100 ft.
%p Then click on the Start Network Test button below.
.center
%a.button-orange.start-network-test{href:'#'} START NETWORK TEST
.wizard-step-column
%h2 Test Results
.network-test-results.ftue-box
.network-test-score
.network-test-text
.wizard-step{ 'layout-wizard-step' => "6", 'dialog-title' => "Success!", 'dialog-purpose' => "Success" }
.ftuesteps
.clearall
.wizard-step-content
.wizard-step-column
%p Congratulations! You are now ready to create, join, and play in online sessions with other JamKazam musicians!
%p Please feel free to watch any of the videos to the right for information on how to connect and play with other musicians, and how to get the most out of JamKazam. When you're ready to go, click the Close button.
%p Have fun and thanks for joining us!
%p — Team JamKazam
.wizard-step-column
%h2
Tutorial Videos
%ul
%li
%a Creating a Session
%li
%a Finding a Session
%li
%a Playing in a Session
%li
%a Connecting with Other Musicians
%li
%a Making and Sharing Recordings
%li
%a Broadcasting Your Sessions
%h2
Other Valuable Resource Links
%ul
%li
%a JamKazam Support Center
%li
%a JamKazam Community Forum
.ftue-buttons
%script{type: 'text/template', id: 'template-ftuesteps'}
@ -233,7 +288,7 @@
.ftue-step-title Success!
%script{type: 'text/template', id: 'template-ftue-buttons'}
%script{type: 'text/template', id: 'template-wizard-buttons'}
.ftue-buttons-holder
%a.button-grey.btn-cancel{href:'#', 'layout-action' => 'close'} CANCEL
%a.button-grey{href: '#'} HELP

View File

@ -260,7 +260,8 @@
// latency_tester does not want to be here
if(window.jamClient.getOperatingMode() == "server") {
window.location.href = "/latency_tester";
window.location = "/latency_tester";
return;
}
// Let's get things rolling...

View File

@ -0,0 +1,7 @@
require 'spec_helper'
describe ApiFeedsController do
render_views
end