diff --git a/ruby/lib/jam_ruby/app/uploaders/music_notation_uploader.rb b/ruby/lib/jam_ruby/app/uploaders/music_notation_uploader.rb index 9735463cf..9f045a949 100644 --- a/ruby/lib/jam_ruby/app/uploaders/music_notation_uploader.rb +++ b/ruby/lib/jam_ruby/app/uploaders/music_notation_uploader.rb @@ -16,6 +16,6 @@ class MusicNotationUploader < CarrierWave::Uploader::Base end def extension_white_list - %w(pdf png jpg jpeg git xml mxl txt) + %w(pdf png jpg jpeg gif xml mxl txt) end end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/feed.rb b/ruby/lib/jam_ruby/models/feed.rb index 0802e3085..6ac48f792 100644 --- a/ruby/lib/jam_ruby/models/feed.rb +++ b/ruby/lib/jam_ruby/models/feed.rb @@ -29,7 +29,7 @@ module JamRuby start = start.to_i time_range = params[:time_range] - time_range ||= 'month' + time_range ||= 'all' raise "not valid time_range #{time_range}" unless TIME_RANGES.has_key?(time_range) type_filter = params[:type] diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb index 965942103..c0588840c 100644 --- a/ruby/lib/jam_ruby/models/music_session.rb +++ b/ruby/lib/jam_ruby/models/music_session.rb @@ -226,7 +226,6 @@ module JamRuby def self.scheduled user query = MusicSession.where("music_sessions.user_id = '#{user.id}'") - query = query.where("music_sessions.scheduled_start IS NOT NULL AND music_sessions.scheduled_start < NOW() + '12 hour'::INTERVAL") query = query.where("music_sessions.scheduled_start > NOW() - '12 hour'::INTERVAL") query = query.where("music_session_id IS NULL") query = query.order("music_sessions.scheduled_start ASC") @@ -394,7 +393,7 @@ module JamRuby end def legal_policy_url - # TODO: move to DB or config file + # TODO: move to DB or config file or helper case legal_policy when "standard" return "http://www.jamkazam.com/session-legal-policies/standard" @@ -443,6 +442,10 @@ module JamRuby end end + def scheduled_end_time + + end + def timezone_description self.get_timezone.to_s end diff --git a/ruby/lib/jam_ruby/models/share_token.rb b/ruby/lib/jam_ruby/models/share_token.rb index 18bb751e6..2f52afe41 100644 --- a/ruby/lib/jam_ruby/models/share_token.rb +++ b/ruby/lib/jam_ruby/models/share_token.rb @@ -1,7 +1,5 @@ module JamRuby class ShareToken < ActiveRecord::Base belongs_to :shareable, :polymorphic => true - - end end \ No newline at end of file diff --git a/ruby/spec/jam_ruby/models/feed_spec.rb b/ruby/spec/jam_ruby/models/feed_spec.rb index d7ba3391d..54ec1955e 100644 --- a/ruby/spec/jam_ruby/models/feed_spec.rb +++ b/ruby/spec/jam_ruby/models/feed_spec.rb @@ -150,7 +150,7 @@ describe Feed do claimed_recording1.recording.feed.created_at = 32.days.ago claimed_recording1.recording.feed.save! - feeds, start = Feed.index(user1, :type => 'recording') + feeds, start = Feed.index(user1, :type => 'recording', time_range: 'month') feeds.length.should == 0 end diff --git a/ruby/spec/jam_ruby/models/music_session_spec.rb b/ruby/spec/jam_ruby/models/music_session_spec.rb index 9176ed777..e1a494ca6 100644 --- a/ruby/spec/jam_ruby/models/music_session_spec.rb +++ b/ruby/spec/jam_ruby/models/music_session_spec.rb @@ -209,6 +209,36 @@ describe MusicSession do end end + describe "scheduled" do + it "excludes based on time-range" do + session = FactoryGirl.create(:music_session, scheduled_start: Time.now) + + sessions = MusicSession.scheduled(session.creator) + sessions.length.should == 1 + + session.scheduled_start = 11.hours.ago + session.save! + sessions = MusicSession.scheduled(session.creator) + sessions.length.should == 1 + + session.scheduled_start = 13.hours.ago + session.save! + sessions = MusicSession.scheduled(session.creator) + sessions.length.should == 0 + + session.scheduled_start = 13.hours.from_now + session.save! + sessions = MusicSession.scheduled(session.creator) + sessions.length.should == 1 + + session.scheduled_start = 300.days.from_now + session.save! + sessions = MusicSession.scheduled(session.creator) + sessions.length.should == 1 + + end + end + def sms(user, params) ActiveRecord::Base.transaction do return MusicSession.sms_index(user, params) diff --git a/web/app/assets/javascripts/accounts_audio_profile.js b/web/app/assets/javascripts/accounts_audio_profile.js index d6c2ed709..42d731577 100644 --- a/web/app/assets/javascripts/accounts_audio_profile.js +++ b/web/app/assets/javascripts/accounts_audio_profile.js @@ -29,7 +29,6 @@ function renderAudioProfileScreen() { if (!gon.isNativeClient) { -// app.layout.showDialog('launch-app-dialog', {d1: 'gear'}); context.JK.guardAgainstBrowser(app, {d1: 'gear'}); } else { diff --git a/web/app/assets/javascripts/banner.js b/web/app/assets/javascripts/banner.js index 99e0ddfbd..b2e8a89a8 100644 --- a/web/app/assets/javascripts/banner.js +++ b/web/app/assets/javascripts/banner.js @@ -114,11 +114,13 @@ if(options.buttons) { var $buttons = $banner.find('.buttons') - context._.each(options.buttons, function(button) { + context._.each(options.buttons, function(button, i) { if(!button.name) throw "button.name must be specified"; if(!button.click) throw "button.click must be specified"; - var $btn = $('' + button.name + ''); + var buttonStyle = options.buttons.length == i + 1 ? 'button-orange' : 'button-grey'; + + var $btn = $('' + button.name + ''); $btn.click(function() { button.click(); hide(); diff --git a/web/app/assets/javascripts/configureTracksHelper.js b/web/app/assets/javascripts/configureTracksHelper.js index e2beb0656..0d17ac918 100644 --- a/web/app/assets/javascripts/configureTracksHelper.js +++ b/web/app/assets/javascripts/configureTracksHelper.js @@ -153,7 +153,9 @@ .css('min-width', '') } - function loadChannels(forceInputsToUnassign) { + // inputChannelFilter is an optional argument that is used by the Gear Wizard. + // basically, if an input channel isn't in there, it's not going to be displayed + function loadChannels(forceInputsToUnassign, inputChannelFilter) { var musicPorts = jamClient.FTUEGetChannels(); $unassignedInputsHolder.empty(); @@ -172,6 +174,12 @@ //inputChannels = inputChannels.concat(inputChannels.concat(inputChannels.concat(inputChannels))) context._.each(inputChannels, function (inputChannel) { + + if(inputChannelFilter && !(inputChannelFilter.indexOf(inputChannel.id) > -1)) { + // skipping input channel because it's not in the filter + return; + } + var $channel = $(context._.template($templateAssignablePort.html(), inputChannel, { variable: 'data' })); $channel.hover( @@ -431,8 +439,8 @@ return saved; } - function reset(forceInputsToUnassign) { - loadChannels(forceInputsToUnassign); + function reset(forceInputsToUnassign, inputChannelFilter) { + loadChannels(forceInputsToUnassign, inputChannelFilter); loadTrackInstruments(forceInputsToUnassign); } diff --git a/web/app/assets/javascripts/fakeJamClient.js b/web/app/assets/javascripts/fakeJamClient.js index 4074b3de0..af144dfd6 100644 --- a/web/app/assets/javascripts/fakeJamClient.js +++ b/web/app/assets/javascripts/fakeJamClient.js @@ -774,6 +774,10 @@ logger.debug("SessionLiveBroadcastStop requested"); } + function RegisterQuitCallback() { + + } + // Javascript Bridge seems to camel-case // Set the instance functions: this.AbortRecording = AbortRecording; @@ -804,6 +808,7 @@ this.IsMyNetworkWireless = IsMyNetworkWireless; this.SetNetworkTestScore = SetNetworkTestScore; this.GetNetworkTestScore = GetNetworkTestScore; + this.RegisterQuitCallback = RegisterQuitCallback; this.connected = true; // FTUE (round 3) diff --git a/web/app/assets/javascripts/findSession.js b/web/app/assets/javascripts/findSession.js index 396c0b813..4869fe0d6 100644 --- a/web/app/assets/javascripts/findSession.js +++ b/web/app/assets/javascripts/findSession.js @@ -145,7 +145,7 @@ } function beforeShow(data) { - context.JK.GenreSelectorHelper.render('#find-session-genre'); + context.JK.GenreSelectorHelper.render('#find-session-genre', 'Any Genre'); } function afterShow(data) { diff --git a/web/app/assets/javascripts/friendSelector.js b/web/app/assets/javascripts/friendSelector.js index ce3aac5eb..8bb232bbd 100644 --- a/web/app/assets/javascripts/friendSelector.js +++ b/web/app/assets/javascripts/friendSelector.js @@ -70,7 +70,6 @@ newSelections = {}; loadFriends(); // HACK TO OVERRIDE PADDING SET SOMEWHERE ELSE - $('.choosefriends-overlay').css({"padding":"8px"}); } this.initialize = function() { diff --git a/web/app/assets/javascripts/genreSelector.js b/web/app/assets/javascripts/genreSelector.js index 42c2ca442..e8341291d 100644 --- a/web/app/assets/javascripts/genreSelector.js +++ b/web/app/assets/javascripts/genreSelector.js @@ -27,9 +27,12 @@ }); } - function render(parentSelector) { + function render(parentSelector, notSelectedString) { + if(!notSelectedString) { + notSelectedString = 'Unspecified' + } $('select', parentSelector).empty(); - $('select', parentSelector).append(''); + $('select', parentSelector).append(''); var template = $('#template-genre-option').html(); $.each(_genres, function(index, value) { // value will be a dictionary entry from _genres: diff --git a/web/app/assets/javascripts/globals.js b/web/app/assets/javascripts/globals.js index 86cf69dcf..4cacf3c4f 100644 --- a/web/app/assets/javascripts/globals.js +++ b/web/app/assets/javascripts/globals.js @@ -28,7 +28,9 @@ }; context.JK.EVENTS = { - DIALOG_CLOSED : 'dialog_closed' + DIALOG_CLOSED : 'dialog_closed', + SHOW_SIGNUP : 'show_signup', + SHOW_SIGNIN : 'show_signin' } context.JK.ALERT_NAMES = { diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js index 9f84e786d..348a6d535 100644 --- a/web/app/assets/javascripts/jam_rest.js +++ b/web/app/assets/javascripts/jam_rest.js @@ -215,6 +215,16 @@ }); } + function updateRsvpRequest(rsvpRequestId, responses) { + return $.ajax({ + url: '/api/rsvp_requests/' + rsvpRequestId, + type: "POST", + data : responses, + dataType : 'json', + contentType: 'application/json' + }); + } + function cancelRsvpRequest(sessionId, rsvpRequestId, cancelAll) { var cancel = "yes"; if (cancelAll) { @@ -1226,6 +1236,7 @@ this.addSessionLike = addSessionLike; this.getRsvpRequests = getRsvpRequests; this.submitRsvpRequest = submitRsvpRequest; + this.updateRsvpRequest = updateRsvpRequest; this.cancelRsvpRequest = cancelRsvpRequest; this.getOpenSessionSlots = getOpenSessionSlots; this.addRecordingComment = addRecordingComment; diff --git a/web/app/assets/javascripts/landing/landing.js b/web/app/assets/javascripts/landing/landing.js index fbdb167c0..3da8e39a0 100644 --- a/web/app/assets/javascripts/landing/landing.js +++ b/web/app/assets/javascripts/landing/landing.js @@ -1,13 +1,35 @@ //= require jquery +//= require jquery.monkeypatch +//= require jquery_ujs +//= require jquery.ui.draggable //= require jquery.queryparams +//= require jquery.hoverIntent +//= require jquery.cookie +//= require jquery.clipboard +//= require jquery.easydropdown +//= require jquery.carousel-1.1 +//= require jquery.mousewheel-3.1.9 +//= require jquery.timeago +//= require jquery.dotdotdot +//= require jquery.listenbroadcast +//= require jquery.listenRecording +//= require jquery.browser +//= require jquery.custom-protocol +//= require jquery.ba-bbq //= require AAA_Log //= require AAC_underscore //= require globals +//= require AAB_message_factory +//= require facebook_helper +//= require layout //= require jamkazam //= require utils //= require ui_helper //= require ga //= require jam_rest +//= require web/signup_helper +//= require web/signin_helper +//= require web/signin //= require landing/init //= require landing/signup //= require shareDialog \ No newline at end of file diff --git a/web/app/assets/javascripts/landing/signup.js b/web/app/assets/javascripts/landing/signup.js index 6e5a56651..a91329222 100644 --- a/web/app/assets/javascripts/landing/signup.js +++ b/web/app/assets/javascripts/landing/signup.js @@ -45,7 +45,9 @@ $.ajax('/api/regions', { data : { country: selected_country }, dataType : 'json' - }).done(regions_done).fail(regions_fail).always(function() { region_select.attr('disabled', false).easyDropDown('enable') }) + }).done(regions_done) + .fail(function(err) { regions_done([]) }) + .always(function() { region_select.attr('disabled', false).easyDropDown('enable') }) } }) @@ -56,16 +58,13 @@ $(data.regions).each(function(index, item) { var option = $(''); - option.text(item); - option.val(item); + option.text(item['name']); + option.val(item['region']); region_select.append(option) }) context.JK.dropdown(region_select); - } - - function regions_fail() { - alert("something went wrong in looking up regions") + cities_done([]); } region_select.change(function() { @@ -80,7 +79,12 @@ $.ajax('/api/cities', { data : { country: selected_country, region: selected_region }, dataType : 'json' - }).done(cities_done).fail(cities_fail).always(function() { city_select.attr('disabled', false).easyDropDown('enable') }) + }) + .done(cities_done) + .error(function(err) { + cities_done([]); + }) + .always(function() { city_select.attr('disabled', false).easyDropDown('enable') }) } }) @@ -97,10 +101,6 @@ context.JK.dropdown(city_select); } - - function cities_fail() { - alert("something went wrong in looking up cities") - } } signup.handle_completion_submit = function handle_completion_submit() { diff --git a/web/app/assets/javascripts/launchAppDialog.js b/web/app/assets/javascripts/launchAppDialog.js index 417a8c83c..af900466e 100644 --- a/web/app/assets/javascripts/launchAppDialog.js +++ b/web/app/assets/javascripts/launchAppDialog.js @@ -60,7 +60,6 @@ function handleBack() { app.layout.closeDialog('launch-app-dialog'); - window.location = '/client#/home'; return false; } diff --git a/web/app/assets/javascripts/networkTestDialog.js b/web/app/assets/javascripts/networkTestDialog.js index c739355a6..ad00388fb 100644 --- a/web/app/assets/javascripts/networkTestDialog.js +++ b/web/app/assets/javascripts/networkTestDialog.js @@ -20,6 +20,10 @@ unfreezeInteractions(); } + function networkTestCancel() { + unfreezeInteractions(); + } + function networkTestStart() { freezeInteractions(); } @@ -47,10 +51,10 @@ return false; }) - $btnHelp.on('click', function(e) { + /** $btnHelp.on('click', function(e) { context.JK.Banner.showAlert('No help is yet available for the network test.'); return false; - }) + })*/ } function beforeShow() { @@ -81,6 +85,7 @@ $(networkTest) .on(networkTest.NETWORK_TEST_DONE, networkTestDone) .on(networkTest.NETWORK_TEST_FAIL, networkTestFail) + .on(networkTest.NETWORK_TEST_CANCEL, networkTestCancel) .on(networkTest.NETWORK_TEST_START, networkTestStart) events(); diff --git a/web/app/assets/javascripts/networkTestHelper.js b/web/app/assets/javascripts/networkTestHelper.js index 098764b4e..c3879a0b0 100644 --- a/web/app/assets/javascripts/networkTestHelper.js +++ b/web/app/assets/javascripts/networkTestHelper.js @@ -6,12 +6,12 @@ context.JK.NetworkTest = function (app) { var NETWORK_TEST_TYPES = { - RestPhase : 0, - PktTest100NormalLatency : 1, - PktTest200MediumLatency : 2, - PktTest400LowLatency : 3, - PktTestRateSweep : 4, - RcvOnly : 5 + RestPhase: 0, + PktTest100NormalLatency: 1, + PktTest200MediumLatency: 2, + PktTest400LowLatency: 3, + PktTestRateSweep: 4, + RcvOnly: 5 } var STARTING_NUM_CLIENTS = 4; var PAYLOAD_SIZE = 100; @@ -37,11 +37,13 @@ var $subscore = null; var $watchVideo = null; var backendGuardTimeout = null; + var primeGuardTimeout = null; + var primeDeferred = null; var serverClientId = ''; var scoring = false; var numClientsToTest = STARTING_NUM_CLIENTS; - var testSummary = {attempts : [], final:null} + var testSummary = {attempts: [], final: null} var $self = $(this); var scoringZoneWidth = 100;//px var inGearWizard = false; @@ -52,36 +54,57 @@ var lastNetworkFailure = null; var bandwidthSamples = []; - var NETWORK_TEST_START = 'network_test.start'; - var NETWORK_TEST_DONE = 'network_test.done'; - var NETWORK_TEST_FAIL = 'network_test.fail'; + var NETWORK_TEST_START = 'network_test.start'; + var NETWORK_TEST_DONE = 'network_test.done'; + var NETWORK_TEST_FAIL = 'network_test.fail'; + var NETWORK_TEST_CANCEL = 'network_test.cancel'; - function createSuccessCallbackName() { - if(inGearWizard) { - return TEST_SUCCESS_CALLBACK + 'ForGearWizard'; + function createSuccessCallbackName(priming) { + if (priming) { + if (inGearWizard) { + return TEST_SUCCESS_CALLBACK + 'ForPumpPrimingGW'; + } + else { + return TEST_SUCCESS_CALLBACK + 'ForPumpPrimingDialog'; + } } else { - return TEST_SUCCESS_CALLBACK + 'ForDialog'; + if (inGearWizard) { + return TEST_SUCCESS_CALLBACK + 'ForGearWizard'; + } + else { + return TEST_SUCCESS_CALLBACK + 'ForDialog'; + } } } - function createTimeoutCallbackName() { - if(inGearWizard) { - return TEST_TIMEOUT_CALLBACK + 'ForGearWizard'; + function createTimeoutCallbackName(priming) { + if (priming) { + if (inGearWizard) { + return TEST_TIMEOUT_CALLBACK + 'ForPumpPrimingGW'; + } + else { + return TEST_TIMEOUT_CALLBACK + 'ForPumpPrimingDialog'; + } } else { - return TEST_TIMEOUT_CALLBACK + 'ForDialog'; + if (inGearWizard) { + return TEST_TIMEOUT_CALLBACK + 'ForGearWizard'; + } + else { + return TEST_TIMEOUT_CALLBACK + 'ForDialog'; + } } } // this averages bandwidthSamples; this method is meant just for GA data function avgBandwidth(num_others) { - if(bandwidthSamples.length == 0) { + if (bandwidthSamples.length == 0) { return 0; } else { var total = 0; - context._.each(bandwidthSamples, function(sample) { + context._.each(bandwidthSamples, function (sample) { total += (sample * num_others * 400 * (100 + 28)); // sample is a percentage of 400. So sample * 400 gives us how many packets/sec. 100 is payload; 28 is UDP+ETHERNET overhead, to give us bandwidth }) return total / bandwidthSamples.length; @@ -98,7 +121,7 @@ serverClientId = ''; scoring = false; numClientsToTest = STARTING_NUM_CLIENTS; - testSummary = {attempts : []}; + testSummary = {attempts: []}; configureStartButton(); $scoredClients.empty(); $testResults.removeClass('good acceptable bad testing'); @@ -125,12 +148,12 @@ function postDiagnostic() { rest.createDiagnostic({ type: 'NETWORK_TEST_RESULT', - data: {client_type: context.JK.clientType(), client_id: context.JK.JamServer.clientID, summary:testSummary} + data: {client_type: context.JK.clientType(), client_id: context.JK.JamServer.clientID, summary: testSummary} }); } function appendContextualStatement() { - if(inGearWizard) { + if (inGearWizard) { return "You can skip this step for now." } else { @@ -143,37 +166,37 @@ } function storeLastNetworkFailure(reason, data) { - if(!trackedPass) { - lastNetworkFailure = {reason:reason, data:data}; + if (!trackedPass) { + lastNetworkFailure = {reason: reason, data: data}; } } function testFinished() { var attempt = getCurrentAttempt(); - if(!testSummary.final) { - testSummary.final = {reason : attempt.reason}; + if (!testSummary.final) { + testSummary.final = {reason: attempt.reason}; } var reason = testSummary.final.reason; var success = false; - if(reason == "success") { + if (reason == "success") { renderStopTest(attempt.num_clients, "Your router and Internet service will support sessions of up to " + attempt.num_clients + " JamKazam musicians.") testedSuccessfully = true; - if(!testSummary.final.num_clients) { + if (!testSummary.final.num_clients) { testSummary.final.num_clients = attempt.num_clients; } // context.jamClient.GetNetworkTestScore() == 0 is a rough approximation if the user has passed the FTUE before - if(inGearWizard || context.jamClient.GetNetworkTestScore() == 0) { + if (inGearWizard || context.jamClient.GetNetworkTestScore() == 0) { trackedPass = true; lastNetworkFailure = null; context.JK.GA.trackNetworkTest(context.JK.detectOS(), testSummary.final.num_clients); } context.jamClient.SetNetworkTestScore(attempt.num_clients); - if(testSummary.final.num_clients == 2) { + if (testSummary.final.num_clients == 2) { $testResults.addClass('acceptable'); } else { @@ -181,63 +204,63 @@ } success = true; } - else if(reason == "minimum_client_threshold") { + else if (reason == "minimum_client_threshold") { context.jamClient.SetNetworkTestScore(0); renderStopTest('', "We're sorry, but your router and Internet service will not effectively support JamKazam sessions. Please click the HELP button for more information.") storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.bandwidth, avgBandwidth(attempt.num_clients - 1)); } - else if(reason == "unreachable" || reason == "no-transmit") { + else if (reason == "unreachable" || reason == "no-transmit") { context.jamClient.SetNetworkTestScore(0); renderStopTest('', "We're sorry, but your router will not support JamKazam in its current configuration. Please click the HELP button for more information."); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.stun, attempt.num_clients); } - else if(reason == "internal_error") { + else if (reason == "internal_error") { context.JK.alertSupportedNeeded("The JamKazam client software had an unexpected problem while scoring your Internet connection."); renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } - else if(reason == "remote_peer_cant_test") { + else if (reason == "remote_peer_cant_test") { context.JK.alertSupportedNeeded("The JamKazam service is experiencing technical difficulties."); renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } - else if(reason == "server_comm_timeout") { + else if (reason == "server_comm_timeout") { gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("Communication with the JamKazam network service has timed out." + appendContextualStatement()); renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } - else if(reason == 'backend_gone') { + else if (reason == 'backend_gone') { context.JK.alertSupportedNeeded("The JamKazam client is experiencing technical difficulties."); renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } - else if(reason == "invalid_response") { + else if (reason == "invalid_response") { gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("The JamKazam client software had an unexpected problem while scoring your Internet connection.

