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 = $('