diff --git a/app/assets/javascripts/ftue.js b/app/assets/javascripts/ftueAudioSelection.js similarity index 62% rename from app/assets/javascripts/ftue.js rename to app/assets/javascripts/ftueAudioSelection.js index 04b28b73e..011c97a8b 100644 --- a/app/assets/javascripts/ftue.js +++ b/app/assets/javascripts/ftueAudioSelection.js @@ -1,18 +1,17 @@ /** -* The First-Time User Experience (FTUE) Screen to be shown -* to users who have not set up their audio hardware yet. -* Corresponds to the route #/ftue3 +* FtueAudioSelectionScreen +* Javascript that goes with the screen where initial +* selection of the audio devices takes place. +* Corresponds to /#ftue2 */ (function(context,$) { "use strict"; context.JK = context.JK || {}; - context.JK.FTUEScreen = function(app) { + context.JK.FtueAudioSelectionScreen = function(app) { var logger = context.JK.logger; var jamClient = context.jamClient; - var playbackTestRunning = false; - var recordingTestRunning = false; function beforeShow(data) { loadDevices(); @@ -24,6 +23,7 @@ function loadDevices() { $('#choose-input-audio-device select').empty(); $('#choose-output-audio-device select').empty(); + $('#choose-input-voice-device select').empty(); var optionTemplate = $('#template_audio_device_item').html(); var devices = context.jamClient.GetASIODevices(); var inputOptions = []; @@ -60,6 +60,7 @@ } $('#choose-input-audio-device select').html(inputOptions.join('')); $('#choose-output-audio-device select').html(outputOptions.join('')); + $('#choose-input-voice-device select').html(inputOptions.join('')); } /** @@ -89,45 +90,6 @@ $('#latency-testing p').html("Done."); } - function playbackButtonHandler(evt) { - if (playbackTestRunning) { - $('#playback-testing p').html('Test stopped by user'); - $('#playbackTestingButton').html('Start Playback Test'); - playbackTestRunning = false; - context.jamClient.StopPlayTest(); - } else { - $('#playback-testing p').html('Playback test in progress... Click the button below when things start to sound crappy'); - $('#playbackTestingButton').html('Click when things sound bad...'); - playbackTestRunning = true; - context.jamClient.StartPlayTest('JK.playbackTestComplete'); - } - } - - function playbackTestComplete() { - logger.debug('playbackTestComplete. Arguments:'); - logger.debug(arguments); - $('#playback-testing p').html('Done'); - $('#playbackTestingButton').html('Start Playback Test'); - playbackTestRunning = false; - } - - function recordingButtonHandler(evt) { - if (recordingTestRunning) { - $('#recording-testing p').html('Recording complete.'); - $('#recordingTestingButton').html('Start Recording Test'); - recordingTestRunning = false; - context.jamClient.RecordTestEnd(); - } else { - $('#recording-testing p').html('Recording in progress... Click the button below to stop recording'); - $('#recordingTestingButton').html('Stop Recording'); - recordingTestRunning = true; - context.jamClient.RecordTestBegin(); - } - } - - function recordingPlaybackButtonHandler(evt) { - context.jamClient.RecordTestPlayback(); - } function events() { $('#enableDevices').click(function() { @@ -135,15 +97,12 @@ testLatency(); }); - $('#playbackTestingButton').click(playbackButtonHandler); - $('#recordingTestingButton').click(recordingButtonHandler); - $('#recordingTestPlaybackButton').click(recordingPlaybackButtonHandler); } function initialize() { events(); var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow }; - app.bindScreen('ftue3', screenBindings); + app.bindScreen('ftue2', screenBindings); } // Expose publics @@ -151,7 +110,6 @@ // Expose callbacks for the bridge on the global namespace context.JK.latencyTestingComplete = latencyTestingComplete; - context.JK.playbackTestComplete = playbackTestComplete; return this; }; diff --git a/app/assets/javascripts/ftueAudioTesting.js b/app/assets/javascripts/ftueAudioTesting.js new file mode 100644 index 000000000..cc5b5116f --- /dev/null +++ b/app/assets/javascripts/ftueAudioTesting.js @@ -0,0 +1,98 @@ +/** +* FtueAudioTestingScreen +* Javascript that goes with the screen where +* testing of selected audio devices happens. +* Corresponds to /#ftue3 +*/ +(function(context,$) { + "use strict"; + + context.JK = context.JK || {}; + context.JK.FtueAudioTestingScreen = function(app) { + var logger = context.JK.logger; + var jamClient = context.jamClient; + + var selectors = { + step1: 'div[layout-id="ftue3"] div[data-step="step1"]', + step2: 'div[layout-id="ftue3"] div[data-step="step2"]', + step3: 'div[layout-id="ftue3"] div[data-step="step3"]', + good: 'div[layout-id="ftue3"] div[data-step="good"]', + bad: 'div[layout-id="ftue3"] div[data-step="bad"]', + progress1: '#recordingTestProgress1', + progress1Int: '#___recordingTestProgress1___', + progress2: '#recordingTestProgress2', + progress2Int: '#___recordingTestProgress2___' + }; + + function beforeShow(data) { + $(selectors.step1).show(); + $(selectors.step2).hide(); + $(selectors.step3).hide(); + $(selectors.good).hide(); + $(selectors.bad).hide(); + } + + function afterShow(data) {} + + function runProgressBar(selector, seconds, doneFunction) { + var id = "___" + selector.substr(1) + "___"; + $(selector).html('
'); + $("#" + id).animate({ + width: "400px" + }, seconds * 1000, doneFunction); + } + + function startTestButtonHandler(evt) { + $(selectors.step1).hide(); + $(selectors.step3).hide(); + $(selectors.good).hide(); + $(selectors.bad).hide(); + $(selectors.step2).show(); + runProgressBar(selectors.progress1, 10, good); + context.jamClient.RecordTestBegin(); + } + + function poorAudioButtonHandler(evt) { + $(selectors.progress1Int).stop(); + $(selectors.step2).hide(); + $(selectors.step3).show(); + runProgressBar(selectors.progress2, 10, bad); + //context.jamClient.RecordTestBegin(); + } + + function goodAudioButtonHandler(evt) { + good(); + } + + function good() { + $(selectors.step2).hide(); + $(selectors.step3).hide(); + $(selectors.good).show(); + } + + function bad() { + $(selectors.step3).hide(); + $(selectors.bad).show(); + } + + function events() { + $('.startTestButton').click(startTestButtonHandler); + $('#poorAudioButton').click(poorAudioButtonHandler); + $('#goodAudioButton').click(goodAudioButtonHandler); + } + + function initialize() { + events(); + var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow }; + app.bindScreen('ftue3', screenBindings); + } + + // Expose publics + this.initialize = initialize; + + //context.JK.playbackTestComplete = playbackTestComplete; + + return this; + }; + + })(window,jQuery); \ No newline at end of file diff --git a/app/assets/stylesheets/client/ftue.css.scss b/app/assets/stylesheets/client/ftue.css.scss new file mode 100644 index 000000000..be15eba5e --- /dev/null +++ b/app/assets/stylesheets/client/ftue.css.scss @@ -0,0 +1,42 @@ +/* Custom Styles for the FTUE Screens */ + +@import "client/common.css.scss"; +@charset "UTF-8"; + +div[layout-id="ftue2"] { + .formrow { + position:relative; + clear:both; + border:none; + margin: 12px; + padding:4px; + } + label { + text-align:left; + } + select { + display:block; + position:absolute; + left: 140px; + top: 0px; + } +} + +div[layout-id="ftue3"] { + button { + margin: 0px 2em; + } + + .progressContainer { + margin: 2em; + border: 1px solid #fff; + width: 400px; + height: 10px; + } + + .progressFull { + height: 10px; + width: 2px; + background-color:#0f0; + } +} diff --git a/app/assets/stylesheets/client/jamkazam.css.scss b/app/assets/stylesheets/client/jamkazam.css.scss index 566c06e08..c18f09c0d 100644 --- a/app/assets/stylesheets/client/jamkazam.css.scss +++ b/app/assets/stylesheets/client/jamkazam.css.scss @@ -21,9 +21,12 @@ body { font-weight: 300; } +b { font-weight: bold; } + a { cursor:pointer; color: $ColorLink; + text-decoration: none; } a:hover { diff --git a/app/assets/stylesheets/client/screen_common.css.scss b/app/assets/stylesheets/client/screen_common.css.scss index b93afebdc..78fdc5b7e 100644 --- a/app/assets/stylesheets/client/screen_common.css.scss +++ b/app/assets/stylesheets/client/screen_common.css.scss @@ -8,6 +8,39 @@ .screen.secondary { border: 1px solid $ColorScreenPrimary; background-color:$ColorScreenBackground; + + .footer button { + margin:1em 0em 1em 1em; + } + + .breadcrumb { + margin-bottom:3em; + } + + .breadcrumb p { + float:left; + } + + p { + margin: 1em; + cursor: pointer; + font-size: 120%; + line-height: 150%; + } + + ul { + margin-left: 2em; + list-style: disc; + } + + li { + margin-bottom:1.5em; + } + + p.current { + font-weight: bold; + } + } .content-head { @@ -70,23 +103,3 @@ width:100%; /*text-align:right;*/ } -.screen.secondary .footer button { - margin:1em 0em 1em 1em; -} - -.screen.secondary .breadcrumb { - margin-bottom:3em; -} - -.screen.secondary .breadcrumb p { - float:left; -} - -.screen.secondary p { - margin: .5em; - cursor: pointer; - font-size: 120%; -} -.screen.secondary p.current { - font-weight: bold; -} diff --git a/app/views/clients/_ftue1.html.erb b/app/views/clients/_ftue1.html.erb index 28280984a..abf69e557 100644 --- a/app/views/clients/_ftue1.html.erb +++ b/app/views/clients/_ftue1.html.erb @@ -1,10 +1,17 @@
-

Welcome to JamKazam!

+

Audio Gear Setup

<%= render "screen_navigation" %>
-

You'll need appropriate audio gear. Here are some links to where you can buy some.

-

Make sure your audio gear is plugged in, then CONTINUE.

+

If you already have audio gear to get your instrumental or vocal music into your computer, please set up your gear and instrument now. Then click the Next button below. For Windows this will be ASIO-compatible audio devices, and Mac gear will use Core Audio. We strongly recommend using headphones with your gear vs. speakers or powered monitors to avoid feedback problems. If you don't already have this gear handy or are not sure what will work, please use the help links below for some guidance:

+ +
+

+
diff --git a/app/views/clients/_ftue2.html.erb b/app/views/clients/_ftue2.html.erb index 20273c3ab..26fce3cdc 100644 --- a/app/views/clients/_ftue2.html.erb +++ b/app/views/clients/_ftue2.html.erb @@ -1,10 +1,42 @@
-

Welcome to JamKazam!

+

Audio Gear Settings

<%= render "screen_navigation" %>
-

Next we'll show you how to hook up a cable for a loopback test, so we can test your latency.

-

Once your cables are all connected, then CONTINUE.

+

Please choose the audio gear you want to use for audio input, chat input, and audio output below. Then play and either sing or speak to ensure that you can hear both your instrument and voice through your headphones. After verifying that you hear your music and voice properly, please click the Next button below. If you don't hear things correctly, please press the Help button below for troubleshooting guidance.

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+

+ + + +

+
+ + diff --git a/app/views/clients/_ftue3.html.erb b/app/views/clients/_ftue3.html.erb index f921b9d3a..3345abcd4 100644 --- a/app/views/clients/_ftue3.html.erb +++ b/app/views/clients/_ftue3.html.erb @@ -1,45 +1,44 @@
-

Welcome to JamKazam!

+

Audio Gear Test

<%= render "screen_navigation" %>
-
-

Step 1: Choose Devices

- - - +
+

We will now test your audio gear to ensure it works and to find its ideal settings. When you are ready, please click the Start Test button below, and be ready to start playing your instrument or singing.

+
-
-

Latency Testing

-

+
+

Please play your instrument and/or sing, and listen to the audio. If the quality of the audio becomes poor, please click the Poor Audio button below. This test will last about 45 seconds.

+ +
-
-

Playback Testing

-

Click the button below to start a playback test. We'll start with safe settings, and then lower the values for better latency. When things begin to sound bad, click the button again.

- +
+

Please press the Good Audio button when the audio quality improves to an acceptable level.

+ +
-
-

Recording Testing

-

When ready, click the button below to enable recording of your audio input. When done, click the button again, and use the other button for playback to see how things sound.

- - + +
+

Congratulations! Your audio gear is now ready to use, and you may create or join sessions with other musicians in JamKazam.

+
-

If everything looks good, then WE'RE DONE.

+
+

We're sorry, but it appears you are not happy with the quality of your audio, so we cannot recommend that you use JamKazam with this audio gear.

+ + +
+
+

+ + +

+
- diff --git a/app/views/clients/index.html.erb b/app/views/clients/index.html.erb index 1f87d7d36..cbd8ccf80 100644 --- a/app/views/clients/index.html.erb +++ b/app/views/clients/index.html.erb @@ -72,13 +72,15 @@ var sessionScreen = new JK.SessionScreen(jk); sessionScreen.initialize(); - var ftueScreen = new JK.FTUEScreen(jk); - ftueScreen.initialize(); + var ftueAudioSelectionScreen = new JK.FtueAudioSelectionScreen(jk); + ftueAudioSelectionScreen.initialize(); + + var ftueAudioTestingScreen = new JK.FtueAudioTestingScreen(jk); + ftueAudioTestingScreen.initialize(); var testBridgeScreen = new JK.TestBridgeScreen(jk); testBridgeScreen.initialize(); - } else { var landing = new JK.LandingPage(jk); landing.initialize(); diff --git a/app/views/layouts/client.html.erb b/app/views/layouts/client.html.erb index 07500a21d..45ab02314 100644 --- a/app/views/layouts/client.html.erb +++ b/app/views/layouts/client.html.erb @@ -18,6 +18,7 @@ <%= stylesheet_link_tag "client/findSession", media: "all" %> <%= stylesheet_link_tag "client/session", media: "all" %> <%= stylesheet_link_tag "client/search", media: "all" %> + <%= stylesheet_link_tag "client/ftue", media: "all" %> <%= stylesheet_link_tag "client/lato", media: "all" %> <%= include_gon %> <%= javascript_include_tag "application" %> diff --git a/features/step_definitions/create_session_steps.rb b/features/step_definitions/create_session_steps.rb index c8f797a60..a3b178a60 100644 --- a/features/step_definitions/create_session_steps.rb +++ b/features/step_definitions/create_session_steps.rb @@ -14,6 +14,12 @@ When /^I create a public music session$/ do sleep 1 page.find("a[href='#/ftue3']").click sleep 1 + page.find('div[data-step="step1"] button.startTestButton').click + sleep 1 + page.find("#poorAudioButton").click + sleep 1 + page.find("#goodAudioButton").click + sleep 1 page.find("[cucumber-id='ftue-home-link']").click sleep 1 @@ -47,6 +53,12 @@ Then /^I should be in a music session that another musician can find$/ do sleep 1 @second_session.find("a[href='#/ftue3']").click sleep 1 + @second_session.find('div[data-step="step1"] button.startTestButton').click + sleep 1 + @second_session.find("#poorAudioButton").click + sleep 1 + @second_session.find("#goodAudioButton").click + sleep 1 @second_session.find("[cucumber-id='ftue-home-link']").click sleep 1 diff --git a/features/support/login_helper.rb b/features/support/login_helper.rb index b5153b92b..e869e908c 100644 --- a/features/support/login_helper.rb +++ b/features/support/login_helper.rb @@ -2,6 +2,11 @@ module LoginHelper def login(user, context) context.visit root_path + + # When troubleshooting JS errors, sleeping when the UI first comes up is helpful. + # It allows you to bring up a JS console on the test browser and see what the problem is. + # sleep 60 + # verify that the root page is showing context.should have_content "Welcome to JamKazam" @@ -20,4 +25,4 @@ module LoginHelper end end -World(LoginHelper) \ No newline at end of file +World(LoginHelper) diff --git a/jenkins b/jenkins index 60eddfe68..0acf5a9a9 100755 --- a/jenkins +++ b/jenkins @@ -1,12 +1,26 @@ #!/bin/bash +DEB_SERVER=http://localhost:9010/apt-i386 + echo "starting build..." ./build if [ "$?" = "0" ]; then echo "build succeeded" - - echo "TODO: build debian package" + + if [ ! -z "$PACKAGE" ]; then + echo "publishing ubuntu package (.deb)" + DEBPATH=`find target/deb -name *.deb` + DEBNAME=`basename $DEBPATH` + + curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME + + if [ "$?" != "0" ]; then + echo "deb publish failed" + exit 1 + fi + echo "done publishing deb" + fi else echo "build failed" exit 1 diff --git a/spec/requests/music_sessions_api_spec.rb b/spec/requests/music_sessions_api_spec.rb index 4d1e9388d..917a82daf 100644 --- a/spec/requests/music_sessions_api_spec.rb +++ b/spec/requests/music_sessions_api_spec.rb @@ -12,15 +12,7 @@ describe "Music Session API ", :type => :api do end def make_friends(user1, user2) - friendship = Friendship.new() - friendship.user_id = user1.id - friendship.friend_id = user2.id - friendship.save - - friendship = Friendship.new() - friendship.user_id = user2.id - friendship.friend_id = user1.id - friendship.save + Friendship.save(user1, user2) end describe "profile page" do