Reason: " + attempt.backend_data.reason + '.'); renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } - else if(reason == 'no_servers') { + else if (reason == 'no_servers') { gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("No network test servers are available." + appendContextualStatement()); renderStopTest('', ''); testedSuccessfully = true; storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } - else if(reason == 'no_network') { + else if (reason == 'no_network') { context.JK.Banner.showAlert("Please try again later. Your network appears down."); renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.noNetwork); } - else if(reason == "rest_api_error") { + else if (reason == "rest_api_error") { gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("Unable to acquire a network test server." + appendContextualStatement()); testedSuccessfully = true; renderStopTest('', ''); storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror); } - else if(reason == "timeout") { + else if (reason == "timeout") { gearUtils.skipNetworkTest(); context.JK.alertSupportedNeeded("Communication with the JamKazam network service timed out." + appendContextualStatement()); testedSuccessfully = true; @@ -256,7 +279,7 @@ configureStartButton(); postDiagnostic(); - if(success) { + if (success) { $self.triggerHandler(NETWORK_TEST_DONE) } else { @@ -268,6 +291,12 @@ return testSummary.attempts[testSummary.attempts.length - 1]; } + function primeTimedOut() { + logger.warn("backend never completed priming pump phase"); + scoring = false; + primeDeferred.reject(); + } + function backendTimedOut() { testSummary.final = {reason: 'backend_gone'} testFinished(); @@ -278,15 +307,31 @@ } function clearBackendGuard() { - if(backendGuardTimeout) { + if (backendGuardTimeout) { clearTimeout(backendGuardTimeout); backendGuardTimeout = null; } } + function clearPrimeGuard() { + if (primeGuardTimeout) { + clearTimeout(primeGuardTimeout); + primeGuardTimeout = null; + } + } + + function setPrimeGuard() { + clearPrimeGuard(); + primeGuardTimeout = setTimeout(function () { + primeTimedOut() + }, 2 * 1000); + } + function setBackendGuard() { clearBackendGuard(); - backendGuardTimeout = setTimeout(function(){backendTimedOut()}, (gon.ftue_network_test_duration + 1) * 1000); + backendGuardTimeout = setTimeout(function () { + backendTimedOut() + }, (gon.ftue_network_test_duration + 1) * 1000); } function attemptTestPass() { @@ -308,7 +353,7 @@ setBackendGuard(); - context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(), createTimeoutCallbackName(), + context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(false), createTimeoutCallbackName(false), NETWORK_TEST_TYPES.PktTest400LowLatency, gon.ftue_network_test_duration, numClientsToTest, @@ -316,53 +361,78 @@ } - function startNetworkTest(checkWireless) { + // you have to score a little to 'prime' the logic to know whether it's on wireless or not + function primePump() { + scoring = true; + primeDeferred = new $.Deferred(); - if(scoring) return false; + setPrimeGuard(); - if(checkWireless) { - // check if on Wifi 1st - var isWireless = context.jamClient.IsMyNetworkWireless(); - if(isWireless == -1) { - logger.warn("unable to determine if the user is on wireless or not for network test. skipping prompt.") - } - else if(isWireless == 1) { - context.JK.Banner.showAlert({buttons: [ - {name: 'RUN NETWORK TEST ANYWAY', click: function() {startNetworkTest(false)}}, - {name: 'CANCEL', click: function() {}}], - html: "

It appears that your computer is connected to your network using WiFi.

" + - "

We strongly advise against running the JamKazam application on a WiFi connection. " + - "We recommend using a wired Ethernet connection from your computer to your router. " + - "A WiFi connection is likely to cause significant issues in both latency and audio quality.

