From 1d168257d0bca830d3a9f41576c317df6276337d Mon Sep 17 00:00:00 2001 From: Jonathon Wilson Date: Sun, 27 Oct 2013 18:37:55 -0600 Subject: [PATCH 01/11] Visual work for new FTUE screen --- .../assets/stylesheets/client/ftue.css.scss | 119 ++++++++++++++++++ web/app/views/clients/_ftue.html.erb | 119 +++++++++++++++++- 2 files changed, 237 insertions(+), 1 deletion(-) diff --git a/web/app/assets/stylesheets/client/ftue.css.scss b/web/app/assets/stylesheets/client/ftue.css.scss index 9af975c1a..fe158c0b2 100644 --- a/web/app/assets/stylesheets/client/ftue.css.scss +++ b/web/app/assets/stylesheets/client/ftue.css.scss @@ -110,6 +110,125 @@ div.dialog.ftue { margin-top: 12px; } + p.intro { + margin-top:0px; + } + .ftue-new { + clear:both; + position:relative; + width:100%; + height: 54px; + margin-top: 12px; + select { + font-size: 15px; + padding: 3px; + } + .latency { + position: absolute; + top: 120px; + font-size: 12px; + .report { + color:#fff; + position: absolute; + top: 20px; + left: 0px; + width: 105px; + height: 50px; + background-color: #72a43b; + padding: 10px; + text-align: center; + .ms-label { + padding-top: 10px; + font-size: 34px; + font-family: Arial, sans-serif; + } + p { + margin-top: 4px; + } + } + .instructions { + color:#fff; + position: absolute; + top: 20px; + left: 125px; + width: 595px; + height: 36px; + padding: 10px; + padding-top: 24px; + background-color: #666; + } + } + .column { + position:absolute; + width: 220px; + height: 50px; + margin-right:8px; + } + .settings-2-device { + left:0px; + } + .settings-2-center { + left:50%; + margin-left: -110px; + .buttons { + margin-top: 14px; + a { + margin-right: 0px; + } + } + } + .settings-2-voice { + top: 0px; + right:0px; + } + .controls { + margin-top: 16px; + background-color: #222; + height: 48px; + width: 220px; + } + .ftue-vu-left { + position:relative; + top: 0px; + } + .ftue-vu-right { + position:relative; + top: 22px; + } + .ftue-fader { + position:relative; + top: 14px; + left: 8px; + } + .gain-label { + color: $ColorScreenPrimary; + position:absolute; + top: 76px; + right: 6px; + } + + .subcolumn { + position:absolute; + top: 60px; + font-size: 12px !important; + width: 68px; + height: 48px; + } + .subcolumn select { + width: 68px; + } + .subcolumn.first { + left:0px; + } + .subcolumn.second { + left:50%; + margin-left:-34px; + } + .subcolumn.third { + right:0px; + } + } + .asio-settings { clear:both; position:relative; diff --git a/web/app/views/clients/_ftue.html.erb b/web/app/views/clients/_ftue.html.erb index ddb4d244b..9c90073b4 100644 --- a/web/app/views/clients/_ftue.html.erb +++ b/web/app/views/clients/_ftue.html.erb @@ -7,8 +7,125 @@
+ + +
+

+ Choose a device to capture and play your session audio. If + you’re not using a mic with this device, then also choose a + voice chat input to talk with others during sessions. Then play + and speak, and adjust the gain faders so that you hear both your + instrument and voice in your headphones at comfortable volumes. +

+ + +
+
+ Session Audio Device:
+ + +
+ +
+
+
GAIN
+
+
+
+
+ +
+ Frame
+ +
+
+ Buffer/In
+ +
+
+ Buffer/Out
+ +
+
+ + +
+ Voice Chat Input:
+ +
+
+
+
GAIN
+
+
+
+ + +
+ Latency:
+
+
9.83
+

milliseconds

+
+
+ Your audio speed is good. When done with settings, click Save Settings to continue. +
+
+
+ + + +
+ + -
+

Please identify which of the three types of audio gear below you are going to use with the JamKazam service, and click one to From 33eed269ed4a2381cb9ec38b5ca53ffd90af261b Mon Sep 17 00:00:00 2001 From: Jonathon Wilson Date: Thu, 31 Oct 2013 12:08:05 -0600 Subject: [PATCH 02/11] New FTUE panel controls mostly working. --- web/app/assets/javascripts/ftue.js | 234 +++++++++++++++++- web/app/assets/javascripts/jamkazam.js | 2 + .../assets/stylesheets/client/ftue.css.scss | 30 ++- web/app/views/clients/_ftue.html.erb | 37 +-- 4 files changed, 280 insertions(+), 23 deletions(-) diff --git a/web/app/assets/javascripts/ftue.js b/web/app/assets/javascripts/ftue.js index 9bb2253b2..936e5e348 100644 --- a/web/app/assets/javascripts/ftue.js +++ b/web/app/assets/javascripts/ftue.js @@ -25,6 +25,8 @@ }; var faderMap = { + 'ftue-2-audio-input-fader': jamClient.FTUESetInputVolume, + 'ftue-2-voice-input-fader': jamClient.FTUESetOutputVolume, 'ftue-audio-input-fader': jamClient.FTUESetInputVolume, 'ftue-voice-input-fader': jamClient.FTUESetChatInputVolume, 'ftue-audio-output-fader': jamClient.FTUESetOutputVolume @@ -44,6 +46,10 @@ function beforeShow(data) { var vuMeters = [ + '#ftue-2-audio-input-vu-left', + '#ftue-2-audio-input-vu-right', + '#ftue-2-voice-input-vu-left', + '#ftue-2-voice-input-vu-right', '#ftue-audio-input-vu-left', '#ftue-audio-input-vu-right', '#ftue-voice-input-vu-left', @@ -80,6 +86,8 @@ // Always reset the driver select box to "Choose..." which forces everything // to sync properly when the user reselects their driver of choice. // VRFS-375 and VRFS-561 + $('[layout-wizard="ftue"] [layout-wizard-step="0"] .settings-2-device select').val(""); + $('[layout-wizard="ftue"] [layout-wizard-step="0"] .settings-2-voice select').val(""); $('[layout-wizard="ftue"] [layout-wizard-step="2"] .asio-settings .settings-driver select').val(""); } @@ -317,6 +325,14 @@ $('#asio-framesize').on('change', setAsioFrameSize); $('#asio-input-latency').on('change', setAsioInputLatency); $('#asio-output-latency').on('change', setAsioOutputLatency); + // New FTUE events + $('.ftue-new .settings-2-device select').on('change', newFtueAudioDeviceChanged); + $('.ftue-new .settings-2-voice select').on('change', newFtueAudioDeviceChanged); + $('#btn-ftue-2-asio-resync').on('click', newFtueAsioResync); + $('#btn-ftue-2-asio-control-panel').on('click', openASIOControlPanel); + $('#ftue-2-asio-framesize').on('change', newFtueSetAsioFrameSize); + $('#ftue-2-asio-input-latency').on('change', newFtueSetAsioInputLatency); + $('#ftue-2-asio-output-latency').on('change', newFtueSetAsioOutputLatency); } /** @@ -368,7 +384,6 @@ * Load available drivers and populate the driver select box. */ function loadAudioDrivers() { - var drivers = jamClient.FTUEGetDevices(); var driverOptionFunc = function(driverKey, index, list) { @@ -377,11 +392,217 @@ }; var optionsHtml = ''; - var $select = $('[layout-wizard-step="2"] .settings-driver select'); - $select.empty(); + var selectors = [ + '[layout-wizard-step="0"] .settings-2-device select', + '[layout-wizard-step="0"] .settings-2-voice select', + '[layout-wizard-step="2"] .settings-driver select' + ]; var sortedDeviceKeys = context._.keys(drivers).sort(); context._.each(sortedDeviceKeys, driverOptionFunc); - $select.html(optionsHtml); + $.each(selectors, function(index, selector) { + var $select = $(selector); + $select.empty(); + $select.html(optionsHtml); + }); + } + + // Handler for when the audio device is changed in the new FTUE screen + // This works differently from the old FTUE. There is no input/output selection, + // as soon as the user chooses a driver, we auto-assign inputs and outputs. + // We also call jamClient.FTUEGetExpectedLatency, which returns a structure like: + // { latency: 11.1875, latencyknown: true, latencyvar: 1} + function newFtueAudioDeviceChanged(evt) { + var $select = $(evt.currentTarget); + + var $audioSelect = $('.ftue-new .settings-2-device select'); + var $voiceSelect = $('.ftue-new .settings-2-voice select'); + var audioDriverId = $audioSelect.val(); + var voiceDriverId = $voiceSelect.val(); + jamClient.FTUESetMusicDevice(audioDriverId); + jamClient.FTUESetChatInput(voiceDriverId); + if (voiceDriverId) { // Let the back end know whether a voice device is selected + jamClient.TrackSetChatEnable(true); + } else { + jamClient.TrackSetChatEnable(false); + } + if (!audioDriverId) { + // reset back to 'Choose...' + newFtueEnableControls(false); + return; + } + var musicInputs = jamClient.FTUEGetMusicInputs(); + var musicOutputs = jamClient.FTUEGetMusicOutputs(); + + // set the music input to the first available input, + // and output to the first available output + var kin = null, kout = null, k = null; + // TODO FIXME - this jamClient call returns a dictionary. + // It's difficult to know what to auto-choose. + // For example, with my built-in audio, the keys I get back are + // digital in, line in, mic in and stereo mix. Which should we pick for them? + for (k in musicInputs) { + kin = k; + break; + } + for (k in musicOutputs) { + kout = k; + break; + } + var result; + if (kin && kout) { + jamClient.FTUESetMusicInput(kin); + jamClient.FTUESetMusicOutput(kout); + } else { + // TODO FIXME - how to handle a driver selection where we are unable to + // autoset both inputs and outputs? (I'd think this could happen if either + // the input or output side returned no values) + context.alert("TODO - handle 'unable to set both inputs/outputs' case"); + return; + } + + newFtueEnableControls(true); + newFtueOsSpecificSettings(); + setLevels(0); + newFtueUpdateLatencyView('loading'); + jamClient.FTUESave(false); + setVuCallbacks(); + + var latency = jamClient.FTUEGetExpectedLatency(); + newFtueUpdateLatencyView(latency); + + } + + function newFtueSave(persist) { + newFtueUpdateLatencyView('loading'); + jamClient.FTUESave(persist); + var latency = jamClient.FTUEGetExpectedLatency(); + newFtueUpdateLatencyView(latency); + } + + function newFtueAsioResync(evt) { + // In theory, we should be calling the following, but it causes + // us to not have both inputs/outputs loaded, and simply calling + // FTUE Save appears to resync things. + //jamClient.FTUERefreshDevices(); + newFtueSave(false); + } + + function newFtueSetAsioFrameSize(evt) { + var val = parseFloat($(evt.currentTarget).val(),10); + if (isNaN(val)) { + return; + } + logger.debug("Calling FTUESetFrameSize(" + val + ")"); + jamClient.FTUESetFrameSize(val); + newFtueSave(false); + } + function newFtueSetAsioInputLatency(evt) { + var val = parseInt($(evt.currentTarget).val(),10); + if (isNaN(val)) { + return; + } + logger.debug("Calling FTUESetInputLatency(" + val + ")"); + jamClient.FTUESetInputLatency(val); + newFtueSave(false); + } + function newFtueSetAsioOutputLatency(evt) { + var val = parseInt($(evt.currentTarget).val(),10); + if (isNaN(val)) { + return; + } + logger.debug("Calling FTUESetOutputLatency(" + val + ")"); + jamClient.FTUESetOutputLatency(val); + newFtueSave(false); + } + + // Enable or Disable the frame/buffer controls in the new FTUE screen + function newFtueEnableControls(enable) { + var $frame = $('#ftue-2-asio-framesize'); + var $bin = $('#ftue-2-asio-input-latency'); + var $bout = $('#ftue-2-asio-output-latency'); + if (enable) { + $frame.removeAttr("disabled"); + $bin.removeAttr("disabled"); + $bout.removeAttr("disabled"); + } else { + $frame.attr("disabled", "disabled"); + $bin.attr("disabled", "disabled"); + $bout.attr("disabled", "disabled"); + } + } + + // Based on OS and Audio Hardware, set Frame/Buffer settings appropriately + // and show/hide the ASIO button. + function newFtueOsSpecificSettings() { + var $frame = $('#ftue-2-asio-framesize'); + var $bin = $('#ftue-2-asio-input-latency'); + var $bout = $('#ftue-2-asio-output-latency'); + var $asioBtn = $('#btn-ftue-2-asio-control-panel'); + if (jamClient.GetOSAsString() === "Win32") { + if (jamClient.FTUEHasControlPanel()) { + // Win32 + ControlPanel = ASIO + // frame=2.5, buffers=0 + $asioBtn.show(); + $frame.val(2.5); + $bin.val(0); + $bout.val(0); + } else { + // Win32, no ControlPanel = WDM/Kernel Streaming + // frame=10, buffers=0 + $asioBtn.hide(); + $frame.val(10); + // TODO FIXME - the old FTUE set the buffers to 1 for WDM/Kernel streaming + // The new FTUE spec says to use 0, as I've done here... + $bin.val(0); + $bout.val(0); + } + } else { // Assuming Mac. TODO: Linux check here + // frame=2.5, buffers=0 + $asioBtn.hide(); + $frame.val(2.5); + $bin.val(0); + $bout.val(0); + } + + } + + // Given a latency structure, update the view. + function newFtueUpdateLatencyView(latency) { + var $report = $('.ftue-new .latency .report'); + var $instructions = $('.ftue-new .latency .instructions'); + var latencyClass = "neutral"; + var latencyValue = "N/A"; + if (latency && latency.latencyknown) { + latencyValue = latency.latency; + // Round latency to two decimal places. + latencyValue = Math.round(latencyValue * 100) / 100; + if (latency.latency <= 10) { + latencyClass = "good"; + } else if (latency.latency <= 20) { + latencyClass = "acceptable"; + } else { + latencyClass = "bad"; + } + } else { + // TODO FIXME - handle unknown expected latency + // latency unknown... + } + + $('.ms-label', $report).html(latencyValue); + $('p', $report).html('milliseconds'); + + $report.removeClass('good acceptable bad'); + $report.addClass(latencyClass); + + var instructionClasses = ['neutral', 'good', 'acceptable', 'bad', 'start', 'loading']; + $.each(instructionClasses, function(idx, val) { + $('p.' + val, $instructions).hide(); + }); + if (latency === 'loading') { + $('p.loading', $instructions).show(); + } else { + $('p.' + latencyClass, $instructions).show(); + } } function audioDriverChanged(evt) { @@ -459,6 +680,7 @@ var dialogBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow, 'afterHide': afterHide }; app.bindDialog('ftue', dialogBindings); + app.registerWizardStepFunction("0", settingsInit); app.registerWizardStepFunction("2", settingsInit); app.registerWizardStepFunction("4", testLatency); app.registerWizardStepFunction("6", testComplete); @@ -484,6 +706,8 @@ }; context.JK.ftueAudioInputVUCallback = function(dbValue) { + context.JK.ftueVUCallback(dbValue, '#ftue-2-audio-input-vu-left'); + context.JK.ftueVUCallback(dbValue, '#ftue-2-audio-input-vu-right'); context.JK.ftueVUCallback(dbValue, '#ftue-audio-input-vu-left'); context.JK.ftueVUCallback(dbValue, '#ftue-audio-input-vu-right'); }; @@ -492,6 +716,8 @@ context.JK.ftueVUCallback(dbValue, '#ftue-audio-output-vu-right'); }; context.JK.ftueChatInputVUCallback = function(dbValue) { + context.JK.ftueVUCallback(dbValue, '#ftue-2-voice-input-vu-left'); + context.JK.ftueVUCallback(dbValue, '#ftue-2-voice-input-vu-right'); context.JK.ftueVUCallback(dbValue, '#ftue-voice-input-vu-left'); context.JK.ftueVUCallback(dbValue, '#ftue-voice-input-vu-right'); }; diff --git a/web/app/assets/javascripts/jamkazam.js b/web/app/assets/javascripts/jamkazam.js index 6fade3525..5448088e7 100644 --- a/web/app/assets/javascripts/jamkazam.js +++ b/web/app/assets/javascripts/jamkazam.js @@ -259,6 +259,8 @@ if (!(context.jamClient.FTUEGetStatus())) { app.layout.showDialog('ftue'); } + // TODO FIXME REMOVE ME - Testing Only + app.layout.showDialog('ftue'); } this.unloadFunction = function() { diff --git a/web/app/assets/stylesheets/client/ftue.css.scss b/web/app/assets/stylesheets/client/ftue.css.scss index fe158c0b2..0dfbdc4e8 100644 --- a/web/app/assets/stylesheets/client/ftue.css.scss +++ b/web/app/assets/stylesheets/client/ftue.css.scss @@ -146,17 +146,43 @@ div.dialog.ftue { margin-top: 4px; } } + .report.neutral, .report.start { + background-color: #666; + } + .report.good { + background-color: #72a43b; + } + .report.acceptable { + background-color: #D6A800; + } + .report.bad { + background-color: #7B0C00; + } .instructions { color:#fff; position: absolute; top: 20px; left: 125px; width: 595px; - height: 36px; + height: 50px; padding: 10px; - padding-top: 24px; background-color: #666; } + .instructions p.start, .instructions p.neutral { + padding-top: 4px; + } + .instructions p.good { + padding-top: 4px; + } + .instructions p.acceptable { + margin-top: -6px; + } + .instructions p.bad { + margin-top: -6px; + } + .instructions p a { + font-weight: bold; + } } .column { position:absolute; diff --git a/web/app/views/clients/_ftue.html.erb b/web/app/views/clients/_ftue.html.erb index 9c90073b4..78a0bfe18 100644 --- a/web/app/views/clients/_ftue.html.erb +++ b/web/app/views/clients/_ftue.html.erb @@ -31,25 +31,23 @@

- -
-
+
+
GAIN
-
+
Frame
- @@ -58,7 +56,7 @@
Buffer/In
- @@ -74,7 +72,7 @@
Buffer/Out
- @@ -95,22 +93,27 @@ Voice Chat Input:
-
-
+
+
GAIN
-
+
Latency:
-
-
9.83
-

milliseconds

+
+
+

- Your audio speed is good. When done with settings, click Save Settings to continue. +

Choose an audio device to continue...

+ + + + +
From 6198bccf3bf174bd8d2b17c6a74735a4aede179b Mon Sep 17 00:00:00 2001 From: Seth Call Date: Tue, 5 Nov 2013 03:00:43 +0000 Subject: [PATCH 03/11] * refactoring relavent tests to use create_session/find_session utility --- web/app/assets/javascripts/sessionList.js | 2 +- web/app/views/clients/_findSession.html.erb | 2 +- web/spec/features/find_sessions_spec.rb | 29 +-------- web/spec/features/music_sessions_spec.rb | 22 ++----- web/spec/support/utilities.rb | 68 ++++++++++++++++++++- 5 files changed, 74 insertions(+), 49 deletions(-) diff --git a/web/app/assets/javascripts/sessionList.js b/web/app/assets/javascripts/sessionList.js index 49af23e00..af030147e 100644 --- a/web/app/assets/javascripts/sessionList.js +++ b/web/app/assets/javascripts/sessionList.js @@ -137,7 +137,7 @@ // wire up the Join Link to the T&Cs dialog var $parentRow = $('tr[id=' + session.id + ']', tbGroup); - $('#join-link', $parentRow).click(function(evt) { + $('.join-link', $parentRow).click(function(evt) { joinClick(session.id); }); } diff --git a/web/app/views/clients/_findSession.html.erb b/web/app/views/clients/_findSession.html.erb index 562dc7f06..af1d851c6 100644 --- a/web/app/views/clients/_findSession.html.erb +++ b/web/app/views/clients/_findSession.html.erb @@ -72,7 +72,7 @@ - + <%= image_tag "content/icon_join.png", :size => "19x22" %> diff --git a/web/spec/features/find_sessions_spec.rb b/web/spec/features/find_sessions_spec.rb index 8a1f618b2..680add9fc 100644 --- a/web/spec/features/find_sessions_spec.rb +++ b/web/spec/features/find_sessions_spec.rb @@ -31,33 +31,6 @@ describe "Find Session", :js => true, :type => :feature, :capybara_feature => tr it "finds another public session", :slow => true do - - @unique_session_desc = 'Description found easily' - - # create session in one client - in_client(:one) do - page.driver.resize(1500, 600) # crude hack - sign_in_poltergeist user - visit "/client#/createSession" - - within('#create-session-form') do - fill_in('description', :with => @unique_session_desc) - select('Rock', :from => 'genres') - find('div.intellectual-property ins').trigger(:click) - click_link('btn-create-session') # fails if page width is low - end - - # verify that the in-session page is showing - expect(page).to have_selector('h2', text: 'my tracks') - end - - # find session in second client - in_client(:two) do - sign_in_poltergeist finder - visit "/client#/findSession" - - # verify the session description is seen by second client - expect(page).to have_text(@unique_session_desc) - end + create_join_session(user, [finder]) end end diff --git a/web/spec/features/music_sessions_spec.rb b/web/spec/features/music_sessions_spec.rb index 149d22802..d09112208 100644 --- a/web/spec/features/music_sessions_spec.rb +++ b/web/spec/features/music_sessions_spec.rb @@ -2,20 +2,6 @@ require 'spec_helper' describe "Music Session", :js => true, :type => :feature, :capybara_feature => true, :slow => true do - def create_music_session - uu = FactoryGirl.create(:user) - sign_in_poltergeist uu - visit "/client#/createSession" - sleep 3 - within('#create-session-form') do - fill_in('description', :with => 'foobar') - select('Ambient', :from => 'genres') - find('div.intellectual-property ins').trigger(:click) - click_link('btn-create-session') - end - uu - end - def leave_music_session_sleep_delay # add a buffer to ensure WSG has enough time to expire sleep_dur = (Rails.application.config.websocket_gateway_connect_time_stale + @@ -42,7 +28,7 @@ describe "Music Session", :js => true, :type => :feature, :capybara_feature => t before(:each) do UserMailer.deliveries.clear pending - @user1 = create_music_session + @user1, session_description = create_session end describe "cleanly leaves music session" do @@ -77,14 +63,14 @@ describe "Music Session", :js => true, :type => :feature, :capybara_feature => t before(:each) do UserMailer.deliveries.clear in_client(:user1_music_session) do - @user1 = create_music_session + @user1, session_description = create_session end end describe "cleanly leaves" do it "should update music session and user session history" do in_client(:user2_music_session) do - @user2 = create_music_session + @user2, session_description = create_session sleep 5 should have_link('session-leave') click_link('session-leave') @@ -100,7 +86,7 @@ describe "Music Session", :js => true, :type => :feature, :capybara_feature => t describe "abruptly leaves" do it "should update music session and user session history" do in_client(:user2_music_session) do - @user2 = create_music_session + @user2, session_description = create_session sleep 5 should have_link('session-leave') page.evaluate_script("JK.JamServer.close(true)") diff --git a/web/spec/support/utilities.rb b/web/spec/support/utilities.rb index 16cf3cb5e..7ad7153dc 100644 --- a/web/spec/support/utilities.rb +++ b/web/spec/support/utilities.rb @@ -6,7 +6,7 @@ end def in_client(name) # to assist multiple-client RSpec/Capybara testing - Capybara.session_name = name + Capybara.session_name = name.class == JamRuby::User ? name.id : name yield end @@ -70,4 +70,70 @@ end def wait_until_curtain_gone should have_no_selector('.curtain') +end + +def determine_test_name(metadata, test_name_buffer = '') + description = metadata[:description_args] + if description.kind_of?(Array) + description = description[0] + end + if metadata.has_key? :example_group + return determine_test_name(metadata[:example_group], "#{description} #{test_name_buffer}") + else + return "#{description} #{test_name_buffer}" + end +end + +# takes, or creates, a unique session description which is returned for subsequent calls to join_session to use +# in finding this session) +def create_session(creator = FactoryGirl.create(:user), unique_session_desc = "create_join_session #{SecureRandom.urlsafe_base64}") + + # create session in one client + in_client(creator) do + page.driver.resize(1500, 600) # makes sure all the elements are visible + sign_in_poltergeist creator + wait_until_curtain_gone + visit "/client#/createSession" + expect(page).to have_selector('h2', text: 'session info') + + within('#create-session-form') do + fill_in('description', :with => unique_session_desc) + select('Rock', :from => 'genres') + find('div.intellectual-property ins').trigger(:click) + find('#btn-create-session').trigger(:click) # fails if page width is low + end + + # verify that the in-session page is showing + expect(page).to have_selector('h2', text: 'my tracks') + end + + return creator, unique_session_desc + +end + + +# this code assumes that there are no music sessions in the database. it should fail on the +# find('.join-link') call if > 1 session exists because capybara will complain of multile matches +def join_session(joiner, unique_session_desc) + + in_client(joiner) do + sign_in_poltergeist joiner + wait_until_curtain_gone + visit "/client#/findSession" + + # verify the session description is seen by second client + expect(page).to have_text(unique_session_desc) + find('.join-link').trigger(:click) + find('#btn-accept-terms').trigger(:click) + expect(page).to have_selector('h2', text: 'my tracks') + end +end + +def create_join_session(creator, joiners=[]) + creator, unique_session_desc = create_session(creator) + + # find session in second client + joiners.each do |joiner| + join_session(joiner, unique_session_desc) + end end \ No newline at end of file From 443593a9ee654bac6f2b9e55492966d919dd0f38 Mon Sep 17 00:00:00 2001 From: Jonathon Wilson Date: Mon, 4 Nov 2013 20:26:24 -0700 Subject: [PATCH 04/11] New FTUE. Cancel and Save buttons working with notification if you haven't selected an audio device. --- web/app/assets/javascripts/ftue.js | 20 ++++++++++++++++++++ web/app/assets/javascripts/layout.js | 13 ++++++++----- web/app/views/clients/_ftue.html.erb | 4 ++-- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/web/app/assets/javascripts/ftue.js b/web/app/assets/javascripts/ftue.js index 936e5e348..d58be61da 100644 --- a/web/app/assets/javascripts/ftue.js +++ b/web/app/assets/javascripts/ftue.js @@ -333,6 +333,7 @@ $('#ftue-2-asio-framesize').on('change', newFtueSetAsioFrameSize); $('#ftue-2-asio-input-latency').on('change', newFtueSetAsioInputLatency); $('#ftue-2-asio-output-latency').on('change', newFtueSetAsioOutputLatency); + $('#btn-ftue-2-save').on('click', newFtueSaveSettingsHandler); } /** @@ -406,6 +407,25 @@ }); } + /** + * Handler for the new FTUE save button. + */ + function newFtueSaveSettingsHandler(evt) { + evt.preventDefault(); + var selectedAudioDevice = $('.ftue-new .settings-2-device select').val(); + logger.dbg('newFtueSave. selectedAudioDevice:' + selectedAudioDevice); + if (!(selectedAudioDevice)) { + app.notify({ + title: "Please select an audio device", + text: "Please choose a usable audio device, or select cancel." + }); + return false; + } + jamClient.FTUESave(true); + app.layout.closeDialog('ftue'); + return false; + } + // Handler for when the audio device is changed in the new FTUE screen // This works differently from the old FTUE. There is no input/output selection, // as soon as the user chooses a driver, we auto-assign inputs and outputs. diff --git a/web/app/assets/javascripts/layout.js b/web/app/assets/javascripts/layout.js index 512fe2484..e210e3477 100644 --- a/web/app/assets/javascripts/layout.js +++ b/web/app/assets/javascripts/layout.js @@ -303,7 +303,9 @@ padding: '0px' }; $('[layout]').css(layoutStyle); - $('[layout="notify"]').css({"z-index": "9", "padding": "20px"}); + // JW: Setting z-index of notify to 1001, so it will appear above the dialog overlay. + // This allows dialogs to use the notification. + $('[layout="notify"]').css({"z-index": "1001", "padding": "20px"}); $('[layout="panel"]').css({position: 'relative'}); $('[layout-panel="expanded"] [layout-panel="header"]').css({ margin: "0px", @@ -595,10 +597,11 @@ } notifyQueue.push({message: message, descriptor: descriptor}); - $notify.slideDown(2000) - .delay(2000) + // JW - speeding up the in/out parts of notify. Extending non-moving time. + $notify.slideDown(250) + .delay(4000) .slideUp({ - duration: 2000, + duration: 400, queue: true, complete: function() { notifyDetails = notifyQueue.shift(); @@ -614,7 +617,7 @@ } } }); - } + }; function setNotificationInfo(message, descriptor) { var $notify = $('[layout="notify"]'); diff --git a/web/app/views/clients/_ftue.html.erb b/web/app/views/clients/_ftue.html.erb index 78a0bfe18..5417766aa 100644 --- a/web/app/views/clients/_ftue.html.erb +++ b/web/app/views/clients/_ftue.html.erb @@ -119,9 +119,9 @@
From 1aeb358d2964b3916ba4496fd2b4aaa4bd005a25 Mon Sep 17 00:00:00 2001 From: Jonathon Wilson Date: Tue, 5 Nov 2013 15:44:40 -0700 Subject: [PATCH 05/11] Add proper showing of FTUE on Create/Join session if id hasn't been done. --- web/app/assets/javascripts/createSession.js | 9 ++++++++- web/app/assets/javascripts/ftue.js | 9 +++++++++ web/app/assets/javascripts/jamkazam.js | 9 +++------ web/app/assets/javascripts/layout.js | 10 +++++++++- web/app/assets/javascripts/sessionList.js | 13 ++++++++++--- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/web/app/assets/javascripts/createSession.js b/web/app/assets/javascripts/createSession.js index fe19afe00..9f697366f 100644 --- a/web/app/assets/javascripts/createSession.js +++ b/web/app/assets/javascripts/createSession.js @@ -178,6 +178,13 @@ function submitForm(evt) { evt.preventDefault(); + // If user hasn't completed FTUE - do so now. + if (!(context.jamClient.FTUEGetStatus())) { + app.afterFtue = function() { submitForm(evt); }; + app.layout.showDialog('ftue'); + return; + } + var isValid = validateForm(); if (!isValid) { // app.notify({ @@ -435,4 +442,4 @@ return this; }; - })(window,jQuery); + })(window,jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/ftue.js b/web/app/assets/javascripts/ftue.js index d58be61da..6ae1ec829 100644 --- a/web/app/assets/javascripts/ftue.js +++ b/web/app/assets/javascripts/ftue.js @@ -422,7 +422,16 @@ return false; } jamClient.FTUESave(true); + jamClient.FTUESetStatus(true); // No FTUE wizard next time + rest.userCertifiedGear({success:true}); app.layout.closeDialog('ftue'); + if (app.afterFtue) { + // If there's a function to invoke, invoke it. + logger.dbg("afterFTUE function:"); + logger.dbg(app.afterFtue); + app.afterFtue(); + app.afterFtue = null; + } return false; } diff --git a/web/app/assets/javascripts/jamkazam.js b/web/app/assets/javascripts/jamkazam.js index 5448088e7..61da06700 100644 --- a/web/app/assets/javascripts/jamkazam.js +++ b/web/app/assets/javascripts/jamkazam.js @@ -255,12 +255,6 @@ } logger.debug("Changing screen to " + url); context.location = url; - - if (!(context.jamClient.FTUEGetStatus())) { - app.layout.showDialog('ftue'); - } - // TODO FIXME REMOVE ME - Testing Only - app.layout.showDialog('ftue'); } this.unloadFunction = function() { @@ -296,6 +290,9 @@ } }; + // Holder for a function to invoke upon successfully completing the FTUE. + // See createSession.submitForm as an example. + this.afterFtue = null; // enable temporary suspension of heartbeat for fine-grained control this.heartbeatActive = true; diff --git a/web/app/assets/javascripts/layout.js b/web/app/assets/javascripts/layout.js index e210e3477..6958bf426 100644 --- a/web/app/assets/javascripts/layout.js +++ b/web/app/assets/javascripts/layout.js @@ -383,12 +383,20 @@ function linkClicked(evt) { evt.preventDefault(); + var $currentTarget = $(evt.currentTarget); // allow links to be disabled - if($(evt.currentTarget).hasClass("disabled") ) { + if($currentTarget.hasClass("disabled") ) { return; } + // If link requires FTUE, show that first. + if ($currentTarget.hasClass("requires-ftue")) { + if (!(context.jamClient.FTUEGetStatus())) { + app.layout.showDialog('ftue'); + } + } + var destination = $(evt.currentTarget).attr('layout-link'); var destinationType = $('[layout-id="' + destination + '"]').attr("layout"); if (destinationType === "screen") { diff --git a/web/app/assets/javascripts/sessionList.js b/web/app/assets/javascripts/sessionList.js index 49af23e00..8aaa83249 100644 --- a/web/app/assets/javascripts/sessionList.js +++ b/web/app/assets/javascripts/sessionList.js @@ -138,7 +138,14 @@ var $parentRow = $('tr[id=' + session.id + ']', tbGroup); $('#join-link', $parentRow).click(function(evt) { - joinClick(session.id); + // If no FTUE, show that first. + if (!(context.jamClient.FTUEGetStatus())) { + app.afterFtue = function() { joinClick(session.id); }; + app.layout.showDialog('ftue'); + return; + } else { + joinClick(session.id); + } }); } } @@ -201,7 +208,7 @@ } function openAlert(sessionId) { - var alertDialog = new context.JK.AlertDialog(app, "YES", + var alertDialog = new context.JK.AlertDialog(app, "YES", "You must be approved to join this session. Would you like to send a request to join?", sessionId, onCreateJoinRequest); @@ -210,7 +217,7 @@ } function sessionNotJoinableAlert() { - var alertDialog = new context.JK.AlertDialog(app, "OK", + var alertDialog = new context.JK.AlertDialog(app, "OK", "This session is over or is no longer public and cannot be joined. Please click Refresh to update the session list.", null, function(evt) { From cfb6a6133f69777f9b1c474317a6922396608d82 Mon Sep 17 00:00:00 2001 From: Anthony Davis Date: Tue, 5 Nov 2013 20:03:43 -0600 Subject: [PATCH 06/11] adding optional 'fog' dependency 'unf' to suppress warnings --- admin/Gemfile | 1 + web/Gemfile | 1 + 2 files changed, 2 insertions(+) diff --git a/admin/Gemfile b/admin/Gemfile index 47096903d..f80ab1d01 100644 --- a/admin/Gemfile +++ b/admin/Gemfile @@ -41,6 +41,7 @@ gem 'rails3-jquery-autocomplete' gem 'activeadmin' gem "meta_search", '>= 1.1.0.pre' gem 'fog', "~> 1.3.1" +gem 'unf' #optional fog dependency gem 'country-select' gem 'aasm', '3.0.16' gem 'postgres-copy' diff --git a/web/Gemfile b/web/Gemfile index 4a4ae6449..ab19237e8 100644 --- a/web/Gemfile +++ b/web/Gemfile @@ -47,6 +47,7 @@ gem 'aws-sdk', '1.8.0' gem 'aasm', '3.0.16' gem 'carrierwave' gem 'fog' +gem 'unf' #optional fog dependency gem 'devise', '>= 1.1.2' #gem 'thin' # the presence of this gem on mac seems to prevent normal startup of rails. gem 'postgres-copy' From c6802c4e4091624c60f93d81d90f3d2c4f4679b3 Mon Sep 17 00:00:00 2001 From: Jonathon Wilson Date: Tue, 5 Nov 2013 19:50:32 -0700 Subject: [PATCH 07/11] New FTUE: Prevent save if bad or unknown latency. If unknown, link to old FTUE. --- web/app/assets/javascripts/ftue.js | 16 ++++++++++------ web/app/assets/javascripts/session.js | 4 +--- web/app/assets/stylesheets/client/ftue.css.scss | 6 +++++- web/app/views/clients/_ftue.html.erb | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/web/app/assets/javascripts/ftue.js b/web/app/assets/javascripts/ftue.js index 6ae1ec829..21414246b 100644 --- a/web/app/assets/javascripts/ftue.js +++ b/web/app/assets/javascripts/ftue.js @@ -412,8 +412,11 @@ */ function newFtueSaveSettingsHandler(evt) { evt.preventDefault(); + var $saveButton = $('#btn-ftue-2-save'); + if ($saveButton.hasClass('disabled')) { + return; + } var selectedAudioDevice = $('.ftue-new .settings-2-device select').val(); - logger.dbg('newFtueSave. selectedAudioDevice:' + selectedAudioDevice); if (!(selectedAudioDevice)) { app.notify({ title: "Please select an audio device", @@ -427,8 +430,6 @@ app.layout.closeDialog('ftue'); if (app.afterFtue) { // If there's a function to invoke, invoke it. - logger.dbg("afterFTUE function:"); - logger.dbg(app.afterFtue); app.afterFtue(); app.afterFtue = null; } @@ -485,7 +486,6 @@ // TODO FIXME - how to handle a driver selection where we are unable to // autoset both inputs and outputs? (I'd think this could happen if either // the input or output side returned no values) - context.alert("TODO - handle 'unable to set both inputs/outputs' case"); return; } @@ -601,20 +601,24 @@ var $instructions = $('.ftue-new .latency .instructions'); var latencyClass = "neutral"; var latencyValue = "N/A"; + var $saveButton = $('#btn-ftue-2-save'); if (latency && latency.latencyknown) { latencyValue = latency.latency; // Round latency to two decimal places. latencyValue = Math.round(latencyValue * 100) / 100; if (latency.latency <= 10) { latencyClass = "good"; + $saveButton.removeClass('disabled'); } else if (latency.latency <= 20) { latencyClass = "acceptable"; + $saveButton.removeClass('disabled'); } else { latencyClass = "bad"; + $saveButton.addClass('disabled'); } } else { - // TODO FIXME - handle unknown expected latency - // latency unknown... + latencyClass = "unknown"; + $saveButton.addClass('disabled'); } $('.ms-label', $report).html(latencyValue); diff --git a/web/app/assets/javascripts/session.js b/web/app/assets/javascripts/session.js index 3eaf1574e..278f733b8 100644 --- a/web/app/assets/javascripts/session.js +++ b/web/app/assets/javascripts/session.js @@ -621,8 +621,6 @@ $connection.addClass(connectionClass); } else if (eventName === 'add' || eventName === 'remove') { - //logger.dbg('non-vu event: ' + eventName + ',' + mixerId + ',' + value); - // TODO - _renderSession. Note I get streams of these in // sequence, so have Nat fix, or buffer/spam protect // Note - this is already handled from websocket events. @@ -632,7 +630,7 @@ } else { // Examples of other events // Add media file track: "add", "The_Abyss_4T", 0 - logger.dbg('non-vu event: ' + eventName + ',' + mixerId + ',' + value); + logger.debug('non-vu event: ' + eventName + ',' + mixerId + ',' + value); } } } diff --git a/web/app/assets/stylesheets/client/ftue.css.scss b/web/app/assets/stylesheets/client/ftue.css.scss index 0dfbdc4e8..02b4d1f27 100644 --- a/web/app/assets/stylesheets/client/ftue.css.scss +++ b/web/app/assets/stylesheets/client/ftue.css.scss @@ -146,7 +146,7 @@ div.dialog.ftue { margin-top: 4px; } } - .report.neutral, .report.start { + .report.neutral, .report.start, .report.unknown { background-color: #666; } .report.good { @@ -171,6 +171,10 @@ div.dialog.ftue { .instructions p.start, .instructions p.neutral { padding-top: 4px; } + .instructions p.unknown { + margin-top:0px; + padding-top: 4px; + } .instructions p.good { padding-top: 4px; } diff --git a/web/app/views/clients/_ftue.html.erb b/web/app/views/clients/_ftue.html.erb index 5417766aa..4084acb51 100644 --- a/web/app/views/clients/_ftue.html.erb +++ b/web/app/views/clients/_ftue.html.erb @@ -109,7 +109,7 @@

Choose an audio device to continue...

- + From e2c59d6543514135cfb48bb4e21a8e5024486204 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Mon, 4 Nov 2013 22:53:44 -0500 Subject: [PATCH 08/11] VRFS-687 fix issue with band profile social tab, added logging --- web/app/assets/javascripts/bandProfile.js | 4 ++-- web/app/assets/javascripts/jam_rest.js | 8 ++++++++ web/app/assets/javascripts/profile.js | 10 +++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/web/app/assets/javascripts/bandProfile.js b/web/app/assets/javascripts/bandProfile.js index d03ce3bdf..54d0130d1 100644 --- a/web/app/assets/javascripts/bandProfile.js +++ b/web/app/assets/javascripts/bandProfile.js @@ -245,7 +245,7 @@ $('#band-profile-biography').html(band.biography); } else { - + logger.debug("No band found with bandId = " + bandId); } } @@ -266,7 +266,7 @@ function bindSocial() { // FOLLOWERS - url = "/api/bands/" + bandId + "/followers"; + var url = "/api/bands/" + bandId + "/followers"; $.ajax({ type: "GET", dataType: "json", diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js index ea66bcbec..341e0d284 100644 --- a/web/app/assets/javascripts/jam_rest.js +++ b/web/app/assets/javascripts/jam_rest.js @@ -168,6 +168,14 @@ }); } + function getMusicianFollowers(userId) { + + } + + function getBandFollowers(bandId) { + + } + function getClientDownloads(options) { return $.ajax({ diff --git a/web/app/assets/javascripts/profile.js b/web/app/assets/javascripts/profile.js index fc69c53bc..17f07bff2 100644 --- a/web/app/assets/javascripts/profile.js +++ b/web/app/assets/javascripts/profile.js @@ -307,22 +307,22 @@ $('#profile-location').html(user.location); // stats - var text = user.friend_count > 1 || user.friend_count == 0 ? " Friends" : " Friend"; + var text = user.friend_count > 1 || user.friend_count === 0 ? " Friends" : " Friend"; $('#profile-friend-stats').html(user.friend_count + text); - text = user.follower_count > 1 || user.follower_count == 0 ? " Followers" : " Follower"; + text = user.follower_count > 1 || user.follower_count === 0 ? " Followers" : " Follower"; $('#profile-follower-stats').html(user.follower_count + text); - text = user.session_count > 1 || user.session_count == 0 ? " Sessions" : " Session"; + text = user.session_count > 1 || user.session_count === 0 ? " Sessions" : " Session"; $('#profile-session-stats').html(user.session_count + text); - text = user.recording_count > 1 || user.recording_count == 0 ? " Recordings" : " Recording"; + text = user.recording_count > 1 || user.recording_count === 0 ? " Recordings" : " Recording"; $('#profile-recording-stats').html(user.recording_count + text); $('#profile-biography').html(user.biography); } else { - + logger.debug("No user found with userId = " + userId); } } From 297bce049dec2da66f3d8d5d1d1de65cd21d6e00 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Tue, 5 Nov 2013 20:06:38 +0000 Subject: [PATCH 09/11] * working through all the various dependency issues of admin project --- admin/Gemfile | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/admin/Gemfile b/admin/Gemfile index f80ab1d01..923e75852 100644 --- a/admin/Gemfile +++ b/admin/Gemfile @@ -33,22 +33,24 @@ group :assets do end gem 'will_paginate', '3.0.3' gem 'bootstrap-will_paginate', '0.0.6' -gem 'carrierwave' +gem 'carrierwave', '0.9.0' gem 'uuidtools', '2.1.2' gem 'bcrypt-ruby', '3.0.1' gem 'jquery-rails', '2.3.0' # pinned because jquery-ui-rails was split from jquery-rails, but activeadmin doesn't support this gem yet gem 'rails3-jquery-autocomplete' -gem 'activeadmin' -gem "meta_search", '>= 1.1.0.pre' -gem 'fog', "~> 1.3.1" -gem 'unf' #optional fog dependency -gem 'country-select' +gem 'activeadmin', '0.6.2' +gem 'mime-types', '1.25' +gem "meta_search" #, '>= 1.1.0.pre' +gem 'fog', "~> 1.18.0" +gem 'unf', '0.1.3' #optional fog dependency +gem 'country-select', '1.1.1' gem 'aasm', '3.0.16' -gem 'postgres-copy' +gem 'postgres-copy', '0.6.0' gem 'aws-sdk' -gem 'bugsnag' +gem 'bugsnag' -gem 'eventmachine', '1.0.0' + +gem 'eventmachine', '1.0.3' gem 'amqp', '0.9.8' gem 'logging-rails', :require => 'logging/rails' @@ -57,8 +59,8 @@ gem 'ruby-protocol-buffers', '1.2.2' gem 'sendgrid', '1.1.0' -gem 'geokit-rails' -gem 'postgres_ext' +gem 'geokit-rails', '2.0.0' +gem 'postgres_ext', '1.0.0' group :libv8 do gem 'libv8', "~> 3.11.8" From e40b26d91953c0e545ac0e674fabacf81c102059 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Tue, 5 Nov 2013 22:14:30 -0500 Subject: [PATCH 10/11] VRFS-837 check for undefined session --- web/app/assets/javascripts/findSession.js | 30 +++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/web/app/assets/javascripts/findSession.js b/web/app/assets/javascripts/findSession.js index 832f298e6..bc063cc73 100644 --- a/web/app/assets/javascripts/findSession.js +++ b/web/app/assets/javascripts/findSession.js @@ -152,13 +152,15 @@ function containsInvitation(session) { var i, invitation = null; - if ("invitations" in session) { - // user has invitations for this session - for (i=0; i < session.invitations.length; i++) { - invitation = session.invitations[i]; - // session contains an invitation for this user - if (invitation.receiver_id == context.JK.currentUserId) { - return true; + if (session !== undefined) { + if ("invitations" in session) { + // user has invitations for this session + for (i=0; i < session.invitations.length; i++) { + invitation = session.invitations[i]; + // session contains an invitation for this user + if (invitation.receiver_id == context.JK.currentUserId) { + return true; + } } } } @@ -169,12 +171,14 @@ function containsFriend(session) { var i, participant = null; - if ("participants" in session) { - for (i=0; i < session.participants.length; i++) { - participant = session.participants[i]; - // this session participant is a friend - if (participant !== null && participant !== undefined && participant.user.is_friend) { - return true; + if (session !== undefined) { + if ("participants" in session) { + for (i=0; i < session.participants.length; i++) { + participant = session.participants[i]; + // this session participant is a friend + if (participant !== null && participant !== undefined && participant.user.is_friend) { + return true; + } } } } From 250933490b2f6b49d5ad0c6df2ad4f3096217127 Mon Sep 17 00:00:00 2001 From: Anthony Davis Date: Tue, 5 Nov 2013 22:21:12 -0600 Subject: [PATCH 11/11] removing 'unf' in admin Gemfile in case it's breaking the build --- admin/Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/Gemfile b/admin/Gemfile index f80ab1d01..df321ebed 100644 --- a/admin/Gemfile +++ b/admin/Gemfile @@ -41,7 +41,7 @@ gem 'rails3-jquery-autocomplete' gem 'activeadmin' gem "meta_search", '>= 1.1.0.pre' gem 'fog', "~> 1.3.1" -gem 'unf' #optional fog dependency +# gem 'unf' #optional fog dependency gem 'country-select' gem 'aasm', '3.0.16' gem 'postgres-copy'