From fcc7130536a64c46f7c4be06a9337d8255528f8e Mon Sep 17 00:00:00 2001 From: Seth Call Date: Thu, 22 May 2014 11:26:56 -0500 Subject: [PATCH] * wip --- ruby/lib/jam_ruby/models/latency_tester.rb | 4 + web/app/assets/javascripts/JamServer.js | 1 - web/app/assets/javascripts/fakeJamClient.js | 2 + .../assets/javascripts/gear/gear_wizard.js | 86 +------------ .../javascripts/gear/loopback_wizard.js | 15 +++ .../javascripts/gear/step_configure_tracks.js | 1 + .../gear/step_configure_voice_chat.js | 1 + .../gear/step_direct_monitoring.js | 72 +++++++++++ .../javascripts/gear/step_network_test.js | 80 +++++++++++- .../javascripts/gear/step_select_gear.js | 1 + web/app/assets/javascripts/gear/wizard.js | 121 ++++++++++++++++++ web/app/assets/javascripts/jam_rest.js | 11 ++ web/app/assets/javascripts/session.js | 4 + web/app/assets/javascripts/utils.js | 4 + .../stylesheets/client/gearWizard.css.scss | 86 ++++++++++++- .../api_latency_testers_controller.rb | 2 +- .../views/clients/gear/_gear_wizard.html.haml | 73 +++++++++-- web/app/views/clients/index.html.erb | 3 +- .../api_latency_tests_controller_spec.rb | 7 + 19 files changed, 474 insertions(+), 100 deletions(-) create mode 100644 web/app/assets/javascripts/gear/loopback_wizard.js create mode 100644 web/app/assets/javascripts/gear/wizard.js create mode 100644 web/spec/controllers/api_latency_tests_controller_spec.rb diff --git a/ruby/lib/jam_ruby/models/latency_tester.rb b/ruby/lib/jam_ruby/models/latency_tester.rb index 2962f3bc2..bebcc9cdf 100644 --- a/ruby/lib/jam_ruby/models/latency_tester.rb +++ b/ruby/lib/jam_ruby/models/latency_tester.rb @@ -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) diff --git a/web/app/assets/javascripts/JamServer.js b/web/app/assets/javascripts/JamServer.js index 748490320..c61b8b6fe 100644 --- a/web/app/assets/javascripts/JamServer.js +++ b/web/app/assets/javascripts/JamServer.js @@ -20,7 +20,6 @@ var channelId = null; var clientType = null; var mode = null; - var rest = context.JK.Rest(); // heartbeat var heartbeatInterval = null; diff --git a/web/app/assets/javascripts/fakeJamClient.js b/web/app/assets/javascripts/fakeJamClient.js index 4752d26aa..e07dcb406 100644 --- a/web/app/assets/javascripts/fakeJamClient.js +++ b/web/app/assets/javascripts/fakeJamClient.js @@ -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; diff --git a/web/app/assets/javascripts/gear/gear_wizard.js b/web/app/assets/javascripts/gear/gear_wizard.js index 09d1714ab..26ec35fe4 100644 --- a/web/app/assets/javascripts/gear/gear_wizard.js +++ b/web/app/assets/javascripts/gear/gear_wizard.js @@ -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]'))); diff --git a/web/app/assets/javascripts/gear/loopback_wizard.js b/web/app/assets/javascripts/gear/loopback_wizard.js new file mode 100644 index 000000000..4b3f48784 --- /dev/null +++ b/web/app/assets/javascripts/gear/loopback_wizard.js @@ -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); diff --git a/web/app/assets/javascripts/gear/step_configure_tracks.js b/web/app/assets/javascripts/gear/step_configure_tracks.js index 655f98596..a6ef48b70 100644 --- a/web/app/assets/javascripts/gear/step_configure_tracks.js +++ b/web/app/assets/javascripts/gear/step_configure_tracks.js @@ -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; diff --git a/web/app/assets/javascripts/gear/step_configure_voice_chat.js b/web/app/assets/javascripts/gear/step_configure_voice_chat.js index a967a0564..e50bb5850 100644 --- a/web/app/assets/javascripts/gear/step_configure_voice_chat.js +++ b/web/app/assets/javascripts/gear/step_configure_voice_chat.js @@ -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; diff --git a/web/app/assets/javascripts/gear/step_direct_monitoring.js b/web/app/assets/javascripts/gear/step_direct_monitoring.js index 80d8a83cb..c1cb4f514 100644 --- a/web/app/assets/javascripts/gear/step_direct_monitoring.js +++ b/web/app/assets/javascripts/gear/step_direct_monitoring.js @@ -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; diff --git a/web/app/assets/javascripts/gear/step_network_test.js b/web/app/assets/javascripts/gear/step_network_test.js index 91d05ba34..715e8b4e5 100644 --- a/web/app/assets/javascripts/gear/step_network_test.js +++ b/web/app/assets/javascripts/gear/step_network_test.js @@ -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); \ No newline at end of file diff --git a/web/app/assets/javascripts/gear/step_select_gear.js b/web/app/assets/javascripts/gear/step_select_gear.js index 1f8049e41..5f520db66 100644 --- a/web/app/assets/javascripts/gear/step_select_gear.js +++ b/web/app/assets/javascripts/gear/step_select_gear.js @@ -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; diff --git a/web/app/assets/javascripts/gear/wizard.js b/web/app/assets/javascripts/gear/wizard.js new file mode 100644 index 000000000..01cd910db --- /dev/null +++ b/web/app/assets/javascripts/gear/wizard.js @@ -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); \ No newline at end of file diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js index 8a092562f..859fc82b1 100644 --- a/web/app/assets/javascripts/jam_rest.js +++ b/web/app/assets/javascripts/jam_rest.js @@ -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; }; diff --git a/web/app/assets/javascripts/session.js b/web/app/assets/javascripts/session.js index 2fc9e00b1..20fae6390 100644 --- a/web/app/assets/javascripts/session.js +++ b/web/app/assets/javascripts/session.js @@ -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(); }; diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js index c4fc28ad3..57b0a5c74 100644 --- a/web/app/assets/javascripts/utils.js +++ b/web/app/assets/javascripts/utils.js @@ -686,6 +686,10 @@ } } + context.JK.isNetworkError = function(failArgs) { + return false; + } + context.JK.clientType = function () { if (context.jamClient) { return context.jamClient.IsNativeClient() ? 'client' : 'browser'; diff --git a/web/app/assets/stylesheets/client/gearWizard.css.scss b/web/app/assets/stylesheets/client/gearWizard.css.scss index 9574ee3de..1e4404b66 100644 --- a/web/app/assets/stylesheets/client/gearWizard.css.scss +++ b/web/app/assets/stylesheets/client/gearWizard.css.scss @@ -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 { diff --git a/web/app/controllers/api_latency_testers_controller.rb b/web/app/controllers/api_latency_testers_controller.rb index e9f98f68c..19b4293ac 100644 --- a/web/app/controllers/api_latency_testers_controller.rb +++ b/web/app/controllers/api_latency_testers_controller.rb @@ -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 diff --git a/web/app/views/clients/gear/_gear_wizard.html.haml b/web/app/views/clients/gear/_gear_wizard.html.haml index ca8afbd2b..63ccd5bfa 100644 --- a/web/app/views/clients/gear/_gear_wizard.html.haml +++ b/web/app/views/clients/gear/_gear_wizard.html.haml @@ -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.
+ %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 diff --git a/web/app/views/clients/index.html.erb b/web/app/views/clients/index.html.erb index 7dd8a344f..513d49d75 100644 --- a/web/app/views/clients/index.html.erb +++ b/web/app/views/clients/index.html.erb @@ -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... diff --git a/web/spec/controllers/api_latency_tests_controller_spec.rb b/web/spec/controllers/api_latency_tests_controller_spec.rb new file mode 100644 index 000000000..8ef24e6c2 --- /dev/null +++ b/web/spec/controllers/api_latency_tests_controller_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe ApiFeedsController do + render_views + + +end