"}) - return false; - } - } + context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(true), createTimeoutCallbackName(true), + NETWORK_TEST_TYPES.PktTest400LowLatency, + 1, // minimum time needed to prime pump + 2, + PAYLOAD_SIZE); + + return primeDeferred; + } + + function prepareNetworkTest() { + + if (scoring) return false; + logger.info("starting network test"); resetTestState(); scoring = true; $self.triggerHandler(NETWORK_TEST_START); renderStartTest(); rest.getLatencyTester() - .done(function(response) { + .done(function (response) { // ensure there are no tests ongoing serverClientId = response.client_id; - testSummary.serverClientId = serverClientId; logger.info("beginning network test against client_id: " + serverClientId); - attemptTestPass(); + primePump() + .done(function () { + // check if on Wifi 1st + var isWireless = context.jamClient.IsMyNetworkWireless(); + if (isWireless == -1) { + logger.warn("unable to determine if the user is on wireless or not for network test. skipping prompt.") + } + else if (isWireless == 1) { + context.JK.Banner.showAlert({buttons: [ + {name: 'CANCEL', click: function () { + scoring = false; + configureStartButton(); + renderStopTest(); + $self.triggerHandler(NETWORK_TEST_CANCEL) + }}, + {name: 'RUN NETWORK TEST ANYWAY', click: function () { + attemptTestPass();; + }} + ], + html: "

It appears that your computer is connected to your network using WiFi.

" + + "

We strongly advise against running the JamKazam application on a WiFi connection. " + + "We recommend using a wired Ethernet connection from your computer to your router. " + + "A WiFi connection is likely to cause significant issues in both latency and audio quality.

"}) + } + }) + .fail(function () { + context.JK.Banner.showAlert("Network Test Failure", "Unable to determine internet connection type.") + }); }) - .fail(function(jqXHR) { - if(jqXHR.status == 404) { + .fail(function (jqXHR) { + if (jqXHR.status == 404) { // means there are no network testers available. // we have to skip this part of the UI testSummary.final = {reason: 'no_servers'} } else { - if(context.JK.isNetworkError(arguments)) { + if (context.JK.isNetworkError(arguments)) { testSummary.final = {reason: 'no_network'} } else { @@ -371,7 +441,7 @@ } testFinished(); }) - logger.info("starting network test"); + return false; } @@ -381,7 +451,7 @@ $currentScore.stop().data('showSubscore', showSubscore); - if(!showSubscore) { + if (!showSubscore) { $subscore.text(''); } @@ -390,7 +460,7 @@ width: width + '%' }, { step: function (now, fx) { - if(showSubscore) { + if (showSubscore) { var newWidth = ( 100 * parseFloat($currentScore.css('width')) / parseFloat($currentScore.parent().css('width')) ); $subscore.text((Math.round(newWidth * 10) / 10) + '%'); } @@ -399,12 +469,37 @@ ; } + function primePumpTimeout(data) { + clearPrimeGuard(); + scoring = false; + primeDeferred.reject(); + } + + function primePumpComplete(data) { + if (data.progress === true) { + // waiting... + logger.debug("pump prime progress report"); + setPrimeGuard(); + } + else { + clearPrimeGuard(); + // we could check for errors, but it's confusing to do so. we just want to let the backend figure out if + // the interface is wireless, or not + setTimeout(function () { + logger.debug("pump primed"); + scoring = false; + primeDeferred.resolve(); + }, 500); // give backend room to breath for timing/race issues + + } + } + function networkTestComplete(data) { var attempt = getCurrentAttempt(); function refineTest(up) { - if(up) { - if(numClientsToTest == gon.ftue_network_test_max_clients) { + if (up) { + if (numClientsToTest == gon.ftue_network_test_max_clients) { attempt.reason = "success"; testFinished(); } @@ -416,15 +511,15 @@ } else { // reduce numclients if we can - if(numClientsToTest == MINIMUM_ACCEPTABLE_SESSION_SIZE) { + if (numClientsToTest == MINIMUM_ACCEPTABLE_SESSION_SIZE) { // we are too low already. fail the user attempt.reason = "minimum_client_threshold"; testFinished(); } - else if(numClientsToTest > STARTING_NUM_CLIENTS) { + else if (numClientsToTest > STARTING_NUM_CLIENTS) { // this means we've gone up before... so don't go back down (i.e., creating a loop) attempt.reason = "success"; - testSummary.final = { reason:'success', num_clients: numClientsToTest - 1 } + testSummary.final = { reason: 'success', num_clients: numClientsToTest - 1 } testFinished(); } else { @@ -437,21 +532,21 @@ attempt.backend_data = data; - if(data.progress === true) { + if (data.progress === true) { setBackendGuard(); var animate = true; - if(data.downthroughput && data.upthroughput) { + if (data.downthroughput && data.upthroughput) { - if(data.downthroughput > 0 || data.upthroughput > 0) { + if (data.downthroughput > 0 || data.upthroughput > 0) { attempt.received_progress = true; animate = true; } - if(attempt.received_progress) { + if (attempt.received_progress) { // take the lower - var throughput= data.downthroughput < data.upthroughput ? data.downthroughput : data.upthroughput; + var throughput = data.downthroughput < data.upthroughput ? data.downthroughput : data.upthroughput; bandwidthSamples.push(data.upthroughput); @@ -463,36 +558,36 @@ clearBackendGuard(); logger.debug("network test pass success. data: ", data); - if(data.reason == "unreachable") { + if (data.reason == "unreachable") { // STUN logger.debug("network test: unreachable (STUN issue or similar)"); attempt.reason = data.reason; testFinished(); } - else if(data.reason == "no-transmit") { + else if (data.reason == "no-transmit") { logger.debug("network test: no-transmit (STUN issue or similar)"); attempt.reason = data.reason; testFinished(); } - else if(data.reason == "internal_error") { + else if (data.reason == "internal_error") { // oops logger.debug("network test: internal_error (client had a unexpected problem)"); attempt.reason = data.reason; testFinished(); } - else if(data.reason == "remote_peer_cant_test") { + else if (data.reason == "remote_peer_cant_test") { // old client logger.debug("network test: remote_peer_cant_test (old client)") attempt.reason = data.reason; testFinished(); } - else if(data.reason == "server_comm_timeout") { + else if (data.reason == "server_comm_timeout") { logger.debug("network test: server_comm_timeout (communication with server problem)") attempt.reason = data.reason; testFinished(); } else { - if(!data.downthroughput || !data.upthroughput) { + if (!data.downthroughput || !data.upthroughput) { // we have to assume this is bad. just not a reason we know about in code logger.debug("network test: no test data (unknown issue? " + data.reason + ")") attempt.reason = "invalid_response"; @@ -500,11 +595,11 @@ } else { // success... but we still have to verify if this data is within threshold - if(data.downthroughput < gon.ftue_packet_rate_treshold) { + if (data.downthroughput < gon.ftue_packet_rate_treshold) { logger.debug("network test: downthroughput too low. downthroughput: " + data.downthroughput + ", threshold: " + gon.ftue_packet_rate_treshold); refineTest(false); } - else if(data.upthroughput < gon.ftue_packet_rate_treshold) { + else if (data.upthroughput < gon.ftue_packet_rate_treshold) { logger.debug("network test: upthroughput too low. upthroughput: " + data.upthroughput + ", threshold: " + gon.ftue_packet_rate_treshold); refineTest(false); } @@ -538,7 +633,7 @@ } function configureStartButton() { - if(scoring) { + if (scoring) { $startNetworkTestBtn.text('NETWORK TEST RUNNING...').removeClass('button-orange').addClass('button-grey') } else { @@ -560,48 +655,75 @@ } function initializeVideoWatchButton() { - if(operatingSystem == "Win32") { + if (operatingSystem == "Win32") { $watchVideo.attr('href', 'https://www.youtube.com/watch?v=rhAdCVuwhBc'); } else { $watchVideo.attr('href', 'https://www.youtube.com/watch?v=0r1py0AYJ4Y'); } } + function initialize(_$step, _inGearWizard) { $step = _$step; inGearWizard = _inGearWizard; $startNetworkTestBtn = $step.find('.start-network-test'); - if($startNetworkTestBtn.length == 0) throw 'no start network test button found in network-test' + if ($startNetworkTestBtn.length == 0) throw 'no start network test button found in network-test' $testResults = $step.find('.network-test-results'); $testScore = $step.find('.network-test-score'); $testText = $step.find('.network-test-text'); $scoringBar = $step.find('.scoring-bar'); $goodMarker = $step.find('.good-marker'); - $goodLine =$step.find('.good-line'); + $goodLine = $step.find('.good-line'); $currentScore = $step.find('.current-score'); - $scoredClients= $step.find('.scored-clients'); + $scoredClients = $step.find('.scored-clients'); $subscore = $step.find('.subscore'); $watchVideo = $step.find('.watch-video'); - $startNetworkTestBtn.on('click', startNetworkTest); + $startNetworkTestBtn.on('click', function () { + prepareNetworkTest(); + }); operatingSystem = context.JK.GetOSAsString(); initializeVideoWatchButton(); + // if this network test is instantiated anywhere else than the gearWizard, or a dialog, then this will have to be expanded - if(inGearWizard) { - context.JK.HandleNetworkTestSuccessForGearWizard = function(data) { networkTestComplete(data)}; // pin to global for bridge callback - context.JK.HandleNetworkTestTimeoutForGearWizard = function(data) { networkTestTimeout(data)}; // pin to global for bridge callback + if (inGearWizard) { + context.JK.HandleNetworkTestSuccessForPumpPrimingGW = function (data) { + primePumpComplete(data) + }; + context.JK.HandleNetworkTestTimeoutForPumpPrimingGW = function (data) { + primePumpTimeout(data) + }; + context.JK.HandleNetworkTestSuccessForGearWizard = function (data) { + networkTestComplete(data) + }; // pin to global for bridge callback + context.JK.HandleNetworkTestTimeoutForGearWizard = function (data) { + networkTestTimeout(data) + }; // pin to global for bridge callback } else { - context.JK.HandleNetworkTestSuccessForDialog = function(data) { networkTestComplete(data)}; // pin to global for bridge callback - context.JK.HandleNetworkTestTimeoutForDialog = function(data) { networkTestTimeout(data)}; // pin to global for bridge callback + context.JK.HandleNetworkTestSuccessForPumpPrimingDialog = function (data) { + primePumpComplete(data) + }; + context.JK.HandleNetworkTestTimeoutForPumpPrimingDialog = function (data) { + primePumpTimeout(data) + }; + context.JK.HandleNetworkTestSuccessForDialog = function (data) { + networkTestComplete(data) + }; // pin to global for bridge callback + context.JK.HandleNetworkTestTimeoutForDialog = function (data) { + networkTestTimeout(data) + }; // pin to global for bridge callback } + } - this.isScoring = function () { return scoring; }; + this.isScoring = function () { + return scoring; + }; this.hasScoredNetworkSuccessfully = hasScoredNetworkSuccessfully; this.initialize = initialize; this.reset = reset; @@ -611,6 +733,7 @@ this.NETWORK_TEST_START = NETWORK_TEST_START; this.NETWORK_TEST_DONE = NETWORK_TEST_DONE; this.NETWORK_TEST_FAIL = NETWORK_TEST_FAIL; + this.NETWORK_TEST_CANCEL = NETWORK_TEST_CANCEL; return this; } diff --git a/web/app/assets/javascripts/rsvpSubmitDialog.js b/web/app/assets/javascripts/rsvpSubmitDialog.js index 9f7ea2e59..0b37a72f9 100644 --- a/web/app/assets/javascripts/rsvpSubmitDialog.js +++ b/web/app/assets/javascripts/rsvpSubmitDialog.js @@ -20,9 +20,13 @@ .done(function(response) { if (response) { $('.session-name', $screen).html(response.name); - $('.scheduled-start', $screen).html(response.scheduled_start); - if (response.recurring_mode !== null) { + var timestamp = new Date(response.scheduled_start).toDateString() + ', ' + + context.JK.formatUtcTime(new Date(response.scheduled_start), false); + + $('.scheduled-start', $screen).html(timestamp); + + if (response.recurring_mode !== null && response.recurring_mode === 'weekly') { $('.schedule-recurrence', $screen).html("Recurs " + response.recurring_mode + " on this day at this time"); } } diff --git a/web/app/assets/javascripts/scheduled_session.js b/web/app/assets/javascripts/scheduled_session.js index 8fc0b3353..7a1d1b557 100644 --- a/web/app/assets/javascripts/scheduled_session.js +++ b/web/app/assets/javascripts/scheduled_session.js @@ -98,7 +98,8 @@ context._.each(sessionList, function (session) { session.scheduled_start = new Date(session.scheduled_start).toDateString() + ', ' + - getFormattedTime(new Date(session.scheduled_start), false); + context.JK.formatUtcTime(new Date(session.scheduled_start), false); + var options = { id: session.id, name: session.name, @@ -311,7 +312,7 @@ var moveToFinish = function() { app.layout.closeDialog('confirm'); createSessionSettings.startDate = new Date(session.scheduled_start).toDateString(); - createSessionSettings.startTime = getFormattedTime(new Date(session.scheduled_start), false); + createSessionSettings.startTime = context.JK.formatUtcTime(new Date(session.scheduled_start), false); createSessionSettings.genresValues = session.genres; createSessionSettings.genres = [session.genre_id]; createSessionSettings.timezone.label = session.timezone_description; @@ -547,7 +548,7 @@ data.legal_terms = true; data.language = createSessionSettings.language.value; if (createSessionSettings.createType == 'quick-start' || createSessionSettings.createType == 'immediately') { - data.start = new Date().toDateString() + ' ' + getFormattedTime(new Date(), false); + data.start = new Date().toDateString() + ' ' + context.JK.formatUtcTime(new Date(), false); data.duration = "30"; } else if (createSessionSettings.createType == 'rsvp') { @@ -746,10 +747,10 @@ } if (step == STEP_SELECT_TYPE && createSessionSettings.createType == 'start-scheduled' && createSessionSettings.selectedSessionId == null) { - $btnNext.removeClass('button-orange').addClass('button-grey'); + $btnNext.addClass('disabled'); } else { - $btnNext.removeClass('button-grey').addClass('button-orange'); + $btnNext.removeClass('disabled'); } if (step == STEP_SELECT_CONFIRM) { @@ -770,7 +771,7 @@ event.preventDefault(); } - if ($(this).is('.button-grey')) return false; + if ($(this).is('.disabled')) return false; if ($.inArray(createSessionSettings.createType, ['start-scheduled', 'quick-start']) > -1) step = STEP_SELECT_TYPE; else @@ -806,7 +807,7 @@ if (event) { event.preventDefault(); } - if ($(this).is('.button-grey')) return false; + if ($(this).is('.disabled')) return false; if ($.inArray(createSessionSettings.createType, ['start-scheduled', 'quick-start']) > -1) step = STEP_SELECT_CONFIRM; @@ -856,30 +857,6 @@ } - function getFormattedTime(date, change) { - if (change) { - date.setMinutes(Math.ceil(date.getMinutes() / 30) * 30); - } - var h12h = date.getHours(); - var m12h = date.getMinutes(); - var ampm; - if (h12h >= 0 && h12h < 12) { - if (h12h === 0) { - h12h = 12; // 0 becomes 12 - } - ampm = "AM"; - } - else { - if (h12h > 12) { - h12h -= 12; // 13-23 becomes 1-11 - } - ampm = "PM"; - } - var timeString = ("00" + h12h).slice(-2) + ":" + ("00" + m12h).slice(-2) + " " + ampm; - - return timeString; - } - function toggleDate() { var selectedDate = new Date($('#session-start-date').val()); var currentDate = new Date(); @@ -889,7 +866,7 @@ currentDate.getMonth() == selectedDate.getMonth() && currentDate.getDate() == selectedDate.getDate()) { - var timeString = getFormattedTime(currentDate, true); + var timeString = context.JK.formatUtcTime(currentDate, true); startIndex = defaultTimeArray.indexOf(timeString); } $startTimeList.empty(); @@ -903,14 +880,11 @@ $startTimeList.val(createSessionSettings.startTime); toggleStartTime(); - - context.JK.dropdown($startTimeList); - context.JK.dropdown($endTimeList); } function toggleStartTime() { var valueSelected = $startTimeList.find('option:selected').val(); - var startIndex = defaultTimeArray.indexOf(valueSelected) + 1; + var startIndex = defaultTimeArray.indexOf(valueSelected) + 2; var $endTimeList = $('#end-time-list'); $endTimeList.empty(); @@ -923,9 +897,14 @@ $endTimeList.append($('')); } - if (createSessionSettings.endTime != defaultTimeArray[startIndex]) + if (createSessionSettings.endTime != defaultTimeArray[startIndex]) { createSessionSettings.endTime = defaultTimeArray[startIndex]; + } + $endTimeList.val(createSessionSettings.endTime); + + context.JK.dropdown($startTimeList); + context.JK.dropdown($endTimeList); } function initializeControls() { @@ -971,7 +950,7 @@ } if (error) { - app.notifyAlert("Error", "We're sorry, but we do not allow upload of that file type. Please upload only the file types listed in the Upload dialog box."); + app.notifyAlert("Error", "You can only upload images (.png .jpg .jpeg .gif), PDFs (.pdf), and XML files (.xml .mxl)."); $inputFiles.replaceWith($inputFiles.clone(true)); } else { @@ -1072,10 +1051,10 @@ var $btnNext = $('#create-session-buttons .btn-next'); if (step == STEP_SELECT_TYPE && createSessionSettings.createType == 'start-scheduled' && createSessionSettings.selectedSessionId == null) { - $btnNext.removeClass('button-orange').addClass('button-grey'); + $btnNext.addClass('disabled') } else { - $btnNext.removeClass('button-grey').addClass('button-orange'); + $btnNext.removeClass('disabled'); } toggleStepStatus(); diff --git a/web/app/assets/javascripts/sessionList.js b/web/app/assets/javascripts/sessionList.js index f0cb814c0..116d30200 100644 --- a/web/app/assets/javascripts/sessionList.js +++ b/web/app/assets/javascripts/sessionList.js @@ -184,6 +184,12 @@ } var sessionVals = buildSessionObject(session, notationFileHtml, rsvpUsersHtml, openSlotsHtml, latencyHtml); + + // format scheduled start time + sessionVals.scheduled_start = new Date(session.scheduled_start).toDateString() + ', ' + + context.JK.formatUtcTime(new Date(session.scheduled_start), false);// + '-' + + //context.JK.formatUtcTime(new Date(session.scheduled_start + session.scheduled_duration), false); + sessionVals.rsvp_link_display_style = showRsvpLink ? "block" : "none"; var row = context.JK.fillTemplate($inactiveSessionTemplate.html(), sessionVals); @@ -298,8 +304,6 @@ latencyStyle = LATENCY.UNKNOWN.style; } else { - latencyUsers++; - totalLatency += latency; if (latency <= LATENCY.GOOD.max) { latencyDescription = LATENCY.GOOD.description; latencyStyle = LATENCY.GOOD.style; diff --git a/web/app/assets/javascripts/shutdownDialog.js b/web/app/assets/javascripts/shutdownDialog.js new file mode 100644 index 000000000..94aea13f4 --- /dev/null +++ b/web/app/assets/javascripts/shutdownDialog.js @@ -0,0 +1,36 @@ +(function (context, $) { + + "use strict"; + + context.JK = context.JK || {}; + + context.JK.ShutdownDialog = function (app) { + var logger = context.JK.logger; + + function show() { + context.JK.Banner.showAlert( + { title: "Close JamKazam Application", + buttons: [ + {name: 'Completely Shut Down the App', click: function() {context.jamClient.ShutdownApplication()}}, + {name: 'Let App Run in Background', click: function() {context.jamClient.ShutdownApplication()}} + ], + html: $('#template-shutdown-prompt').html()}); + } + + function initialize() { + //context.jamClient.RegisterQuitCallback("window.JK.ShutdownDialogCallback"); + } + + function quitCallback(options) { + logger.debug("oh hai"); + show(); + } + + this.initialize = initialize; + + context.JK.ShutdownDialogCallback = quitCallback; + + return this; + + } +})(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/user_dropdown.js b/web/app/assets/javascripts/user_dropdown.js index d8868a058..656ce71ab 100644 --- a/web/app/assets/javascripts/user_dropdown.js +++ b/web/app/assets/javascripts/user_dropdown.js @@ -85,7 +85,11 @@ function handleWhatsNext(userProfile) { if (notYetShownWhatsNext && gon.isNativeClient && userProfile.show_whats_next) { notYetShownWhatsNext = false; - app.layout.showDialog('whatsNext'); + console.log("window.location.pathname", window.location.pathname, gon.client_path, window.location.pathname.indexOf(gon.client_url)); + if(window.location.pathname.indexOf(gon.client_path) == 0) { + app.layout.showDialog('whatsNext'); + } + } } diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js index 592c06b06..6699aa73a 100644 --- a/web/app/assets/javascripts/utils.js +++ b/web/app/assets/javascripts/utils.js @@ -11,6 +11,7 @@ var ALERT_NAMES = context.JK.ALERT_NAMES; var ALERT_TYPES = context.JK.ALERT_TYPES; + var EVENTS = context.JK.EVENTS; var days = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); @@ -520,6 +521,30 @@ return date.toLocaleTimeString(); } + context.JK.formatUtcTime = function(date, change) { + if (change) { + date.setMinutes(Math.ceil(date.getMinutes() / 30) * 30); + } + var h12h = date.getHours(); + var m12h = date.getMinutes(); + var ampm; + if (h12h >= 0 && h12h < 12) { + if (h12h === 0) { + h12h = 12; // 0 becomes 12 + } + ampm = "AM"; + } + else { + if (h12h > 12) { + h12h -= 12; // 13-23 becomes 1-11 + } + ampm = "PM"; + } + var timeString = ("00" + h12h).slice(-2) + ":" + ("00" + m12h).slice(-2) + " " + ampm; + + return timeString; + } + context.JK.prettyPrintElements = function ($elements) { $.each($elements, function (index, item) { var $item = $(item); @@ -556,6 +581,10 @@ return $item; } + // returns: + // * Win32 + // * MacOSX + // * Unix context.JK.GetOSAsString = function() { if(!os) { os = context.jamClient.GetOSAsString(); @@ -938,6 +967,12 @@ if(!gon.isNativeClient) { logger.debug("guarding against normal browser on screen thaht requires native client") app.layout.showDialog('launch-app-dialog', args) + .one(EVENTS.DIALOG_CLOSED, function() { + if(args && args.goHome) { + window.location = '/client#/home'; + } + }) + return false; } return true; diff --git a/web/app/assets/javascripts/web/session_info.js b/web/app/assets/javascripts/web/session_info.js index fba2b7d55..f26e1e878 100644 --- a/web/app/assets/javascripts/web/session_info.js +++ b/web/app/assets/javascripts/web/session_info.js @@ -4,7 +4,7 @@ context.JK = context.JK || {}; - context.JK.ShowSessionInfo = function(app) { + context.JK.ShowSessionInfo = function(app, musicSessionId) { var logger = context.JK.logger; var rest = JK.Rest(); var ui = new context.JK.UIHelper(app); @@ -18,7 +18,7 @@ UNKNOWN: {description: "UNKNOWN", style: "latency-grey", min: -2, max: -2} }; - function addComment(musicSessionId) { + function addComment() { var comment = $("#txtSessionInfoComment").val(); if ($.trim(comment).length > 0) { rest.addSessionInfoComment(musicSessionId, comment) @@ -64,7 +64,66 @@ }); } - function initialize(musicSessionId) { + // this is done post-page load to allow websocket connection to be established + function addLatencyDetails() { + rest.getSessionHistory(musicSessionId) + .done(function(session) { + if (session.approved_rsvps && session.approved_rsvps.length > 0) { + // loop through each record in RSVPs, which has already been rendered, and extract + // the user ID + $('.rsvp-details').each(function(index) { + var $user = $(this).find('div[hoveraction="musician"]'); + var userId = $user.attr('user-id'); + var latency = null; + var latencyStyle = LATENCY.UNKNOWN.style; + var latencyDescription = LATENCY.UNKNOWN.description; + + // default current user to GOOD + if (userId === context.JK.currentUserId) { + latencyStyle = LATENCY.GOOD.style; + latencyDescription = LATENCY.GOOD.description; + } + else { + // find the corresponding user in the API response payload + for (var i=0; i < session.approved_rsvps.length; i++) { + if (session.approved_rsvps.id === userId) { + latency = session.approved_rsvps[i].latency; + break; + } + } + if (latency) { + if (latency <= LATENCY.GOOD.max) { + latencyDescription = LATENCY.GOOD.description; + latencyStyle = LATENCY.GOOD.style; + } + else if (latency > LATENCY.MEDIUM.min && latency <= LATENCY.MEDIUM.max) { + latencyDescription = LATENCY.MEDIUM.description; + latencyStyle = LATENCY.MEDIUM.style; + } + else { + latencyDescription = LATENCY.POOR.description; + latencyStyle = LATENCY.POOR.style; + } + } + else { + latencyStyle = LATENCY.UNKNOWN.style; + latencyDescription = LATENCY.UNKNOWN.description; + } + } + + // add the latency details for this user to the UI + var latencyHtml = context.JK.fillTemplate($('#template-latency-detail').html(), { + latencyStyle: latencyStyle, + latencyDescription: latencyDescription + }); + + $(this).find('.latency-tags').append(latencyHtml); + }); + } + }); + } + + function initialize() { registerScheduledSessionComment(); var $parent = $('.landing-sidebar'); @@ -134,12 +193,14 @@ $("#btnPostComment").click(function(e) { if ($.trim($("#txtSessionInfoComment").val()).length > 0) { - addComment(musicSessionId); + addComment(); $("#txtSessionComment").val(''); $("#txtSessionComment").blur(); } }); + addLatencyDetails(); + $(document).on("rsvpSubmitEvent", function() { location.reload(); }); diff --git a/web/app/assets/javascripts/web/signin.js b/web/app/assets/javascripts/web/signin.js new file mode 100644 index 000000000..d01d2c200 --- /dev/null +++ b/web/app/assets/javascripts/web/signin.js @@ -0,0 +1,39 @@ +(function (context, $) { + + "use strict"; + + context.JK = context.JK || {}; + + var $signin; + var $signinRoot; + var $signupRoot; + + var rest = context.JK.Rest(); + var logger = context.JK.logger; + var EVENTS = context.JK.EVENTS; + + function initialize() { + + $signinRoot = $('.signin-common'); + $signupRoot = $('.signup-common'); + + var signinHelper = new context.JK.SigninHelper(context.JK.app); + $(signinHelper).on(EVENTS.SHOW_SIGNUP, function() { + $signinRoot.hide(); + $signupRoot.show(); + }); + signinHelper.initialize($signinRoot, false); + + var signupHelper = new context.JK.SignupHelper(context.JK.app); + $(signupHelper).on(EVENTS.SHOW_SIGNIN, function() { + $signupRoot.hide(); + $signinRoot.show(); + }); + signupHelper.initialize($signupRoot); + + $signinRoot.find('input[name="session[email]"]').focus(); + } + + context.JK.SigninPage = initialize; + +})(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/web/signinDialog.js b/web/app/assets/javascripts/web/signinDialog.js index e93d4492f..a76d649d5 100644 --- a/web/app/assets/javascripts/web/signinDialog.js +++ b/web/app/assets/javascripts/web/signinDialog.js @@ -5,78 +5,21 @@ context.JK = context.JK || {}; context.JK.SigninDialog = function(app) { + var EVENTS = context.JK.EVENTS; var logger = context.JK.logger; var rest = context.JK.Rest(); var dialogId = '#signin-dialog'; + var $dialog = null; + var signinHelper = null; - function reset() { - $(dialogId + ' #signin-form').removeClass('login-error') - - $(dialogId + ' input[name=email]').val(''); - $(dialogId + ' input[name=password]').val(''); - $(dialogId + ' input[name=remember_me]').attr('checked', 'checked') - } - - function login() { - var email = $(dialogId + ' input[name=email]').val(); - var password = $(dialogId + ' input[name=password]').val(); - var rememberMe = $(dialogId + ' input[name=remember_me]').is(':checked') - - rest.login({email: email, password: password, remember_me: rememberMe}) - .done(function() { - app.layout.closeDialog('signin-dialog') - - var redirectTo = $.QueryString['redirect-to']; - if(redirectTo) { - logger.debug("redirectTo:" + redirectTo); - window.location.href = redirectTo; - } - else { - logger.debug("default post-login path"); - window.location.href = '/client' - } - }) - .fail(function(jqXHR) { - if(jqXHR.status == 422) { - $(dialogId + ' #signin-form').addClass('login-error') - } - else { - app.notifyServerError(jqXHR, "Unable to log in") - } - }) - } - - function events() { - $(dialogId + ' .signin-cancel').click(function(e) { - app.layout.closeDialog('signin-dialog'); - e.stopPropagation(); - return false; - }); - - $(dialogId + ' #signin-form').submit(function(e) { - login(); - return false; - }); - - $(dialogId + ' .signin-submit').click(function(e) { - login(); - return false; - }); - - $(dialogId + ' .show-signup-dialog').click(function(e) { - app.layout.closeDialog('signin-dialog') - app.layout.showDialog('signup-dialog') - return false; - }) - } function beforeShow() { logger.debug("showing login form") - reset(); + signinHelper.reset(); } function afterShow() { - $(dialogId + ' input[name=email]').focus(); + $dialog.find('input[name="session[email]"]').focus(); } function afterHide() { @@ -93,10 +36,16 @@ app.bindDialog('signin-dialog', dialogBindings); - events(); + $dialog = $(dialogId); + + signinHelper = new context.JK.SigninHelper(app); + $(signinHelper).on(EVENTS.SHOW_SIGNUP, function() { + app.layout.closeDialog('signin-dialog') + app.layout.showDialog('signup-dialog') + }) + signinHelper.initialize($dialog, true); } this.initialize = initialize; - } })(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/web/signin_helper.js b/web/app/assets/javascripts/web/signin_helper.js new file mode 100644 index 000000000..76a5dfaab --- /dev/null +++ b/web/app/assets/javascripts/web/signin_helper.js @@ -0,0 +1,115 @@ +(function(context,$) { + + "use strict"; + + context.JK = context.JK || {}; + + context.JK.SigninHelper = function(app) { + + if(!app) throw "no app defined"; + + var logger = context.JK.logger; + var rest = context.JK.Rest(); + var $self = $(this); + var $parent = null; + var $signinBtn = null; + var $signinForm = null; + var $signinCancelBtn = null; + var $email = null; + var $password = null; + var $rememberMe = null; + var useAjax = false; + var EVENTS = context.JK.EVENTS; + + function reset() { + $signinForm.removeClass('login-error') + + $email.val(''); + $password.val(''); + $rememberMe.attr('checked', 'checked') + } + + function login() { + var email = $email.val(); + var password = $password.val(); + var rememberMe = $rememberMe.is(':checked') + + reset(); + + $signinBtn.text('TRYING...'); + + rest.login({email: email, password: password, remember_me: rememberMe}) + .done(function() { + //app.layout.closeDialog('signin-dialog') + + var redirectTo = $.QueryString['redirect-to']; + if(redirectTo) { + logger.debug("redirectTo:" + redirectTo); + window.location.href = redirectTo; + } + else { + logger.debug("default post-login path"); + window.location.href = '/client' + } + }) + .fail(function(jqXHR) { + if(jqXHR.status == 422) { + $signinForm.addClass('login-error') + } + else { + app.notifyServerError(jqXHR, "Unable to log in") + } + }) + .always(function() { + $signinBtn.text('SIGN IN') + }) + } + + + function events() { + $signinCancelBtn.click(function(e) { + app.layout.closeDialog('signin-dialog'); + e.stopPropagation(); + return false; + }); + + if(useAjax) { + $signinForm.submit(function(e) { + login(); + return false; + }); + + $signinBtn.click(function(e) { + login(); + return false; + }); + } + + + $parent.find('.show-signup-dialog').click(function(e) { + $self.triggerHandler(EVENTS.SHOW_SIGNUP); + return false; + }) + } + + function initialize(_$parent, _useAjax){ + $parent = _$parent; + useAjax = _useAjax; + + $signinBtn = $parent.find('.signin-submit') + $signinForm = $parent.find('.signin-form') + $signinCancelBtn = $parent.find('.signin-cancel') + $email = $parent.find('input[name="session[email]"]'); + $password = $parent.find('input[name="session[password]"]'); + $rememberMe = $parent.find('input[name="user[remember_me]"]'); + + if($signinForm.length == 0) throw "no signin form found"; + events(); + } + + this.initialize = initialize; + this.reset = reset; + + return this; + } +})(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/web/signupDialog.js b/web/app/assets/javascripts/web/signupDialog.js index fc126cb57..cc69ccae0 100644 --- a/web/app/assets/javascripts/web/signupDialog.js +++ b/web/app/assets/javascripts/web/signupDialog.js @@ -1,49 +1,43 @@ -(function(context,$) { +(function (context, $) { - "use strict"; + "use strict"; - context.JK = context.JK || {}; + context.JK = context.JK || {}; - context.JK.SignupDialog = function(app) { - var logger = context.JK.logger; - var rest = context.JK.Rest(); - var dialogId = '#signup-dialog'; - - function events() { - $(dialogId + ' .signup-cancel').click(function(e) { - app.layout.closeDialog('signup-dialog'); - e.stopPropagation(); - return false; - }); - - $(dialogId + ' .show-signin-dialog').click(function(e) { - app.layout.closeDialog('signup-dialog') - app.layout.showDialog('signin-dialog') - return false; - }) - } - - function beforeShow() { - - } - - function afterHide() { - - } - - function initialize(){ - - var dialogBindings = { - 'beforeShow' : beforeShow, - 'afterHide': afterHide - }; - - app.bindDialog('signup-dialog', dialogBindings); - - events(); - } - - this.initialize = initialize; + context.JK.SignupDialog = function (app) { + var logger = context.JK.logger; + var rest = context.JK.Rest(); + var dialogId = '#signup-dialog'; + var $dialog = null; + var signupHelper = null; + var EVENTS = context.JK.EVENTS; + function beforeShow() { } + + function afterHide() { + } + + function initialize() { + + var dialogBindings = { + 'beforeShow': beforeShow, + 'afterHide': afterHide + }; + + app.bindDialog('signup-dialog', dialogBindings); + + $dialog = $(dialogId); + + signupHelper = new context.JK.SignupHelper(app); + $(signupHelper).on(EVENTS.SHOW_SIGNIN, function () { + app.layout.closeDialog('signup-dialog') + app.layout.showDialog('signin-dialog') + }) + signupHelper.initialize($dialog); + } + + this.initialize = initialize; + + } })(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/web/signup_helper.js b/web/app/assets/javascripts/web/signup_helper.js new file mode 100644 index 000000000..2bf34b662 --- /dev/null +++ b/web/app/assets/javascripts/web/signup_helper.js @@ -0,0 +1,47 @@ +(function(context,$) { + + "use strict"; + + context.JK = context.JK || {}; + + context.JK.SignupHelper = function(app) { + + if(!app) throw "no app defined"; + + var logger = context.JK.logger; + var rest = context.JK.Rest(); + var $self = $(this); + var $parent = null; + var $signupCancel = null; + var $showSigninDialog = null; + var EVENTS = context.JK.EVENTS; + + function events() { + $parent.find('.signup-cancel').click(function(e) { + app.layout.closeDialog('signup-dialog'); + e.stopPropagation(); + return false; + }); + + $parent.find('.show-signin-dialog').click(function(e) { + $self.triggerHandler(EVENTS.SHOW_SIGNIN); + return false; + }) + } + + function initialize(_$parent){ + $parent = _$parent; + + $showSigninDialog = $parent.find('.show-signin-dialog') + $signupCancel = $parent.find('.signup-cancel') + + if($showSigninDialog.length == 0) throw "no $showSigninDialog found"; + if($signupCancel.length == 0) throw "no $signupCancel form found"; + events(); + } + + this.initialize = initialize; + + return this; + } +})(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/web/web.js b/web/app/assets/javascripts/web/web.js index 4112c4d99..a97905224 100644 --- a/web/app/assets/javascripts/web/web.js +++ b/web/app/assets/javascripts/web/web.js @@ -21,7 +21,9 @@ //= require globals //= require AAB_message_factory //= require facebook_helper +//= require web/signup_helper //= require web/signupDialog +//= require web/signin_helper //= require web/signinDialog //= require web/videoDialog //= require invitationDialog diff --git a/web/app/assets/javascripts/web/welcome.js b/web/app/assets/javascripts/web/welcome.js index 2403fa2dc..dd570b763 100644 --- a/web/app/assets/javascripts/web/welcome.js +++ b/web/app/assets/javascripts/web/welcome.js @@ -18,7 +18,7 @@ return false; }); - $('#signin').click(function (e) { + $('#signin.signin').click(function (e) { if (context.JK.currentUserId) { rest.getUserDetail({id:context.JK.currentUserId}) .done(function () { @@ -73,6 +73,12 @@ } }); } + + $('.like-link').click(function() { + var like_site = $(this).data('site'); + JK.GA.trackJKSocial(JK.GA.Categories.jkLike, like_site, JK.clientType()); + window.open("/endorse/0/"+like_site, '_blank'); + }); } context.JK.WelcomePage = initialize; diff --git a/web/app/assets/javascripts/wizard/gear/gear_wizard.js b/web/app/assets/javascripts/wizard/gear/gear_wizard.js index 2a052d2a9..74ecf668c 100644 --- a/web/app/assets/javascripts/wizard/gear/gear_wizard.js +++ b/web/app/assets/javascripts/wizard/gear/gear_wizard.js @@ -12,6 +12,7 @@ var $wizardSteps = null; var $templateSteps = null; var loopbackWizard = null; + var inputs = null; var self = this; @@ -42,6 +43,8 @@ } function newSession() { + inputs = null; + context._.each(STEPS, function(stepInfo, stepNumber) { if(stepInfo.newSession) { stepInfo.newSession.call(stepInfo); @@ -171,6 +174,13 @@ wizard.setBackState(enabled); } + function setChosenInputs(_inputs) { + inputs = _inputs; + } + + function getChosenInputs() { + return inputs; + } function initialize(_loopbackWizard) { @@ -190,20 +200,23 @@ $wizardSteps = $dialog.find('.wizard-step'); $templateSteps = $('#template-ftuesteps'); - stepUnderstandGear.initialize($wizardSteps.filter($('[layout-wizard-step=0]'))); - stepSelectGear.initialize($wizardSteps.filter($('[layout-wizard-step=1]'))); - stepConfigureTracks.initialize($wizardSteps.filter($('[layout-wizard-step=2]'))); - stepConfigureVoiceChat.initialize($wizardSteps.filter($('[layout-wizard-step=3]'))); - stepDirectMonitoring.initialize($wizardSteps.filter($('[layout-wizard-step=4]'))); - stepNetworkTest.initialize($wizardSteps.filter($('[layout-wizard-step=5]'))); - stepSuccess.initialize($wizardSteps.filter($('[layout-wizard-step=6]'))); - wizard = new context.JK.Wizard(app); + + stepUnderstandGear.initialize($wizardSteps.filter($('[layout-wizard-step=0]')), self); + stepSelectGear.initialize($wizardSteps.filter($('[layout-wizard-step=1]')), self); + stepConfigureTracks.initialize($wizardSteps.filter($('[layout-wizard-step=2]')), self); + stepConfigureVoiceChat.initialize($wizardSteps.filter($('[layout-wizard-step=3]')), self); + stepDirectMonitoring.initialize($wizardSteps.filter($('[layout-wizard-step=4]')), self); + stepNetworkTest.initialize($wizardSteps.filter($('[layout-wizard-step=5]')), self); + stepSuccess.initialize($wizardSteps.filter($('[layout-wizard-step=6]')), self); + wizard.initialize($dialog, $wizardSteps, STEPS); events(); } + this.setChosenInputs = setChosenInputs; // so step 2 can 'talk' to step 3 + this.getChosenInputs = getChosenInputs; this.setNextState = setNextState; this.setBackState = setBackState; this.initialize = initialize; diff --git a/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js b/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js index 495bf07e3..81c330620 100644 --- a/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js +++ b/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js @@ -14,6 +14,11 @@ var $step = null; var successfullyAssignedOnce = false; + var wizard = null; + + function handleHelp() { + return "https://jamkazam.desk.com/customer/portal/articles/1599961-first-time-setup---step-3---configure-tracks"; + } function handleNext() { var saved = configureTracksHelper.trySave(); @@ -33,15 +38,17 @@ function beforeShow() { var forceInputsToUnassigned = !successfullyAssignedOnce; - configureTracksHelper.reset(forceInputsToUnassigned) + configureTracksHelper.reset(forceInputsToUnassigned, wizard.getChosenInputs()) } - function initialize(_$step) { + function initialize(_$step, _wizard) { $step = _$step; + wizard = _wizard; configureTracksHelper.initialize($step); } + this.handleHelp = handleHelp; this.newSession = newSession; this.handleNext = handleNext; this.beforeShow = beforeShow; diff --git a/web/app/assets/javascripts/wizard/gear/step_configure_voice_chat.js b/web/app/assets/javascripts/wizard/gear/step_configure_voice_chat.js index 98e189dea..00d00e484 100644 --- a/web/app/assets/javascripts/wizard/gear/step_configure_voice_chat.js +++ b/web/app/assets/javascripts/wizard/gear/step_configure_voice_chat.js @@ -20,6 +20,10 @@ var voiceChatHelper = new context.JK.VoiceChatHelper(app); var firstTimeShown = false; + function handleHelp() { + return "https://jamkazam.desk.com/customer/portal/articles/1599963-first-time-setup---step-4---configure-voice-chat"; + } + function newSession() { firstTimeShown = true; } @@ -47,6 +51,7 @@ } + this.handleHelp = handleHelp; this.handleNext = handleNext; this.newSession = newSession; this.beforeShow = beforeShow; diff --git a/web/app/assets/javascripts/wizard/gear/step_direct_monitoring.js b/web/app/assets/javascripts/wizard/gear/step_direct_monitoring.js index aeb79bec3..f76e0abaf 100644 --- a/web/app/assets/javascripts/wizard/gear/step_direct_monitoring.js +++ b/web/app/assets/javascripts/wizard/gear/step_direct_monitoring.js @@ -49,6 +49,10 @@ } } + function handleHelp() { + return "https://jamkazam.desk.com/customer/portal/articles/1599967-first-time-setup---step-5---turn-off-direct-monitoring"; + } + function handleNext() { } @@ -87,6 +91,7 @@ $directMonitoringBtn.on('click', togglePlay); } + this.handleHelp = handleHelp; this.handleNext = handleNext; this.newSession = newSession; this.beforeShow = beforeShow; diff --git a/web/app/assets/javascripts/wizard/gear/step_network_test.js b/web/app/assets/javascripts/wizard/gear/step_network_test.js index 4b8df386e..b82a622ae 100644 --- a/web/app/assets/javascripts/wizard/gear/step_network_test.js +++ b/web/app/assets/javascripts/wizard/gear/step_network_test.js @@ -23,6 +23,10 @@ updateButtons(); } + function networkTestCancel() { + updateButtons(); + } + function networkTestStart() { updateButtons(); } @@ -39,6 +43,10 @@ dialog.setBackState(!networkTest.isScoring()); } + function handleHelp() { + return "https://jamkazam.desk.com/customer/portal/articles/1599969-first-time-setup---step-6---test-your-network"; + } + function newSession() { networkTest.reset(); updateButtons(); @@ -59,9 +67,11 @@ $(networkTest) .on(networkTest.NETWORK_TEST_DONE, networkTestDone) .on(networkTest.NETWORK_TEST_FAIL, networkTestFail) + .on(networkTest.NETWORK_TEST_CANCEL, networkTestCancel) .on(networkTest.NETWORK_TEST_START, networkTestStart) } + this.handleHelp = handleHelp; this.newSession = newSession; this.beforeHide = beforeHide; this.beforeShow = beforeShow; diff --git a/web/app/assets/javascripts/wizard/gear/step_select_gear.js b/web/app/assets/javascripts/wizard/gear/step_select_gear.js index d0c5b10a2..00657da1f 100644 --- a/web/app/assets/javascripts/wizard/gear/step_select_gear.js +++ b/web/app/assets/javascripts/wizard/gear/step_select_gear.js @@ -19,6 +19,7 @@ var frameBuffers = new context.JK.FrameBuffers(app); var gearTest = new context.JK.GearTest(app); var loopbackShowing = false; + var wizard = null; // the goal of lastFailureAnalytics and trackedPass are to send only a single AudioTest 'Pass' or 'Failed' event, per FTUE wizard open/close var lastFailureAnalytics = {}; @@ -795,49 +796,59 @@ initializeNextButtonState(); } + function handleHelp() { + if(operatingSystem == "Win32") { + return "https://jamkazam.desk.com/customer/portal/articles/1599818-first-time-setup---step-2---select-and-test-audio-gear---windows-"; + } + else { + return "https://jamkazam.desk.com/customer/portal/articles/1599845-first-time-setup---step-2---select-and-test-audio-gear---mac"; + } + } + function handleNext() { + var $assignedInputs = $inputChannels.find('input[type="checkbox"]:checked'); + var $assignedOutputs = $outputChannels.find('input[type="checkbox"]:checked'); + + var errors = []; + if($assignedInputs.length == 0) { + errors.push("There must be at least one selected input ports."); + } + if($assignedInputs.length > 12) { + errors.push("There can only be up to 12 selected inputs ports."); + } + if($assignedOutputs.length != 2) { + errors.push("There must be exactly 2 selected output ports."); + } + var $errors = $(''); + context._.each(errors, function(error) { + $errors.append('
  • ' + error + '
  • '); + }); + + if(errors.length > 0) { + context.JK.Banner.showAlert({html:$errors}); + return false; + } + if(!savedProfile) { - var $assignedInputs = $inputChannels.find('input[type="checkbox"]:checked'); - var $assignedOutputs = $outputChannels.find('input[type="checkbox"]:checked'); - - var errors = []; - if($assignedInputs.length == 0) { - errors.push("There must be at least one selected input ports."); - } - if($assignedInputs.length > 12) { - errors.push("There can only be up to 12 selected inputs ports."); - } - if($assignedOutputs.length != 2) { - errors.push("There must be exactly 2 selected output ports."); - } - var $errors = $(''); - context._.each(errors, function(error) { - $errors.append('
  • ' + error + '
  • '); - }); - - if(errors.length > 0) { - context.JK.Banner.showAlert({html:$errors}); + context.jamClient.FTUESetMusicProfileName(gearUtils.createProfileName(selectedDeviceInfo)); + var result = context.jamClient.FTUESave(true); + if(result && result != "") { + // failed + logger.warn("unable to FTUESave(true). reason:" + result); + context.JK.Banner.alertSupportedNeeded("Unable to persist the audio profile. " + result); return false; } else { - context.jamClient.FTUESetMusicProfileName(gearUtils.createProfileName(selectedDeviceInfo)); - var result = context.jamClient.FTUESave(true); - if(result && result != "") { - // failed - logger.warn("unable to FTUESave(true). reason:" + result); - context.JK.Banner.alertSupportedNeeded("Unable to persist the audio profile. " + result); - return false; - } - else { - context.JK.GA.trackAudioTestCompletion(context.JK.detectOS()); - trackedPass = true; - lastFailureAnalytics = null; - savedProfile = true; - return true; - } + context.JK.GA.trackAudioTestCompletion(context.JK.detectOS()); + trackedPass = true; + lastFailureAnalytics = null; + savedProfile = true; } } + // keep the shared state between step 2 and step 3 up-to-date + wizard.setChosenInputs(context._.map($assignedInputs, function(input) { return $(input).attr('data-id') })); + return true; } function onFocus() { @@ -883,8 +894,9 @@ updateDialogForCurrentDevices(); } - function initialize(_$step) { + function initialize(_$step, _wizard) { $step = _$step; + wizard = _wizard; $watchVideoInput = $step.find('.watch-video.audio-input'); $watchVideoOutput = $step.find('.watch-video.audio-output'); @@ -919,6 +931,7 @@ this.getLastAudioTestFailAnalytics = getLastAudioTestFailAnalytics; this.handleNext = handleNext; this.newSession = newSession; + this.handleHelp = handleHelp; this.beforeShow = beforeShow; this.beforeHide = beforeHide; this.beforeWizardShow = beforeWizardShow; diff --git a/web/app/assets/javascripts/wizard/gear/step_understand_gear.js b/web/app/assets/javascripts/wizard/gear/step_understand_gear.js index 648b741dd..605089717 100644 --- a/web/app/assets/javascripts/wizard/gear/step_understand_gear.js +++ b/web/app/assets/javascripts/wizard/gear/step_understand_gear.js @@ -8,6 +8,10 @@ var $step = null; var operatingSystem; + function handleHelp() { + return "https://jamkazam.desk.com/customer/portal/articles/1599817-first-time-setup---step-1"; + } + function beforeShow() { var $watchVideo = $step.find('.watch-video'); var videoUrl = 'https://www.youtube.com/watch?v=NiELWY769Tw'; @@ -23,6 +27,7 @@ operatingSystem = context.JK.GetOSAsString(); } + this.handleHelp = handleHelp; this.beforeShow = beforeShow; this.initialize = initialize; diff --git a/web/app/assets/javascripts/wizard/wizard.js b/web/app/assets/javascripts/wizard/wizard.js index 3d8bf4307..e3a6eaed3 100644 --- a/web/app/assets/javascripts/wizard/wizard.js +++ b/web/app/assets/javascripts/wizard/wizard.js @@ -76,6 +76,20 @@ return false; } + function help() { + if ($(this).is('.disabled')) return false; + + var stepInfo = STEPS[step]; + if(stepInfo.handleHelp) { + var result = stepInfo.handleHelp.call(stepInfo); + if(!result) {return false;} + + context.JK.popExternalLink(result); + } + + return false; + } + function moveToStep() { var $nextWizardStep = $wizardSteps.filter($('[layout-wizard-step=' + step + ']')); @@ -119,6 +133,7 @@ $btnCancel.hide(); } + $btnHelp.on('click', help); $btnNext.on('click', next); $btnBack.on('click', back); $btnClose.on('click', function() {$self.triggerHandler('wizard_close'); return false;}); diff --git a/web/app/assets/stylesheets/client/client.css b/web/app/assets/stylesheets/client/client.css index 0fe1feba3..c3e6145f4 100644 --- a/web/app/assets/stylesheets/client/client.css +++ b/web/app/assets/stylesheets/client/client.css @@ -9,6 +9,7 @@ * compiled file, but it's generally better to create a new file per style scope. * *= require_self + *= require jquery.ui.datepicker *= require ./ie *= require jquery.bt *= require easydropdown diff --git a/web/app/assets/stylesheets/client/createSession.css.scss b/web/app/assets/stylesheets/client/createSession.css.scss index 29f0e6a2f..fcb8ac92f 100644 --- a/web/app/assets/stylesheets/client/createSession.css.scss +++ b/web/app/assets/stylesheets/client/createSession.css.scss @@ -67,7 +67,7 @@ } .session-wrapper { - padding: 10px 35px 5px 35px; + padding: 10px 35px 0 35px; white-space: initial; h3 { @@ -140,7 +140,7 @@ .btn-select-files { margin-top: 10px; - margin-left:0; + margin-left:2px; width:110px; @include border_box_sizing; } @@ -287,11 +287,6 @@ #session-step-5 { } - .session-buttons { - padding-right: 30px; - padding-bottom: 20px; - } - #session-name-disp { font-style:italic; } @@ -319,10 +314,42 @@ margin-bottom:20px; } - #create-session-buttons { - margin-top:10px; + + .session-buttons { + position:absolute; + width:100%; + bottom:15px; + + .left-buttons { + position:absolute; + left:29px; + bottom:0; + } + + .right-buttons { + position:absolute; + right:29px; + bottom:0; + } + + #create-session-buttons { + position: absolute; + bottom: 0; + width:100%; + @include border_box_sizing; + padding-right:45px; + padding-bottom:15px; + + .btn-help { + float:left; + } + } + } + + + .error-text { margin:2px 0 0 2em; @@ -346,6 +373,10 @@ } #create-session-form { + position:relative; + padding-bottom:50px; + @include border_box_sizing; + min-height:100%; .musician_access .dropdown-wrapper { width:75px; @@ -403,13 +434,13 @@ .choosefriends-overlay { width:384px; - height:344px; - padding:8px; background-color:#787878; position:fixed; top:20%; left:50%; margin-left:-200px; + padding:8px 8px 15px !important; + min-height:initial !important; } .choosefriends-inner { diff --git a/web/app/assets/stylesheets/client/dialog.css.scss b/web/app/assets/stylesheets/client/dialog.css.scss index fa4c12d1a..b0ca88cb8 100644 --- a/web/app/assets/stylesheets/client/dialog.css.scss +++ b/web/app/assets/stylesheets/client/dialog.css.scss @@ -6,7 +6,7 @@ border: 1px solid $ColorScreenPrimary; color:#fff; min-width: 400px; - min-height: 450px; + min-height: 375px; z-index: 100; h2 { diff --git a/web/app/assets/stylesheets/client/ftue.css.scss b/web/app/assets/stylesheets/client/ftue.css.scss index 933d01a6b..494e12532 100644 --- a/web/app/assets/stylesheets/client/ftue.css.scss +++ b/web/app/assets/stylesheets/client/ftue.css.scss @@ -443,7 +443,7 @@ div[layout-id="ftue3"] { */ /* Start Jeff's ftue.css */ -.signin-overlay { +.landing-overlay { z-index:100; width:800px; height:auto; diff --git a/web/app/assets/stylesheets/client/jamkazam.css.scss b/web/app/assets/stylesheets/client/jamkazam.css.scss index 16d357c82..1a173dd70 100644 --- a/web/app/assets/stylesheets/client/jamkazam.css.scss +++ b/web/app/assets/stylesheets/client/jamkazam.css.scss @@ -242,8 +242,8 @@ input[type="button"] { .autocomplete-suggestions { border: 1px solid #999; background: #666; overflow: auto; } .autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; } -.autocomplete-selected { background: #F0F0F0; } -.autocomplete-suggestions strong { font-weight: normal; color: #3399FF; } +.autocomplete-selected { background: #999; } +.autocomplete-suggestions strong { font-weight: normal; color: #a2cffd; } .autocomplete .selected { background:$ColorScreenBackground; diff --git a/web/app/assets/stylesheets/client/jquery-ui-overrides.css.scss b/web/app/assets/stylesheets/client/jquery-ui-overrides.css.scss index 6852495c4..d066cf241 100644 --- a/web/app/assets/stylesheets/client/jquery-ui-overrides.css.scss +++ b/web/app/assets/stylesheets/client/jquery-ui-overrides.css.scss @@ -1,6 +1,6 @@ /* DatePicker Container */ .ui-datepicker { - width: 216px; + width: 254px; height: auto; margin: 5px auto 0; font: 9pt Arial, sans-serif; @@ -18,12 +18,12 @@ .ui-datepicker-header { // background: url('../img/dark_leather.png') repeat 0 0 #000; background-color: #7e7e7e; - color: #e0e0e0; + color: #333; font-weight: bold; -webkit-box-shadow: inset 0px 1px 1px 0px rgba(250, 250, 250, .2); -moz-box-shadow: inset 0px 1px 1px 0px rgba(250, 250, 250, .2); box-shadow: inset 0px 1px 1px 0px rgba(250, 250, 250, .2); - text-shadow: 1px -1px 0px #000; + //text-shadow: 1px -1px 0px #000; filter: dropshadow(color=#000, offx=1, offy=-1); line-height: 30px; border-width: 1px 0 0 0; @@ -68,8 +68,8 @@ text-transform: uppercase; font-size: 6pt; padding: 5px 0; - color: #666666; - text-shadow: 1px 0px 0px #fff; + color: #ccc; + //text-shadow: 1px 0px 0px #fff; filter: dropshadow(color=#fff, offx=1, offy=0); } .ui-datepicker tbody td { @@ -97,14 +97,14 @@ filter: dropshadow(color=#fff, offx=1, offy=1); } .ui-datepicker-calendar .ui-state-default { - background: #4e4e4e; - background: -moz-linear-gradient(top, #4e4e4e 0%, #0e0e0e 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ededed), color-stop(100%,#dedede)); - background: -webkit-linear-gradient(top, #4e4e4e 0%,#0e0e0e 100%); - background: -o-linear-gradient(top, #4e4e4e 0%,#0e0e0e 100%); - background: -ms-linear-gradient(top, #4e4e4e 0%,#0e0e0e 100%); - background: linear-gradient(top, #4e4e4e 0%,#0e0e0e 100%); - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ededed', endColorstr='#dedede',GradientType=0 ); + //background: #4e4e4e; + //background: -moz-linear-gradient(top, #4e4e4e 0%, #0e0e0e 100%); + //background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ededed), color-stop(100%,#dedede)); + //background: -webkit-linear-gradient(top, #4e4e4e 0%,#0e0e0e 100%); + //background: -o-linear-gradient(top, #4e4e4e 0%,#0e0e0e 100%); + //background: -ms-linear-gradient(top, #4e4e4e 0%,#0e0e0e 100%); + //background: linear-gradient(top, #4e4e4e 0%,#0e0e0e 100%); + //filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ededed', endColorstr='#dedede',GradientType=0 ); -webkit-box-shadow: inset 1px 1px 0px 0px rgba(250, 250, 250, .5); -moz-box-shadow: inset 1px 1px 0px 0px rgba(250, 250, 250, .5); box-shadow: inset 1px 1px 0px 0px rgba(250, 250, 250, .5); @@ -124,6 +124,7 @@ position: relative; margin: -1px; } + .ui-datepicker-unselectable .ui-state-default { background: #4e4e4e; color: #b4b3b3; diff --git a/web/app/assets/stylesheets/client/screen_common.css.scss b/web/app/assets/stylesheets/client/screen_common.css.scss index 4f481ea62..aa6657686 100644 --- a/web/app/assets/stylesheets/client/screen_common.css.scss +++ b/web/app/assets/stylesheets/client/screen_common.css.scss @@ -172,7 +172,7 @@ small, .small {font-size:11px;} .bold {font-weight:bold;} .rsvp-instruments { - height:80px; + height:auto; overflow:auto; background-color:#202020; padding:8px; diff --git a/web/app/assets/stylesheets/client/wizard/wizard.css.scss b/web/app/assets/stylesheets/client/wizard/wizard.css.scss index 4e974eb15..41b7c1a64 100644 --- a/web/app/assets/stylesheets/client/wizard/wizard.css.scss +++ b/web/app/assets/stylesheets/client/wizard/wizard.css.scss @@ -9,7 +9,6 @@ @include border_box_sizing; padding-right:45px; padding-bottom:15px; - } .wizard-buttons-holder { diff --git a/web/app/assets/stylesheets/landing/landing.css b/web/app/assets/stylesheets/landing/landing.css index ef1d495a8..23908ed65 100644 --- a/web/app/assets/stylesheets/landing/landing.css +++ b/web/app/assets/stylesheets/landing/landing.css @@ -6,4 +6,6 @@ *= require client/ftue *= require landing/simple_landing *= require landing/footer +*= require users/signinCommon +*= require users/signin */ \ No newline at end of file diff --git a/web/app/assets/stylesheets/landing/simple_landing.css.scss b/web/app/assets/stylesheets/landing/simple_landing.css.scss index 07020e0a0..54881b998 100644 --- a/web/app/assets/stylesheets/landing/simple_landing.css.scss +++ b/web/app/assets/stylesheets/landing/simple_landing.css.scss @@ -27,6 +27,11 @@ body { top:0; } +.landing-overlay { + position:relative; + top:0; +} + strong { font-weight: 600; @@ -92,86 +97,22 @@ strong { // all custom CSS for the sign-in page goes here .signin-page { - .ftue-inner { - line-height:18px; + z-index:100; + width:300px; + height:auto; + position:absolute; + top:110px; + background-color:#333; + border: 1px solid #ed3618; + margin-left:-150px; + + .overlay-inner { + height:auto; + margin-left:0; } - .ftue-left, .ftue-right { - - } - - fieldset[name=text-input]{ - float:right; - margin-right:18px; - } - - fieldset[name=signin-options] { - float:left; - margin:10px 0 0 10px; - - small { - float:left; - } - } - - fieldset[name=actions] { - float:right; - margin: 10px 19px 0 0; - } - - .field { - right:0; - } - - .email { - float:left; - margin-right:10px; - - } - - .password { - float:left; - } - - label { - margin:27px 0 10px; - } - - - - .already-member { - - } - - .keep-logged-in { - - } - - .forgot-password { - font-size:11px; - float:right; - margin:15px 19px 0 0; - - a { - text-decoration: underline; - } - } - - .login-error { - background-color: #330000; - border: 1px solid #990000; - padding:4px; - } - - .login-error-msg { + .signin-cancel { display:none; - margin-top:10px; - text-align:center; - color:#F00; - font-size:11px; } - fieldset.login-error .login-error-msg { - display:block; - } } diff --git a/web/app/assets/stylesheets/users/request_reset_password.css.scss b/web/app/assets/stylesheets/users/request_reset_password.css.scss new file mode 100644 index 000000000..e69de29bb diff --git a/web/app/assets/stylesheets/users/signin.css.scss b/web/app/assets/stylesheets/users/signin.css.scss new file mode 100644 index 000000000..0cfbeaa5c --- /dev/null +++ b/web/app/assets/stylesheets/users/signin.css.scss @@ -0,0 +1,10 @@ +body.signin { + + .signup-common { + display:none; + + .signup-cancel { + display:none; + } + } +} \ No newline at end of file diff --git a/web/app/assets/stylesheets/users/signinCommon.css.scss b/web/app/assets/stylesheets/users/signinCommon.css.scss new file mode 100644 index 000000000..3a5d7ca0a --- /dev/null +++ b/web/app/assets/stylesheets/users/signinCommon.css.scss @@ -0,0 +1,55 @@ +.signin-common { + + div.field { + width:100%; + } + + div.overlay-inner { + height:auto; + } + + label { + margin-bottom:2px; + } + + div.email { + margin-top:5px; + } + + div.password { + margin-top:20px; + } + + div.actions { + margin-top:20px; + } + + .login-error { + background-color: #330000; + border: 1px solid #990000; + padding:4px; + + div.actions { + margin-top:10px; + } + } + + .login-error-msg { + display:none; + margin-top:10px; + text-align:center; + color:#F00; + font-size:11px; + } + + .login-error .login-error-msg { + display:block; + } + + input[type=text], input[type=password]{ + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + } +} \ No newline at end of file diff --git a/web/app/assets/stylesheets/users/signinDialog.css.scss b/web/app/assets/stylesheets/users/signinDialog.css.scss index 2412813d3..1bef3b20a 100644 --- a/web/app/assets/stylesheets/users/signinDialog.css.scss +++ b/web/app/assets/stylesheets/users/signinDialog.css.scss @@ -1,59 +1,3 @@ #signin-dialog { height:auto; -} - -#signin-dialog { - - div.field { - width:100%; - } - - div.overlay-inner { - height:auto; - } - - label { - margin-bottom:2px; - } - - div.email { - margin-top:5px; - } - - div.password { - margin-top:20px; - } - - div.actions { - margin-top:20px; - } - - .login-error { - background-color: #330000; - border: 1px solid #990000; - padding:4px; - - div.actions { - margin-top:10px; - } - } - - .login-error-msg { - display:none; - margin-top:10px; - text-align:center; - color:#F00; - font-size:11px; - } - - .login-error .login-error-msg { - display:block; - } - - input[type=text], input[type=password]{ - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - } } \ No newline at end of file diff --git a/web/app/assets/stylesheets/web/main.css.scss b/web/app/assets/stylesheets/web/main.css.scss index c0ec227e9..d3725237e 100644 --- a/web/app/assets/stylesheets/web/main.css.scss +++ b/web/app/assets/stylesheets/web/main.css.scss @@ -394,6 +394,10 @@ body.web { width:100%; } } + + .field.terms_of_service .field_with_errors { + display:inline; + } } ul { @@ -453,6 +457,10 @@ body.web { top:0; } +.landing-overlay { + position:relative; + top:0; +} strong { font-weight: 600; @@ -593,4 +601,7 @@ strong { body.jam.web.welcome .no-websocket-connection { display:none; +} +body.jam.web.register .no-websocket-connection { + display:none; } \ No newline at end of file diff --git a/web/app/assets/stylesheets/web/web.css b/web/app/assets/stylesheets/web/web.css index c06b72a33..e99f565ba 100644 --- a/web/app/assets/stylesheets/web/web.css +++ b/web/app/assets/stylesheets/web/web.css @@ -22,5 +22,6 @@ *= require web/welcome #= require web/sessions *= require web/events +*= require users/signinCommon *= require users/signinDialog */ \ No newline at end of file diff --git a/web/app/controllers/music_sessions_controller.rb b/web/app/controllers/music_sessions_controller.rb index 19f37c7c2..226142a58 100644 --- a/web/app/controllers/music_sessions_controller.rb +++ b/web/app/controllers/music_sessions_controller.rb @@ -47,15 +47,9 @@ class MusicSessionsController < ApplicationController # run these 3 queries only if the user has access to the page if @can_view - ActiveRecord::Base.transaction do - @music_sessions, @user_scores = MusicSession.sms_index(current_user, {:session_id => params[:id], :client_id => cookies[:client_id]}) - unless @music_sessions.blank? - ms = @music_sessions[0] - @approved_rsvps = ms.approved_rsvps - @open_slots = ms.open_slots - @pending_invitations = ms.pending_invitations - end - end + @approved_rsvps = @music_session.approved_rsvps + @open_slots = @music_session.open_slots + @pending_invitations = @music_session.pending_invitations end render :layout => "web" diff --git a/web/app/controllers/sessions_controller.rb b/web/app/controllers/sessions_controller.rb index fbeb8ec9f..f2f705141 100644 --- a/web/app/controllers/sessions_controller.rb +++ b/web/app/controllers/sessions_controller.rb @@ -3,7 +3,7 @@ class SessionsController < ApplicationController layout "web" - def new + def signin @login_error = false @sso = params[:sso] @send_back_to = request.headers['REFERER'] @@ -25,7 +25,7 @@ class SessionsController < ApplicationController @login_error = true @sso = params[:sso] @send_back_to = params[:send_back_to] - render 'new', :layout => "landing" + render 'signin', :layout => "landing" else if jkclient_agent? diff --git a/web/app/controllers/users_controller.rb b/web/app/controllers/users_controller.rb index 8fa2cc381..81d80255b 100644 --- a/web/app/controllers/users_controller.rb +++ b/web/app/controllers/users_controller.rb @@ -145,7 +145,7 @@ class UsersController < ApplicationController birth_date = fixup_birthday(params[:jam_ruby_user]["birth_date(2i)"], params[:jam_ruby_user]["birth_date(3i)"], params[:jam_ruby_user]["birth_date(1i)"]) location = { :country => params[:jam_ruby_user][:country], :state => params[:jam_ruby_user][:state], :city => params[:jam_ruby_user][:city]} - terms_of_service = params[:jam_ruby_user][:terms_of_service].nil? ? false : true + terms_of_service = params[:jam_ruby_user][:terms_of_service].nil? || params[:jam_ruby_user][:terms_of_service] == "0"? false : true musician = params[:jam_ruby_user][:musician] @user = UserManager.new.signup(remote_ip: request.remote_ip, diff --git a/web/app/helpers/client_helper.rb b/web/app/helpers/client_helper.rb index f8f52caf6..6f4d0a489 100644 --- a/web/app/helpers/client_helper.rb +++ b/web/app/helpers/client_helper.rb @@ -19,6 +19,7 @@ module ClientHelper def gon_setup gon.root_url = root_url + gon.client_path = client_path # use gon to pass variables into javascript if Rails.env == "development" # if in development mode, we assume you are running websocket-gateway diff --git a/web/app/views/clients/_banner.html.haml b/web/app/views/clients/_banner.html.haml index 9e53fb0e1..42d44452d 100644 --- a/web/app/views/clients/_banner.html.haml +++ b/web/app/views/clients/_banner.html.haml @@ -30,4 +30,18 @@ %li In the resulting screen, drag the JamKazam icon to the Applications folder. It will show a progress bar as it copies. %li Double-click the Applications folder to go into it. %li If you are still running the JamKazam application, you will need to stop it before executing the last step. - %li Find the JamKazam application in the Applications folder, and double-click the icon to launch it! \ No newline at end of file + %li Find the JamKazam application in the Applications folder, and double-click the icon to launch it! + +%script{type: 'text/template', id: 'template-shutdown-prompt'} + .shutdown-prompt + We strongly recommend that you leave the JamKazam application running in the background. + This is a very lightweight app that will not disrupt your use of your computer and other applications, and leaving this app running will deliver the following benefits to you: + %ul + %li + %span.definition Scoring Service + = '- If you leave the app running, there is a service that can check your Internet latency to other JamKazam users. This is critical data that will guide you on which musicians and which sessions will offer a good online play experience.' + %li + %span.definition Recordings + = '- If you leave the app running, any recordings that you and others have made during sessions can be mastered - i.e. uploaded, mixed on our servers, and downloaded back to your computer - so that you have high quality versions of your recordings available.' + + Please consider leaving this lightweight app running in the background for your own benefit, thanks! diff --git a/web/app/views/clients/_findSession.html.erb b/web/app/views/clients/_findSession.html.erb index 49c0110b1..170562148 100644 --- a/web/app/views/clients/_findSession.html.erb +++ b/web/app/views/clients/_findSession.html.erb @@ -1,78 +1,78 @@
    -
    -
    -
    - <%= image_tag "content/icon_search.png", :size => "19x19" %> -
    +
    +
    +
    + <%= image_tag "content/icon_search.png", :size => "19x19" %> +
    -

    find a session

    +

    find a session

    - <%= render "screen_navigation" %> -
    -
    -
    -
    -
    -
    -
    Filter Session List:
    - - -
    - <%= render "genreSelector" %> -
    - - - - - -
    - -
    - - - - -
    - REFRESH -
    -
    -
    -
    -
    -
    - <%= render :partial => "sessionList", :locals => {:title => "current, active sessions", :category => "sessions-active"} %> -
    -
    - No active public sessions found. -
    -
    -
    - <%= render :partial => "sessionList", :locals => {:title => "future, scheduled sessions", :category => "sessions-scheduled"} %> -
    -
    - No scheduled sessions found. -
    -
    - Next -
    -
    -
    - -
    - No more sessions. -
    -
    -
    + <%= render "screen_navigation" %>
    +
    +
    +
    +
    +
    +
    Filter Session List:
    + + +
    + <%= render "genreSelector" %> +
    + + + + + +
    + +
    + + + + +
    + REFRESH +
    +
    +
    +
    +
    +
    + <%= render :partial => "sessionList", :locals => {:title => "current, active sessions", :category => "sessions-active"} %> +
    +
    + No active public sessions found. +
    +
    +
    + <%= render :partial => "sessionList", :locals => {:title => "future, scheduled sessions", :category => "sessions-scheduled"} %> +
    +
    + No scheduled sessions found. +
    +
    + Next +
    +
    +
    + +
    + No more sessions. +
    +
    +
    +
    @@ -160,6 +160,9 @@ Notation Files: {notation_files} + + {scheduled_start} + @@ -243,4 +246,5 @@ {latency_text} +
     
    diff --git a/web/app/views/clients/_networkTestDialog.html.haml b/web/app/views/clients/_networkTestDialog.html.haml index d09c03585..8e70a8a7a 100644 --- a/web/app/views/clients/_networkTestDialog.html.haml +++ b/web/app/views/clients/_networkTestDialog.html.haml @@ -6,5 +6,5 @@ .clearall .buttons %a.button-grey.btn-cancel{href:'#'} CANCEL - %a.button-orange.btn-help{href: '#'} HELP + %a.button-grey.btn-help{rel: 'external', href: 'https://jamkazam.desk.com/customer/portal/articles/1599969-first-time-setup---step-6---test-your-network'} HELP %a.button-orange.btn-close{href:'#'} CLOSE \ No newline at end of file diff --git a/web/app/views/clients/_rsvpSubmitDialog.html.haml b/web/app/views/clients/_rsvpSubmitDialog.html.haml index 319313bc9..330c656b2 100644 --- a/web/app/views/clients/_rsvpSubmitDialog.html.haml +++ b/web/app/views/clients/_rsvpSubmitDialog.html.haml @@ -20,8 +20,7 @@ %br/ %br/ .left - %a.button-orange{:href => 'TBD', :rel => 'external', :target => '_blank'} HELP + %a.button-grey{:href => 'http://jamkazam.desk.com', :rel => 'external', :target => '_blank'} HELP .right %a.button-grey{:id => 'btnCancel', 'layout-action' => 'close'} CANCEL - %a.button-orange{:id => 'btnSubmitRsvp'} SUBMIT RSVP - %br{:clear => "all"}/ \ No newline at end of file + %a.button-orange{:id => 'btnSubmitRsvp'} SUBMIT RSVP \ No newline at end of file diff --git a/web/app/views/clients/_scheduledSession.html.erb b/web/app/views/clients/_scheduledSession.html.erb index 9a972ab3a..c43c41b4b 100644 --- a/web/app/views/clients/_scheduledSession.html.erb +++ b/web/app/views/clients/_scheduledSession.html.erb @@ -94,7 +94,7 @@ This is good option to choose if you just want to jump into a quick test session alone to make sure you audio gear is working properly, and to familiarize yourself with the session interface. Choosing this option will set your session to private so that you won't be disturbed, and will - set other options to defaults. To use this option, just click the NEXT buttono to proceed. + set other options to defaults. To use this option, just click the NEXT button to proceed.
    @@ -266,31 +266,31 @@
  • -
  • +
    @@ -355,7 +355,7 @@

    How will you handle fan access?

    @@ -407,14 +407,17 @@
    -
    -
    -
    -
    + +
    +
    +
    +
    + -
    + + @@ -438,9 +441,13 @@ diff --git a/web/app/views/clients/_sessionSettings.html.haml b/web/app/views/clients/_sessionSettings.html.haml index 3561202da..90b59a060 100644 --- a/web/app/views/clients/_sessionSettings.html.haml +++ b/web/app/views/clients/_sessionSettings.html.haml @@ -47,7 +47,7 @@ Fan Access: .right.w75.ib.mb10 %select{:name => "fan_access", :id => "session-settings-fan-access"} - %option{:value => "listen-chat-band"} Fans may listen, chat with the band + //%option{:value => "listen-chat-band"} Fans may listen, chat with the band %option{:value => "listen-chat"} Fans may listen, chat with each other %option{:value => "no-listen-chat"} Fans may not listen to session diff --git a/web/app/views/clients/index.html.erb b/web/app/views/clients/index.html.erb index 47072000a..e57db530f 100644 --- a/web/app/views/clients/index.html.erb +++ b/web/app/views/clients/index.html.erb @@ -124,7 +124,15 @@ // you need to be logged in to use this part of the interface. // save original URL, and redirect to the home page logger.debug("redirecting back to / because not logged in") - window.location.href = '/?redirect-to=' + encodeURIComponent(JK.locationPath()); + + var redirectPath= '?redirect-to=' + encodeURIComponent(JK.locationPath()); + if(gon.isNativeClient) { + window.location.href = '/signin' + redirectPath; + } + else { + window.location.href = '/' + redirectPath; + } + <% end %> @@ -133,6 +141,9 @@ if (this.didInitAfterConnect) return; this.didInitAfterConnect = true + var shutdownDialog = new JK.ShutdownDialog(JK.app); + shutdownDialog.initialize(); + // This is a helper class with a singleton. No need to instantiate. JK.GenreSelectorHelper.initialize(JK.app); diff --git a/web/app/views/layouts/landing.erb b/web/app/views/layouts/landing.html.erb similarity index 87% rename from web/app/views/layouts/landing.erb rename to web/app/views/layouts/landing.html.erb index d88d06461..960b20852 100644 --- a/web/app/views/layouts/landing.erb +++ b/web/app/views/layouts/landing.html.erb @@ -31,7 +31,7 @@ <%= render "layouts/social_meta" %> <% end %> - +
    <%= javascript_include_tag "landing/landing" %> @@ -63,14 +63,22 @@ JK.currentUserId = '<%= current_user.id %>'; JK.currentUserAvatarUrl = JK.resolveAvatarUrl('<%= current_user.photo_url %>'); JK.currentUserName = '<%= current_user.name %>'; + JK.currentUserMusician = '<%= current_user.musician %>'; <% else %> JK.currentUserId = null; JK.currentUserAvatarUrl = null; JK.currentUserName = null; + JK.currentUserMusician = null; <% end %> + + JK.app = JK.JamKazam(); + + JK.app.initialize({inClient: false, layoutOpts: {layoutFooter: false, sizeOverlayToContent: true}}); }) + <%= yield(:extra_js) %> + <%= render "shared/ga" %> diff --git a/web/app/views/music_sessions/session_info.html.haml b/web/app/views/music_sessions/session_info.html.haml index a6b33e871..906ad80af 100644 --- a/web/app/views/music_sessions/session_info.html.haml +++ b/web/app/views/music_sessions/session_info.html.haml @@ -60,6 +60,10 @@ agreement ( %a.gold{:href => "#{@music_session.legal_policy_url}", :target => "_blank"} View full legal details ) + .clearall.left.w20.ib.mb10 + %strong Fan Page: + .right.w75.ib.mb10.fan_page + = share_token_url(@music_session.share_token.token) %br{clear:'all'}/ @@ -84,28 +88,7 @@ .left.ml10 - rsvp.instrument_list.each do |i| %img.instrument-icon{'instrument-id' => i[:id], height:24, width:24} - .right.w30.ib.f11.center - - if current_user.id == rsvp.id - %table.musicians{:cellpadding => 0, :cellspacing => 0} - %tr.mb15 - %td.latency-green GOOD - - elsif !@user_scores[rsvp.id] - %table.musicians{:cellpadding => 0, :cellspacing => 0} - %tr.mb15 - %td.latency-grey UNKNOWN - - else - - if @user_scores[rsvp.id] >= 0 && @user_scores[rsvp.id] <= 20.0 - %table.musicians{:cellpadding => 0, :cellspacing => 0} - %tr.mb15 - %td.latency-green GOOD - - elsif @user_scores[rsvp.id] > 20.0 && @user_scores[rsvp.id] <= 40.0 - %table.musicians{:cellpadding => 0, :cellspacing => 0} - %tr.mb15 - %td.latency-yellow MEDIUM - - elsif @user_scores[rsvp.id] > 40.0 - %table.musicians{:cellpadding => 0, :cellspacing => 0} - %tr.mb15 - %td.latency-red POOR + .right.w30.ib.f11.center.latency-tags %br{:clear => "all"}/ %br/ @@ -160,6 +143,12 @@ - content_for :extra_js do :javascript $(function () { - var ss = new window.JK.ShowSessionInfo(JK.app); - ss.initialize("#{@music_session.id}"); + var ss = new window.JK.ShowSessionInfo(JK.app, "#{@music_session.id}"); + ss.initialize(); }) + +%script{:type => 'text/template', :id => 'template-latency-detail'} + %table.musicians{:cellpadding => 0, :cellspacing => 0} + %tr.mb15 + %td{:class => "{latencyStyle}"} {latencyDescription} + diff --git a/web/app/views/sessions/new.html.erb b/web/app/views/sessions/new.html.erb deleted file mode 100644 index a59fb1cf6..000000000 --- a/web/app/views/sessions/new.html.erb +++ /dev/null @@ -1,100 +0,0 @@ -<% provide(:title, 'Sign in') %> - - - - - - diff --git a/web/app/views/sessions/signin.html.haml b/web/app/views/sessions/signin.html.haml new file mode 100644 index 000000000..e20fa396e --- /dev/null +++ b/web/app/views/sessions/signin.html.haml @@ -0,0 +1,18 @@ +- provide(:title, 'Sign in') +- provide(:page_name, 'signin') + +.signin-overlay.signin-page + .content-head + %h1 sign in or register + + = render "users/signin" + + = render "users/signup" + + %br{clear: 'all'} + +- content_for :extra_js do + :javascript + $(function () { + window.JK.SigninPage(); + }) \ No newline at end of file diff --git a/web/app/views/users/_create_account_form.html.erb b/web/app/views/users/_create_account_form.html.erb index 77cbbafed..c89173d42 100644 --- a/web/app/views/users/_create_account_form.html.erb +++ b/web/app/views/users/_create_account_form.html.erb @@ -1,4 +1,4 @@ -