diff --git a/admin/Gemfile b/admin/Gemfile
index 3ec3ed16b..750fb4e6d 100644
--- a/admin/Gemfile
+++ b/admin/Gemfile
@@ -71,6 +71,7 @@ gem 'rest-client'
gem 'iso-639'
gem 'rubyzip'
gem 'sanitize'
+gem 'slim'
group :libv8 do
gem 'libv8', "~> 3.11.8"
diff --git a/admin/app/admin/jam_ruby_users.rb b/admin/app/admin/jam_ruby_users.rb
index b6afa5e35..3e8c1dd6b 100644
--- a/admin/app/admin/jam_ruby_users.rb
+++ b/admin/app/admin/jam_ruby_users.rb
@@ -14,27 +14,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do
filter :updated_at
- form do |ff|
- ff.inputs "Details" do
- ff.input :email
- ff.input :admin
- ff.input :raw_password, :label => 'Password'
- ff.input :first_name
- ff.input :last_name
- ff.input :city
- ff.input :state
- ff.input :country
- ff.input :musician
- ff.input :can_invite
- ff.input :photo_url
- ff.input :session_settings
- end
- ff.inputs "Signup" do
- ff.input :email_template, :label => 'Welcome Email Template Name'
- ff.input :confirm_url, :label => 'Signup Confirm URL'
- end
- ff.actions
- end
+ form :partial => "form"
show do |user|
attributes_table do
@@ -53,8 +33,6 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do
row :gender
row :email_confirmed
row :image do user.photo_url ? image_tag(user.photo_url) : '' end
- row :session_settings
- row :can_invite
end
active_admin_comments
end
@@ -114,6 +92,30 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do
# call `create!` to ensure that the rest of the action continues as normal
create!
end
+
+ def update
+
+ @user = resource
+ @user.email = params[:jam_ruby_user][:email]
+ @user.admin = params[:jam_ruby_user][:admin]
+ @user.musician = params[:jam_ruby_user][:musician]
+ @user.first_name = params[:jam_ruby_user][:first_name]
+ @user.last_name = params[:jam_ruby_user][:last_name]
+ @user.state = params[:jam_ruby_user][:state]
+ @user.city = params[:jam_ruby_user][:city]
+
+
+ if params[:jam_ruby_user][:show_frame_options].to_i == 1
+ @user.mod_merge({User::MOD_GEAR => {User::MOD_GEAR_FRAME_OPTIONS => true}})
+ else
+ @user.delete_mod(User::MOD_GEAR, User::MOD_GEAR_FRAME_OPTIONS)
+ end
+
+ @user.save!
+
+ redirect_to edit_admin_user_path(@user)
+
+ end
end
end
diff --git a/admin/app/views/admin/users/_form.html.slim b/admin/app/views/admin/users/_form.html.slim
new file mode 100644
index 000000000..204d9a4da
--- /dev/null
+++ b/admin/app/views/admin/users/_form.html.slim
@@ -0,0 +1,12 @@
+= semantic_form_for([:admin_users, resource], :url => resource.new_record? ? admin_users_path : "#{ENV['RAILS_RELATIVE_URL_ROOT']}/admin/users/#{resource.id}") do |f|
+ = f.inputs "Details" do
+ = f.input :email, label: 'Email'
+ = f.input :admin
+ = f.input :first_name
+ = f.input :last_name
+ = f.input :city
+ = f.input :state
+ = f.input :musician
+ = f.inputs "Gear Mods" do
+ = f.input :show_frame_options, as: :boolean
+ = f.actions
diff --git a/admin/config/initializers/jam_ruby_user.rb b/admin/config/initializers/jam_ruby_user.rb
index 980c82b9b..6d7dca153 100644
--- a/admin/config/initializers/jam_ruby_user.rb
+++ b/admin/config/initializers/jam_ruby_user.rb
@@ -1,11 +1,5 @@
class JamRuby::User
- EMAIL_TMPL_WELCOME = 'welcome_message'
- EMAIL_TMPL_WELCOME_BETA = 'welcome_betauser'
- EMAIL_TMPL_WELCOMES = [EMAIL_TMPL_WELCOME_BETA, EMAIL_TMPL_WELCOME]
-
- CONFIRM_URL = "http://www.jamkazam.com/confirm" # we can't get request.host_with_port, so hard-code confirm url (with user override)
-
attr_accessible :admin, :raw_password, :musician, :can_invite, :photo_url, :session_settings, :confirm_url, :email_template # :invite_email
def raw_password
@@ -25,50 +19,12 @@
end
end
- def confirm_url
- @signup_confirm_url ||= CONFIRM_URL
- end
-
- def confirm_url= url
- @signup_confirm_url = url
- end
-
- def email_template
- @signup_email_template ||= EMAIL_TMPL_WELCOME_BETA
- end
-
- def email_template= tmpl
- @signup_email_template = tmpl
- end
def admin_user
User.where(:email => self.email)[0]
end
- after_create do
- self.update_attribute(:signup_token, SecureRandom.urlsafe_base64)
- url = confirm_url
- url.chomp!('/')
-
- # only supporting two welcome templates ATM
- if EMAIL_TMPL_WELCOMES.index(self.email_template).nil?
- self.email_template = EMAIL_TMPL_WELCOME
- end
- # UserMailer.send(self.email_template, self, "#{url}/#{self.signup_token}").deliver
+ def show_frame_options
+ self.get_gear_mod(MOD_GEAR_FRAME_OPTIONS)
end
-
- after_save do
- logger.debug("*** after_save: #{self.admin_changed?}")
- if self.admin_changed?
- if self.admin
- if self.admin_user.nil?
- au = User.create(:email => self.email)
- au.update_attribute(:encrypted_password, self.password_digest)
- end
- else
- self.admin_user.try(:destroy)
- end
- end
- end
-
end
diff --git a/ruby/lib/jam_ruby/constants/validation_messages.rb b/ruby/lib/jam_ruby/constants/validation_messages.rb
index ea914a4c9..30544bc4a 100644
--- a/ruby/lib/jam_ruby/constants/validation_messages.rb
+++ b/ruby/lib/jam_ruby/constants/validation_messages.rb
@@ -80,7 +80,7 @@ module ValidationMessages
DIFFERENT_SOURCE_TARGET = 'can\'t be same as the sender'
# mods
- MODS_NO_SHOW_MUST_BE_HASH = 'no_show must be a hash'
+ MODS_MUST_BE_HASH = 'must be a hash'
MODS_UNKNOWN_KEY = 'unknown mod'
# takes either a string/string hash, or a string/array-of-strings|symbols hash,
diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb
index 750ddf462..5194517c8 100644
--- a/ruby/lib/jam_ruby/models/music_session.rb
+++ b/ruby/lib/jam_ruby/models/music_session.rb
@@ -68,7 +68,6 @@ module JamRuby
validate :validate_timezone
before_create :generate_share_token
- before_create :add_to_feed
#before_save :update_scheduled_start
before_save :check_scheduling_info_changed
@@ -81,12 +80,6 @@ module JamRuby
true
end
- def add_to_feed
- feed = Feed.new
- feed.music_session = self
- end
-
-
def update_scheduled_start
# it's very important that this only run if timezone changes, or scheduled_start changes
@@ -625,12 +618,6 @@ module JamRuby
hist.end_history if hist
- feed = Feed.find_by_music_session_id(session_id)
- unless feed.nil?
- feed.active = false
- feed.save
- end
-
Notification.send_session_ended(session_id)
end
diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb
index af931a0ac..6e9e6fad0 100644
--- a/ruby/lib/jam_ruby/models/user.rb
+++ b/ruby/lib/jam_ruby/models/user.rb
@@ -19,6 +19,12 @@ module JamRuby
JAM_REASON_IMPORT = 'i'
JAM_REASON_LOGIN = 'l'
+ # MOD KEYS
+ MOD_GEAR = "gear"
+ MOD_GEAR_FRAME_OPTIONS = "show_frame_options"
+
+ MOD_NO_SHOW = "no_show"
+
devise :database_authenticatable, :recoverable, :rememberable
acts_as_mappable
@@ -189,8 +195,8 @@ module JamRuby
# let's work to stop junk from getting into the mods array; this is essentially the schema
def validate_mods
mods_json.each do |key, value|
- if key == "no_show"
- errors.add(:mods, ValidationMessages::MODS_NO_SHOW_MUST_BE_HASH) unless value.is_a?(Hash)
+ if key == MOD_NO_SHOW || key == MOD_GEAR
+ errors.add(:mods, ValidationMessages::MODS_MUST_BE_HASH) unless value.is_a?(Hash)
else
errors.add(:mods, ValidationMessages::MODS_UNKNOWN_KEY)
end
@@ -373,8 +379,8 @@ module JamRuby
# new_modes should be a regular hash with non-symbolized keys (vs symbolized keys)
def mod_merge(new_mods)
self.mods = (mods_json.merge(new_mods) do |key, old_val, new_val|
- if key == "no_show"
- # we take the values from previous no_shows, and merge it with the new no_shows
+ if key == MOD_NO_SHOW || key == MOD_GEAR
+ # we take the values from previous hash, and merge it with the new hash
old_val.merge(new_val)
else
raise "unknown in mode_merge key: #{key}"
@@ -383,6 +389,36 @@ module JamRuby
@mods_json = nil # invalidate this since we've updated self.mods
end
+ # any mod with the value 'null' will be deleted
+ def delete_mod(root_key, sub_key)
+ mod = mods_json
+ root = mod[root_key]
+ if root
+ root.delete(sub_key)
+ # check if root key is completely empty
+ mod.delete(root_key) if root.length == 0
+ # check if mod key is empty
+ mod = nil if mod.length == 0
+ end
+
+ self.mods = mod.nil? ? nil : mod.to_json
+ @mods_json = nil # invalidate this since we've updated self.mods
+ end
+
+ def get_mod(root_key, sub_key)
+ mod = mods_json
+ root = mod[root_key]
+ root[sub_key] if root
+ end
+
+ def get_gear_mod(sub_key)
+ get_mod(MOD_GEAR, sub_key)
+ end
+
+ def get_no_show_mod(sub_key)
+ get_mod(MOD_NO_SHOW, sub_key)
+ end
+
def heartbeat_interval_client
mods_json[:heartbeat_interval_client]
end
diff --git a/ruby/spec/jam_ruby/models/user_spec.rb b/ruby/spec/jam_ruby/models/user_spec.rb
index 36425e495..54797df8c 100644
--- a/ruby/spec/jam_ruby/models/user_spec.rb
+++ b/ruby/spec/jam_ruby/models/user_spec.rb
@@ -608,7 +608,7 @@ describe User do
it "does not allow non-hash no_show" do
user.mod_merge({no_show:true})
user.valid?.should be_false
- user.errors[:mods].should == [ValidationMessages::MODS_NO_SHOW_MUST_BE_HASH]
+ user.errors[:mods].should == [ValidationMessages::MODS_MUST_BE_HASH]
end
end
diff --git a/web/app/assets/javascripts/accounts_session_detail.js b/web/app/assets/javascripts/accounts_session_detail.js
index a3debe85e..d75a5ea2e 100644
--- a/web/app/assets/javascripts/accounts_session_detail.js
+++ b/web/app/assets/javascripts/accounts_session_detail.js
@@ -87,48 +87,54 @@
var instrumentIds = $(e.target).attr('data-instrument-text');
var params = buildRsvpRequestActionParams(rsvpId, true);
- // first check if any open slots exist for these instruments
- rest.getOpenSessionSlots(sessionData.id, true)
- .done(function(openSlots) {
- if (openSlots) {
- if (openSlots.length === 0) {
- ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName, function() {
- approve(rsvpId, params);
- });
- }
- else {
- var arrInstrumentIds = instrumentIds.split('|');
- var openSlotInstrumentIds = [];
- var unavailableSlotInstrumentIds = [];
+ if (sessionData['is_unstructured_rsvp?']) {
+ approve(rsvpId, params);
+ }
- // ensure each instrument in the user's list is available in the open slots list
- $.each(openSlots, function(index, slot) {
- openSlotInstrumentIds.push(slot.instrument_id);
- });
-
- // build list of instrument IDs in the RSVP request for which there are no open slots
- for (var i=0; i < arrInstrumentIds.length; i++) {
- if ($.inArray(arrInstrumentIds[i], openSlotInstrumentIds) === -1) {
- unavailableSlotInstrumentIds.push(arrInstrumentIds[i]);
- }
- }
-
- if (unavailableSlotInstrumentIds.length > 0) {
- ui.launchRsvpCreateSlotDialog(sessionData.id, unavailableSlotInstrumentIds, userName, function() {
- approve(rsvpId, params);
- });
+ // check if any open slots exist for these instruments
+ else {
+ rest.getOpenSessionSlots(sessionData.id, true)
+ .done(function(openSlots) {
+ if (openSlots) {
+ if (openSlots.length === 0) {
+ ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName, function() {
+ approve(rsvpId, params);
+ });
}
else {
- approve(rsvpId, params);
+ var arrInstrumentIds = instrumentIds.split('|');
+ var openSlotInstrumentIds = [];
+ var unavailableSlotInstrumentIds = [];
+
+ // ensure each instrument in the user's list is available in the open slots list
+ $.each(openSlots, function(index, slot) {
+ openSlotInstrumentIds.push(slot.instrument_id);
+ });
+
+ // build list of instrument IDs in the RSVP request for which there are no open slots
+ for (var i=0; i < arrInstrumentIds.length; i++) {
+ if ($.inArray(arrInstrumentIds[i], openSlotInstrumentIds) === -1) {
+ unavailableSlotInstrumentIds.push(arrInstrumentIds[i]);
+ }
+ }
+
+ if (unavailableSlotInstrumentIds.length > 0) {
+ ui.launchRsvpCreateSlotDialog(sessionData.id, unavailableSlotInstrumentIds, userName, function() {
+ approve(rsvpId, params);
+ });
+ }
+ else {
+ approve(rsvpId, params);
+ }
}
}
- }
- else {
- ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName, function() {
- approve(rsvpId, params);
- });
- }
- });
+ else {
+ ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName, function() {
+ approve(rsvpId, params);
+ });
+ }
+ });
+ }
}
function approve(rsvpId, params) {
@@ -333,7 +339,7 @@
if ("instrument_list" in pending_rsvp_request && pending_rsvp_request.instrument_list != null) {
$.each(pending_rsvp_request.instrument_list, function (index, instrument) {
- var instrumentId = instrument == null ? null : instrument.id;
+ var instrumentId = context.JK.getInstrumentId(instrument.id);
var inst = context.JK.getInstrumentIcon24(instrumentId);
instrumentLogoHtml += '
';
instrumentDesc.push(instrumentId);
@@ -372,7 +378,7 @@
$.each(sessionData.approved_rsvps, function(index, approved_rsvp) {
if ("instrument_list" in approved_rsvp) {
$.each(approved_rsvp.instrument_list, function(index, instrument) {
- var instrumentId = instrument == null ? null : instrument.id;
+ var instrumentId = context.JK.getInstrumentId(instrument.id);
var inst = context.JK.getInstrumentIcon24(instrumentId);
instrumentLogoHtml += '
';
});
diff --git a/web/app/assets/javascripts/dialog/adjustGearSpeedDialog.js b/web/app/assets/javascripts/dialog/adjustGearSpeedDialog.js
new file mode 100644
index 000000000..1172ae500
--- /dev/null
+++ b/web/app/assets/javascripts/dialog/adjustGearSpeedDialog.js
@@ -0,0 +1,274 @@
+(function (context, $) {
+
+ "use strict";
+ context.JK = context.JK || {};
+ context.JK.AdjustGearSpeedDialog = function (app) {
+ var AUDIO_DEVICE_BEHAVIOR = context.JK.AUDIO_DEVICE_BEHAVIOR;
+ var gearUtils = context.JK.GearUtils;
+ var logger = context.JK.logger;
+ var rest = context.JK.Rest();
+ var $dialog = null;
+ var modUtils = context.JK.ModUtils;
+
+ var $runTestBtn = null;
+ var $scoreReport = null;
+ var $speedOptions = null;
+ var $saveBtn = null;
+ var $cancelBtn = null;
+ var $fairLabel = null;
+ var $slowLabel = null;
+ var $fastLabel = null;
+
+ var startingFramesize = null;
+ var startingBufferIn = null;
+ var startingBufferOut = null;
+
+ var frameBuffers = new context.JK.FrameBuffers(app);
+ var gearTest = new context.JK.GearTest(app);
+
+ var selectedDeviceInfo;
+ var deviceInformation;
+ var operatingSystem;
+ var frameBuffers;
+ var $frameBuffers;
+ var gearTest;
+
+ var $advanced;
+
+ function attemptScore() {
+ gearTest.attemptScore(selectedDeviceInfo);
+ }
+
+ function invalidateScore() {
+ gearTest.invalidateScore();
+ }
+
+ function getGearTest() {
+ return gearTest;
+ }
+
+ function updateDefaultBuffers() {
+ gearUtils.updateDefaultBuffers(selectedDeviceInfo, frameBuffers)
+ }
+
+ function onFramesizeChanged() {
+ //context.JK.prodBubble($resyncBtn, 'push-resync-when-done', {}, {positions:['top']});
+ updateDefaultBuffers();
+ context.jamClient.FTUESetFrameSize(frameBuffers.selectedFramesize());
+ invalidateScore();
+ }
+
+ function onBufferInChanged() {
+ //context.JK.prodBubble($resyncBtn, 'push-resync-when-done', {}, {positions:['top']});
+ context.jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn());
+ invalidateScore();
+ }
+
+ function onBufferOutChanged() {
+ //context.JK.prodBubble($resyncBtn, 'push-resync-when-done', {}, {positions:['top']});
+ context.jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut());
+ invalidateScore();
+ }
+
+ function freezeAudioInteraction() {
+ logger.debug("adjustGearSpeed: freezing audio interaction");
+ frameBuffers.disable();
+ $speedOptions.iCheck('disable')
+ $cancelBtn.on('click', false).addClass('disabled');
+ $runTestBtn.on('click', false).addClass('disabled');
+ }
+
+ function unfreezeAudioInteraction() {
+ logger.debug("adjustGearSpeed: unfreezing audio interaction");
+ frameBuffers.enable();
+ $speedOptions.iCheck('enable')
+ $cancelBtn.off('click', false).removeClass('disabled')
+ $runTestBtn.off('click', false).removeClass('disabled')
+ }
+
+
+ function updateDefaultLabel() {
+ if(selectedDeviceInfo && (selectedDeviceInfo.input.info.type == 'Win32_wdm' || selectedDeviceInfo.output.info.type == 'Win32_wdm')) {
+
+ }
+ else {
+ }
+ }
+
+ function translateFrameSizeToSpeed(framesize) {
+ if(framesize == 2.5) {
+ return 'fast'
+ }
+ else if(framesize == 5) {
+ return 'fair'
+ }
+ else if (framesize == 10) {
+ return "slow"
+ }
+ else {
+ throw "unknown framesize in translateFrameSizeToSpeed: " + framesize
+ }
+ }
+
+ function beforeShow() {
+ selectedDeviceInfo = gearUtils.selectedDeviceInfo(context.jamClient.FTUEGetInputMusicDevice(), context.jamClient.FTUEGetOutputMusicDevice());
+ deviceInformation = gearUtils.loadDeviceInfo();
+ startingFramesize = context.jamClient.FTUEGetFrameSize();
+ startingBufferIn = context.jamClient.FTUEGetInputLatency();
+ startingBufferOut = context.jamClient.FTUEGetOutputLatency();
+ var startingSpeed = translateFrameSizeToSpeed(startingFramesize)
+ logger.debug("speed upon entry: " + startingSpeed)
+ $speedOptions.filter('[value=' + startingSpeed + ']').iCheck('check')
+ setBuffers(startingSpeed);
+ updateDefaultLabel();
+ invalidateScore();
+ $saveBtn.on('click', false).addClass('disabled');
+ app.user().done(function() {
+ if(modUtils.getGear('show_frame_options')) {
+ $advanced.show();
+ }
+ })
+ }
+
+ function beforeHide() {
+ }
+
+ function onCancel() {
+ var scoring = gearTest.isScoring();
+
+ if(!scoring) {
+ logger.debug("resetting framesize/buffers on cancel of adjust-gear-speed")
+ // make sure the frame/buffer values are the same as when entered
+ context.jamClient.FTUESetFrameSize(startingFramesize);
+ context.jamClient.FTUESetInputLatency(startingBufferIn);
+ context.jamClient.FTUESetOutputLatency(startingBufferOut);
+ }
+
+ return !scoring;
+ }
+
+ function onSave() {
+
+ if($(this).is('.disabled')) {
+ logger.debug("cancelling save because not allowed yet")
+ return;
+ }
+
+ context.jamClient.FTUESetFrameSize(frameBuffers.selectedFramesize());
+ context.jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn());
+ context.jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut());
+
+ app.layout.closeDialog('adjust-gear-speed-dialog')
+
+ return false;
+ }
+
+ function onGearTestStarted(e, data) {
+ renderScoringStarted();
+ }
+
+ function onGearTestDone(e, data) {
+ renderScoringStopped();
+ $saveBtn.off('click', false).removeClass('disabled');
+ gearUtils.postDiagnostic(operatingSystem, deviceInformation, selectedDeviceInfo, gearTest, frameBuffers, true);
+ }
+
+ function onGearTestFail(e, data) {
+ renderScoringStopped();
+ $saveBtn.on('click', false).addClass('disabled');
+ gearUtils.postDiagnostic(operatingSystem, deviceInformation, selectedDeviceInfo, gearTest, frameBuffers, true);
+ }
+
+ function renderScoringStarted() {
+ freezeAudioInteraction();
+ }
+
+ function renderScoringStopped() {
+ unfreezeAudioInteraction();
+ }
+
+ function setBuffers(speed) {
+ var newFrameSize = null;
+ if(speed == 'fast') {
+ newFrameSize = 2.5
+ }
+ else if (speed == 'fair') {
+ newFrameSize = 5
+ }
+ else if (speed == 'slow') {
+ newFrameSize = 10
+ }
+ else {
+ throw "unknown speed setting: " + speed;
+ }
+
+ frameBuffers.setFramesize(newFrameSize);
+ jamClient.FTUESetFrameSize(newFrameSize);
+ updateDefaultBuffers();
+ }
+
+ function onSpeedChanged() {
+
+ setTimeout(function() {
+ var speed = $dialog.find('.speed-option .iradio_minimal.checked input').val()
+
+ setBuffers(speed);
+
+ attemptScore();
+ }, 1)
+
+ }
+
+ function initialize() {
+ var dialogBindings = {
+ 'beforeShow': beforeShow,
+ 'beforeHide': beforeHide,
+ 'onCancel' : onCancel
+ };
+
+ app.bindDialog('adjust-gear-speed-dialog', dialogBindings);
+
+ $dialog = $('#adjust-gear-speed-dialog');
+
+ $runTestBtn = $dialog.find('.run-test-btn');
+ $scoreReport = $dialog.find('.results');
+ $saveBtn = $dialog.find('.btnSave')
+ $cancelBtn = $dialog.find('.btnCancel')
+ $slowLabel = $dialog.find('label[for="adjust-gear-speed-slow"]')
+ $fairLabel = $dialog.find('label[for="adjust-gear-speed-fair"]')
+ $fastLabel = $dialog.find('label[for="adjust-gear-speed-fast"]')
+
+ operatingSystem = context.JK.GetOSAsString();
+
+ $frameBuffers = $dialog.find('.frame-and-buffers');
+ frameBuffers.initialize($frameBuffers);
+ $(frameBuffers)
+ .on(frameBuffers.FRAMESIZE_CHANGED, onFramesizeChanged)
+ .on(frameBuffers.BUFFER_IN_CHANGED, onBufferInChanged)
+ .on(frameBuffers.BUFFER_OUT_CHANGED, onBufferOutChanged)
+
+
+ gearTest.initialize($scoreReport, true)
+ $(gearTest)
+ .on(gearTest.GEAR_TEST_START, onGearTestStarted)
+ .on(gearTest.GEAR_TEST_DONE, onGearTestDone)
+ .on(gearTest.GEAR_TEST_FAIL, onGearTestFail)
+
+ $runTestBtn.click(attemptScore);
+
+ $dialog.data('result', gearTest); // so that others can peek into gear test data after dialog is closed
+
+ $advanced = $dialog.find('.advanced');
+ $speedOptions = $dialog.find('.speed-option input');
+ context.JK.checkbox($speedOptions).on('ifClicked', onSpeedChanged)
+
+ $saveBtn.click(onSave)
+ };
+
+
+ this.getGearTest = getGearTest;
+ this.initialize = initialize;
+ }
+
+ return this;
+})(window, jQuery);
\ No newline at end of file
diff --git a/web/app/assets/javascripts/dialog/rsvpCancelDialog.js b/web/app/assets/javascripts/dialog/rsvpCancelDialog.js
index bd0079bf3..feb4ff9d6 100644
--- a/web/app/assets/javascripts/dialog/rsvpCancelDialog.js
+++ b/web/app/assets/javascripts/dialog/rsvpCancelDialog.js
@@ -21,7 +21,7 @@
$('.session-name', $dialog).html(response.name);
$('.scheduled-start', $dialog).html(response.pretty_scheduled_start_with_timezone);
- if (response.recurring_mode !== null) {
+ if (response.recurring_mode !== null && response.recurring_mode !== 'once') {
$('.schedule-recurrence', $dialog).html("Recurs " + response.recurring_mode + " on this day at this time");
}
}
diff --git a/web/app/assets/javascripts/dialog/rsvpSubmitDialog.js b/web/app/assets/javascripts/dialog/rsvpSubmitDialog.js
index 03ccb6a5f..9b29fcb28 100644
--- a/web/app/assets/javascripts/dialog/rsvpSubmitDialog.js
+++ b/web/app/assets/javascripts/dialog/rsvpSubmitDialog.js
@@ -24,7 +24,7 @@
$('.scheduled-start', $dialog).html(response.pretty_scheduled_start_with_timezone);
- if (response.recurring_mode !== null && response.recurring_mode === 'weekly') {
+ if (response.recurring_mode !== null && response.recurring_mode !== 'once') {
$('.schedule-recurrence', $dialog).html("Recurs " + response.recurring_mode + " on this day at this time");
}
diff --git a/web/app/assets/javascripts/hoverBand.js b/web/app/assets/javascripts/hoverBand.js
index b167baddc..ccc8c4fe5 100644
--- a/web/app/assets/javascripts/hoverBand.js
+++ b/web/app/assets/javascripts/hoverBand.js
@@ -24,7 +24,7 @@
instrumentHtml = '
';
if (val.instruments) { // @FIXME: edge case for Test user that has no instruments?
$.each(val.instruments, function(index, instrument) {
- instrumentHtml += '  + ') ';
+ instrumentHtml += '  + ') ';
});
}
diff --git a/web/app/assets/javascripts/hoverMusician.js b/web/app/assets/javascripts/hoverMusician.js
index 7cac6517e..5e3b5777f 100644
--- a/web/app/assets/javascripts/hoverMusician.js
+++ b/web/app/assets/javascripts/hoverMusician.js
@@ -20,7 +20,7 @@
// instruments
var instrumentHtml = '';
$.each(response.instruments, function(index, val) {
- instrumentHtml += ' ';
+ instrumentHtml += ' ';
});
// followings
@@ -88,7 +88,7 @@
var latencyBadge = context._.template(
$templateLatency.html(),
- $.extend(sessionUtils.createLatency(response), response),
+ $.extend(response, sessionUtils.createLatency(response)),
{variable: 'data'}
);
diff --git a/web/app/assets/javascripts/hoverRecording.js b/web/app/assets/javascripts/hoverRecording.js
index 5321df114..9cadedf27 100644
--- a/web/app/assets/javascripts/hoverRecording.js
+++ b/web/app/assets/javascripts/hoverRecording.js
@@ -58,7 +58,7 @@
instrumentHtml = ' ';
$.each(val.instrument_ids, function(index, val) {
- instrumentHtml += '  + ') ';
+ instrumentHtml += '  + ') ';
});
instrumentHtml += ' | ';
diff --git a/web/app/assets/javascripts/hoverSession.js b/web/app/assets/javascripts/hoverSession.js
index d64dfee71..0d7577167 100644
--- a/web/app/assets/javascripts/hoverSession.js
+++ b/web/app/assets/javascripts/hoverSession.js
@@ -25,7 +25,7 @@
instrumentHtml = ' ';
var instruments = val.instruments.split("|");
$.each(instruments, function(index, instrument) {
- instrumentHtml += '  + ') ';
+ instrumentHtml += '  + ') ';
});
instrumentHtml += ' | ';
diff --git a/web/app/assets/javascripts/jamkazam.js b/web/app/assets/javascripts/jamkazam.js
index d8fb6e4aa..ba3d4e25b 100644
--- a/web/app/assets/javascripts/jamkazam.js
+++ b/web/app/assets/javascripts/jamkazam.js
@@ -22,7 +22,8 @@
var rest = context.JK.Rest();
var inBadState = false;
var userDeferred = null;
-
+ var userData = null;
+ var self = this;
var opts = {
inClient: true, // specify false if you want the app object but none of the client-oriented features
@@ -301,6 +302,7 @@
logger.debug("updating user info")
userDeferred = update; // update the global user object if this succeeded
})
+ update.done(this.updateUserCache)
return update;
}
@@ -309,6 +311,15 @@
return userDeferred;
}
+ // gets the most recent user data. can be null when app is still initializing.
+ // user app.user() if initialize sequence is unknown/asynchronous
+ this.currentUser = function() {
+ if(userData == null) {
+ throw "currentUser has null user data"
+ }
+ return userData;
+ }
+
this.activeElementEvent = function(evtName, data) {
return this.layout.activeElementEvent(evtName, data);
}
@@ -333,6 +344,10 @@
}
};
+ this.updateUserCache = function(_userData) {
+ userData = _userData
+ }
+
this.initialize = function (inOpts) {
var url, hash;
app = this;
@@ -343,6 +358,7 @@
this.layout.handleDialogState();
userDeferred = rest.getUserDetail();
+ userDeferred.done(this.updateUserCache)
if (opts.inClient) {
registerBadStateRecovered();
diff --git a/web/app/assets/javascripts/mods_utils.js.coffee b/web/app/assets/javascripts/mods_utils.js.coffee
index b10250c32..bb06f4605 100644
--- a/web/app/assets/javascripts/mods_utils.js.coffee
+++ b/web/app/assets/javascripts/mods_utils.js.coffee
@@ -12,6 +12,7 @@ class ModUtils
init: () =>
+
# creates a new show structure suitable for applying to a user update
noShow: (noShowName) =>
noShowValue = {}
@@ -31,5 +32,11 @@ class ModUtils
deferred.resolve(shouldShowForName)
))
return deferred;
+
+ # returns a gear mod by name
+ getGear: (name) =>
+ gear = context.JK.app.currentUser().mods?.gear
+ if gear? then gear[name] else undefined
+
# global instance
context.JK.ModUtils = new ModUtils()
\ No newline at end of file
diff --git a/web/app/assets/javascripts/sessionList.js b/web/app/assets/javascripts/sessionList.js
index 2dae2c083..3f3ee478d 100644
--- a/web/app/assets/javascripts/sessionList.js
+++ b/web/app/assets/javascripts/sessionList.js
@@ -380,7 +380,7 @@
var track = participant.tracks[j];
logger.debug("Find:Finding instruments. Participant tracks:", participant.tracks);
var inst = context.JK.getInstrumentIcon24(track.instrument_id);
- instrumentLogoHtml += '  ';
+ instrumentLogoHtml += '  ';
}
var id = participant.user.id;
@@ -411,7 +411,7 @@
for (j=0; j < user.instrument_list.length; j++) {
var instrument = user.instrument_list[j];
var inst = context.JK.getInstrumentIcon24(instrument.id);
- instrumentLogoHtml += '  ';
+ instrumentLogoHtml += '  ';
}
}
diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js
index b7641dbbc..398678e43 100644
--- a/web/app/assets/javascripts/utils.js
+++ b/web/app/assets/javascripts/utils.js
@@ -88,6 +88,7 @@
var instrumentIconMap24 = {};
var instrumentIconMap45 = {};
var instrumentIconMap256 = {};
+ var notSpecifiedText = "Not specified";
$.each(icon_map_base, function (instrumentId, icon) {
instrumentIconMap24[instrumentId] = {asset: "/assets/content/icon_instrument_" + icon + "24.png", name: instrumentId};
@@ -507,6 +508,10 @@
return instrumentIconMap256["_default"].asset;
};
+ context.JK.getInstrumentId = function(instrumentId) {
+ return instrumentId ? instrumentId : notSpecifiedText;
+ }
+
// meant to pass in a bunch of images with an instrument-id attribute on them.
context.JK.setInstrumentAssetPath = function ($elements) {
diff --git a/web/app/assets/javascripts/wizard/frame_buffers.js b/web/app/assets/javascripts/wizard/frame_buffers.js
index f96dde085..a19fdfdf7 100644
--- a/web/app/assets/javascripts/wizard/frame_buffers.js
+++ b/web/app/assets/javascripts/wizard/frame_buffers.js
@@ -9,11 +9,14 @@
var $bufferIn = null;
var $bufferOut = null;
var $frameSize = null;
+ var $adjustSettingsLink = null;
var $self = $(this);
+ var logger = context.JK.logger;
var FRAMESIZE_CHANGED = 'frame_buffers.framesize_changed';
var BUFFER_IN_CHANGED = 'frame_buffers.buffer_in_changed';
var BUFFER_OUT_CHANGED = 'frame_buffers.buffer_out_changed';
+ var ADJUST_GEAR_LINK_CLICKED = 'frame_buffers.adjust_gear_settings_clicked';
function selectedFramesize() {
return parseFloat($frameSize.val());
@@ -77,6 +80,12 @@
logger.debug("buffer-out changed: " + selectedBufferOut());
$self.triggerHandler(BUFFER_OUT_CHANGED, {value: selectedBufferOut()});
});
+
+ $adjustSettingsLink.click(function() {
+ logger.debug("adjust-gear-settings clicked");
+ $self.triggerHandler(ADJUST_GEAR_LINK_CLICKED);
+ return false;
+ });
}
function initialize(_$knobs) {
@@ -89,6 +98,7 @@
$bufferIn = $knobs.find('.select-buffer-in');
$bufferOut = $knobs.find('.select-buffer-out');
$frameSize = $knobs.find('.select-frame-size');
+ $adjustSettingsLink = $knobs.find('.adjust-gear-settings')
events();
render();
@@ -97,6 +107,7 @@
this.FRAMESIZE_CHANGED = FRAMESIZE_CHANGED;
this.BUFFER_IN_CHANGED = BUFFER_IN_CHANGED;
this.BUFFER_OUT_CHANGED = BUFFER_OUT_CHANGED;
+ this.ADJUST_GEAR_LINK_CLICKED = ADJUST_GEAR_LINK_CLICKED;
this.initialize = initialize;
this.selectedFramesize = selectedFramesize;
this.selectedBufferIn = selectedBufferIn;
diff --git a/web/app/assets/javascripts/wizard/gear/gear_wizard.js b/web/app/assets/javascripts/wizard/gear/gear_wizard.js
index 349032d8c..cb0cd4317 100644
--- a/web/app/assets/javascripts/wizard/gear/gear_wizard.js
+++ b/web/app/assets/javascripts/wizard/gear/gear_wizard.js
@@ -13,6 +13,7 @@
var $wizardSteps = null;
var $templateSteps = null;
var loopbackWizard = null;
+ var adjustGearSettings = null;
var inputs = null;
var self = this;
@@ -183,9 +184,10 @@
return inputs;
}
- function initialize(_loopbackWizard) {
+ function initialize(_loopbackWizard, _adjustGearSettings) {
loopbackWizard = _loopbackWizard;
+ adjustGearSettings = _adjustGearSettings;
// on initial page load, we are not in the FTUE. so cancel the FTUE and call FTUESetStatus(true) if needed
if(context.jamClient.FTUEGetStatus() == false) {
@@ -224,6 +226,7 @@
this.createFTUEProfile = createFTUEProfile;
this.getWizard = function() {return wizard; }
this.getLoopbackWizard = function() { return loopbackWizard; };
+ this.getAdjustGearSettings = function() { return adjustGearSettings; };
self = this;
return this;
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 f76e0abaf..ac9a40c25 100644
--- a/web/app/assets/javascripts/wizard/gear/step_direct_monitoring.js
+++ b/web/app/assets/javascripts/wizard/gear/step_direct_monitoring.js
@@ -5,9 +5,11 @@
context.JK = context.JK || {};
context.JK.StepDirectMonitoring = function (app) {
+ var EVENTS = context.JK.EVENTS;
var logger = context.JK.logger;
var $step = null;
var $directMonitoringBtn = null;
+ var $adjustSettingsDirectMonitor = null;
var isPlaying = false;
var playCheckInterval = null;
var trackDurationMs = null;
@@ -83,12 +85,29 @@
}
}
+ function onAdjustGearRequested() {
+ app.layout.showDialog('adjust-gear-speed-dialog').one(EVENTS.DIALOG_CLOSED, function(e, data) {
+
+ var adjustGearTest = data.result;
+
+ if(!data.canceled) {
+ if(adjustGearTest.isGoodFtue()) {
+
+ }
+ }
+ else {
+ logger.debug("adjust-gear-speed was cancelled; ignoring")
+ }
+ })
+ }
+
function initialize(_$step) {
$step = _$step;
$directMonitoringBtn = $step.find('.test-direct-monitoring');
-
$directMonitoringBtn.on('click', togglePlay);
+ $adjustSettingsDirectMonitor = $step.find('.adjust-settings-direct-monitor');
+ $adjustSettingsDirectMonitor.on('click', onAdjustGearRequested)
}
this.handleHelp = handleHelp;
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 d1d53543f..9479f86c9 100644
--- a/web/app/assets/javascripts/wizard/gear/step_select_gear.js
+++ b/web/app/assets/javascripts/wizard/gear/step_select_gear.js
@@ -11,6 +11,7 @@
var VOICE_CHAT = context.JK.VOICE_CHAT;
var AUDIO_DEVICE_BEHAVIOR = context.JK.AUDIO_DEVICE_BEHAVIOR;
var gearUtils = context.JK.GearUtils;
+ var modUtils = context.JK.ModUtils;
var self = null;
var $step = null;
@@ -19,6 +20,7 @@
var frameBuffers = new context.JK.FrameBuffers(app);
var gearTest = new context.JK.GearTest(app);
var loopbackShowing = false;
+ var adjustGearSettingsShowing = 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
@@ -32,6 +34,8 @@
var $inputChannels = null;
var $outputChannels = null;
var $knobs = null;
+ var $adjustSettingsLink = null;
+ var $adjustGearForIoFail = null;
var $scoreReport = null;
var $asioInputControlBtn = null;
var $asioOutputControlBtn = null;
@@ -86,7 +90,7 @@
}
function initializeNextButtonState() {
- dialog.setNextState(gearTest.isGoodFtue() || dialog.getLoopbackWizard().getGearTest().isGoodFtue());
+ dialog.setNextState(gearTest.isGoodFtue() || dialog.getLoopbackWizard().getGearTest().isGoodFtue() || dialog.getAdjustGearSettings().getGearTest().isGoodFtue());
}
function initializeBackButtonState() {
@@ -365,8 +369,9 @@
if(dialog.getLoopbackWizard().getGearTest().isGoodFtue()) {
gearTest.resetScoreReport();
gearTest.showLoopbackDone();
- context.JK.prodBubble(dialog.getWizard().getNextButton(), 'move-on-loopback-success', {}, {positions:['top']});
-
+ setTimeout(function() {
+ context.JK.prodBubble(dialog.getWizard().getNextButton(), 'can-move-on', {}, {positions:['top'], offsetParent: dialog.getWizard().getDialog()});
+ }, 300);
}
initializeNextButtonState();
@@ -379,6 +384,42 @@
})
}
+ function onAdjustGearRequested()
+ {
+ if(gearTest.isScoring()) {logger.debug("ignoring adjust-gear request while scoring"); return false;}
+
+ app.layout.showDialog('adjust-gear-speed-dialog').one(EVENTS.DIALOG_CLOSED, function(e, data) {
+ adjustGearSettingsShowing = false;
+
+ var adjustGearTest = data.result;
+
+ if(!data.canceled) {
+ if(adjustGearTest.isGoodFtue()) {
+ // update our own frame buffers to reflect any changes made by the adjust dialog
+ frameBuffers.setFramesize(context.jamClient.FTUEGetFrameSize())
+ frameBuffers.setBufferIn(context.jamClient.FTUEGetInputLatency())
+ frameBuffers.setBufferOut(context.jamClient.FTUEGetOutputLatency())
+
+ gearTest.resetScoreReport();
+ gearTest.showGearAdjustmentDone();
+
+ setTimeout(function() {
+ context.JK.prodBubble(dialog.getWizard().getNextButton(), 'can-move-on', {}, {positions:['top'], offsetParent: dialog.getWizard().getDialog()});
+ }, 300);
+ }
+
+ initializeNextButtonState();
+ initializeBackButtonState();
+ }
+ else {
+ logger.debug("adjust-gear-speed was cancelled; ignoring")
+ }
+ })
+
+ adjustGearSettingsShowing = true;
+ return false;
+ }
+
function initializeFormElements() {
if (!deviceInformation) throw "devices are not initialized";
@@ -486,6 +527,7 @@
function invalidateScore() {
gearTest.invalidateScore();
dialog.getLoopbackWizard().getGearTest().invalidateScore();
+ dialog.getAdjustGearSettings().getGearTest().invalidateScore();
initializeNextButtonState();
}
@@ -755,6 +797,7 @@
validDevice = autoSelectMinimumValidChannels();
if (!validDevice) {
+ $adjustSettingsLink.hide();
return false;
}
@@ -774,6 +817,11 @@
shownOutputProdOnce = true;
}
+ // further, check if we have both inputs and outputs defined; if so, show ? to allow launch of adjust gear settings dialog
+ if(modUtils.getGear('show_frame_options')) {
+ $adjustSettingsLink.show();
+ }
+
return true;
}
@@ -821,11 +869,12 @@
}
// handle framesize/buffers
- if (inputBehavior && (inputBehavior.showKnobs || outputBehavior.showKnobs)) {
+ if (inputBehavior && (inputBehavior.showKnobs || outputBehavior.showKnobs || modUtils.getGear('show_frame_options'))) {
$knobs.show();
}
else {
$knobs.hide();
+ $adjustSettingsLink.hide();
}
// handle ASIO visibility
@@ -865,36 +914,9 @@
jamClient.FTUESetFrameSize(frameBuffers.selectedFramesize());
}
+
function updateDefaultBuffers() {
-
- // handle specific framesize settings
- if(selectedDeviceInfo && (selectedDeviceInfo.input.info.type == 'Win32_wdm' || selectedDeviceInfo.output.info.type == 'Win32_wdm')) {
- var framesize = frameBuffers.selectedFramesize();
-
- if(framesize == 2.5) {
- logger.debug("setting default buffers to 1/1");
- frameBuffers.setBufferIn('1');
- frameBuffers.setBufferOut('1');
- }
- else if(framesize == 5) {
- logger.debug("setting default buffers to 3/2");
- frameBuffers.setBufferIn('3');
- frameBuffers.setBufferOut('2');
- }
- else {
- logger.debug("setting default buffers to 6/5");
- frameBuffers.setBufferIn('6');
- frameBuffers.setBufferOut('5');
- }
- }
- else {
- logger.debug("setting default buffers to 0/0");
- frameBuffers.setBufferIn(0);
- frameBuffers.setBufferOut(0);
- }
-
- jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn());
- jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut());
+ gearUtils.updateDefaultBuffers(selectedDeviceInfo, frameBuffers)
}
// refocused affects how IO testing occurs.
@@ -940,11 +962,26 @@
}
}
+ function prodUserToTweakASIOSettings($btn) {
+ setTimeout(function() {
+ context.JK.prodBubble($btn, 'tweak-asio-settings', {}, {positions:['top']});
+ }, 300)
+ }
+
function onGearTestFail(e, data) {
renderScoringStopped();
gearUtils.postDiagnostic(operatingSystem, deviceInformation, selectedDeviceInfo, gearTest, frameBuffers, true);
if(data.reason == "latency") {
+
+ console.log("selectedDeviceInfo", selectedDeviceInfo)
+ if(selectedDeviceInfo.input.info.type.indexOf('Win32_asio') > -1) {
+ prodUserToTweakASIOSettings($asioInputControlBtn)
+ }
+ else if(selectedDeviceInfo.output.info.type.indexOf('Win32_asio') > -1) {
+ prodUserToTweakASIOSettings($asioOutputControlBtn)
+ }
+
storeLastFailureForAnalytics(context.JK.detectOS(), context.JK.GA.AudioTestFailReasons.latency, data.latencyScore);
}
else if(data.reason = "io") {
@@ -973,11 +1010,13 @@
var specificResolutions = [];
- if(selectedDeviceInfo.input.behavior.type.indexOf('Win32_asio') > -1 || selectedDeviceInfo.output.behavior.type.indexOf('Win32_asio') > -1) {
+ if(selectedDeviceInfo.input.info.type.indexOf('Win32_asio') > -1 || selectedDeviceInfo.output.info.type.indexOf('Win32_asio') > -1) {
+ // specificResolutions.push("Read over this article")
specificResolutions.push("Select the ASIO SETTINGS... button and try different settings.");
}
- if(selectedDeviceInfo.input.behavior.type == 'Win32_wdm' || selectedDeviceInfo.output.behavior.type == 'Win32_wdm') {
+ if(selectedDeviceInfo.input.info.type == 'Win32_wdm' || selectedDeviceInfo.output.info.type == 'Win32_wdm') {
+ // specificResolutions.push("Read over this article")
specificResolutions.push("Change the Frame, Buffer In, or Buffer Out settings.");
}
@@ -1063,7 +1102,7 @@
}
function onFocus() {
- if(validDevice && !loopbackShowing && !gearTest.isScoring() && getSelectedInputs().length > 0 && getSelectedOutputs().length == 2 ) {
+ if(validDevice && !loopbackShowing && !adjustGearSettingsShowing && !gearTest.isScoring() && getSelectedInputs().length > 0 && getSelectedOutputs().length == 2 ) {
scheduleRescanSystem(function() { attemptScore(true); }, 3000, false)
}
}
@@ -1160,6 +1199,8 @@
$inputChannels = $step.find('.input-ports');
$outputChannels = $step.find('.output-ports');
$knobs = $step.find('.frame-and-buffers');
+ $adjustSettingsLink = $knobs.find('.adjust-gear-settings')
+ $adjustGearForIoFail = $step.find(".adjust-gear-for-io-fail")
$scoreReport = $step.find('.results');
$asioInputControlBtn = $step.find('.asio-settings-input-btn');
$asioOutputControlBtn = $step.find('.asio-settings-output-btn');
@@ -1175,6 +1216,7 @@
.on(frameBuffers.FRAMESIZE_CHANGED, onFramesizeChanged)
.on(frameBuffers.BUFFER_IN_CHANGED, onBufferInChanged)
.on(frameBuffers.BUFFER_OUT_CHANGED, onBufferOutChanged)
+ .on(frameBuffers.ADJUST_GEAR_LINK_CLICKED, onAdjustGearRequested)
gearTest.initialize($scoreReport, true)
$(gearTest)
@@ -1182,6 +1224,7 @@
.on(gearTest.GEAR_TEST_DONE, onGearTestDone)
.on(gearTest.GEAR_TEST_FAIL, onGearTestFail)
.on(gearTest.GEAR_TEST_INVALIDATED_ASYNC, onGearTestInvalidated)
+ $adjustGearForIoFail.click(onAdjustGearRequested);
}
this.getLastAudioTestFailAnalytics = getLastAudioTestFailAnalytics;
diff --git a/web/app/assets/javascripts/wizard/gear_test.js b/web/app/assets/javascripts/wizard/gear_test.js
index 7b56534db..fc397c2f9 100644
--- a/web/app/assets/javascripts/wizard/gear_test.js
+++ b/web/app/assets/javascripts/wizard/gear_test.js
@@ -33,6 +33,8 @@
var $resultsText = null;
var $unknownText = null;
var $loopbackCompleted = null;
+ var $adjustGearSpeedCompleted = null;
+ var $adjustGearForIoFail = null;
var $ioScoreSection = null;
var $latencyScoreSection = null;
@@ -78,6 +80,10 @@
medianIOClass = 'acceptable';
}
+ // uncomment one to force a particular type of I/O failure
+ // medianIOClass = "bad";
+ // stdIOClass = "bad"
+
// take worst between median or std
var ioClassToNumber = {bad: 2, acceptable: 1, good: 0}
var aggregrateIOClass = ioClassToNumber[stdIOClass] > ioClassToNumber[medianIOClass] ? stdIOClass : medianIOClass;
@@ -240,6 +246,10 @@
latencyClass = 'unknown';
}
+ // uncomment these two lines to fail test due to latency
+ // latencyClass = "bad";
+ // validLatency = false;
+
validLatencyScore = validLatency;
if(refocused) {
@@ -300,7 +310,7 @@
logger.debug("gear_test: onInvalidAudioDevice")
asynchronousInvalidDevice = true;
$self.triggerHandler(GEAR_TEST_INVALIDATED_ASYNC);
- context.JK.Banner.showAlert('Invalid Audio Device', 'It appears this audio device is not currently connected. Attach the device to your computer and restart the application, or select a different device.')
+ context.JK.Banner.showAlert('Invalid Audio Device', 'It appears this audio device is not currently connected. Attach the device to your computer and restart the application, or select a different device. If you think your gear is connected and working, this support article can help.')
}
@@ -308,6 +318,10 @@
$loopbackCompleted.show();
}
+ function showGearAdjustmentDone() {
+ $adjustGearSpeedCompleted.show();
+ }
+
function resetScoreReport() {
$ioHeader.hide();
$latencyHeader.hide();
@@ -322,6 +336,7 @@
$resultsText.removeAttr('scored');
$unknownText.hide();
$loopbackCompleted.hide();
+ $adjustGearSpeedCompleted.hide();
$ioScoreSection.removeClass('good acceptable bad unknown starting skip');
$latencyScoreSection.removeClass('good acceptable bad unknown starting')
}
@@ -398,6 +413,8 @@
$resultsText = $scoreReport.find('.results-text');
$unknownText = $scoreReport.find('.unknown-text');
$loopbackCompleted = $scoreReport.find('.loopback-completed')
+ $adjustGearSpeedCompleted = $scoreReport.find('.adjust-gear-speed-completed');
+ $adjustGearForIoFail = $scoreReport.find(".adjust-gear-for-io-fail")
$latencyScoreSection = $scoreReport.find('.latency-score-section');
function onGearTestStart(e, data) {
@@ -514,6 +531,7 @@
this.attemptScore = attemptScore;
this.resetScoreReport = resetScoreReport;
this.showLoopbackDone = showLoopbackDone;
+ this.showGearAdjustmentDone = showGearAdjustmentDone;
this.invalidateScore = invalidateScore;
this.isValidLatencyScore = isValidLatencyScore;
this.isValidIOScore = isValidIOScore;
diff --git a/web/app/assets/javascripts/wizard/gear_utils.js b/web/app/assets/javascripts/wizard/gear_utils.js
index ba5dd70e0..c9d67f533 100644
--- a/web/app/assets/javascripts/wizard/gear_utils.js
+++ b/web/app/assets/javascripts/wizard/gear_utils.js
@@ -145,6 +145,54 @@
return loadedDevices;
}
+ gearUtils.updateDefaultBuffers = function(selectedDeviceInfo, frameBuffers) {
+ function hasWDMAssociated() {
+ return selectedDeviceInfo && (selectedDeviceInfo.input.info.type == 'Win32_wdm' || selectedDeviceInfo.output.info.type == 'Win32_wdm')
+ }
+
+ function hasASIOAssociated() {
+ return selectedDeviceInfo && (selectedDeviceInfo.input.info.type == 'Win32_asio' || selectedDeviceInfo.output.info.type == 'Win32_asio')
+ }
+
+ // handle specific framesize settings
+ if(hasWDMAssociated() || hasASIOAssociated()) {
+ var framesize = frameBuffers.selectedFramesize();
+
+ if(framesize == 2.5) {
+ // if there is a WDM device, start off at 1/1 due to empirically observed issues with 0/0
+ if(hasWDMAssociated()) {
+ logger.debug("setting default buffers to 1/1");
+ frameBuffers.setBufferIn('1');
+ frameBuffers.setBufferOut('1');
+ }
+ else {
+ // otherwise, it's ASIO, so go with 0/0
+ logger.debug("setting default buffers to 0/0");
+ frameBuffers.setBufferIn('0');
+ frameBuffers.setBufferOut('0');
+ }
+ }
+ else if(framesize == 5) {
+ logger.debug("setting default buffers to 3/2");
+ frameBuffers.setBufferIn('3');
+ frameBuffers.setBufferOut('2');
+ }
+ else {
+ logger.debug("setting default buffers to 6/5");
+ frameBuffers.setBufferIn('6');
+ frameBuffers.setBufferOut('5');
+ }
+ }
+ else {
+ logger.debug("setting default buffers to 0/0");
+ frameBuffers.setBufferIn(0);
+ frameBuffers.setBufferOut(0);
+ }
+
+ context.jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn());
+ context.jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut());
+ }
+
gearUtils.ftueSummary = function(operatingSystem, deviceInformation, selectedDeviceInfo, gearTest, frameBuffers, isAutomated) {
return {
os: operatingSystem,
diff --git a/web/app/assets/javascripts/wizard/loopback/step_loopback_test.js b/web/app/assets/javascripts/wizard/loopback/step_loopback_test.js
index d22732519..ccba2ae88 100644
--- a/web/app/assets/javascripts/wizard/loopback/step_loopback_test.js
+++ b/web/app/assets/javascripts/wizard/loopback/step_loopback_test.js
@@ -58,35 +58,7 @@
}
function updateDefaultBuffers() {
-
- // handle specific framesize settings
- if(selectedDeviceInfo && (selectedDeviceInfo.input.info.type == 'Win32_wdm' || selectedDeviceInfo.output.info.type == 'Win32_wdm')) {
- var framesize = frameBuffers.selectedFramesize();
-
- if(framesize == 2.5) {
- logger.debug("setting default buffers to 1/1");
- frameBuffers.setBufferIn('1');
- frameBuffers.setBufferOut('1');
- }
- else if(framesize == 5) {
- logger.debug("setting default buffers to 3/2");
- frameBuffers.setBufferIn('3');
- frameBuffers.setBufferOut('2');
- }
- else {
- logger.debug("setting default buffers to 6/5");
- frameBuffers.setBufferIn('6');
- frameBuffers.setBufferOut('5');
- }
- }
- else {
- logger.debug("setting default buffers to 0/0");
- frameBuffers.setBufferIn(0);
- frameBuffers.setBufferOut(0);
- }
-
- jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn());
- jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut());
+ gearUtils.updateDefaultBuffers(selectedDeviceInfo, frameBuffers)
}
function onFramesizeChanged() {
diff --git a/web/app/assets/javascripts/wizard/wizard.js b/web/app/assets/javascripts/wizard/wizard.js
index e3a6eaed3..6d8600e3e 100644
--- a/web/app/assets/javascripts/wizard/wizard.js
+++ b/web/app/assets/javascripts/wizard/wizard.js
@@ -217,6 +217,10 @@
return $currentWizardStep;
}
+ function getDialog() {
+ return $dialog;
+ }
+
function initialize(_$dialog, _$wizardSteps, _STEPS, _options) {
$dialog = _$dialog;
dialogName = $dialog.attr('layout-id');
@@ -239,6 +243,7 @@
this.onCloseDialog = onCloseDialog;
this.onBeforeShow = onBeforeShow;
this.onAfterHide = onAfterHide;
+ this.getDialog = getDialog;
this.initialize = initialize;
}
diff --git a/web/app/assets/stylesheets/client/wizard/framebuffers.css.scss b/web/app/assets/stylesheets/client/wizard/framebuffers.css.scss
index b3f205d3f..abc010194 100644
--- a/web/app/assets/stylesheets/client/wizard/framebuffers.css.scss
+++ b/web/app/assets/stylesheets/client/wizard/framebuffers.css.scss
@@ -14,6 +14,10 @@
width:45%;
}
+ .adjust-gear-settings {
+ display:none;
+ margin-left:4px;
+ }
.buffers {
float:left;
diff --git a/web/app/assets/stylesheets/client/wizard/gearResults.css.scss b/web/app/assets/stylesheets/client/wizard/gearResults.css.scss
index 4710ba12c..a542212a7 100644
--- a/web/app/assets/stylesheets/client/wizard/gearResults.css.scss
+++ b/web/app/assets/stylesheets/client/wizard/gearResults.css.scss
@@ -20,6 +20,11 @@
display:inline;
}
}
+ &[data-type=adjust-gear-speed] {
+ span.conditional[data-type=adjust-gear-speed] {
+ display:inline;
+ }
+ }
.io, .latency {
display: none;
}
@@ -47,7 +52,7 @@
padding: 8px;
}
- .loopback-completed {
+ .loopback-completed, .adjust-gear-speed-completed {
display:none;
}
@@ -115,6 +120,14 @@
display: none
}
+ span.io-failure {
+ display:none;
+ }
+
+ %span.no-io-failure {
+ display:inline;
+ }
+
&[latency-score="unknown"] {
display: none;
}
@@ -159,6 +172,16 @@
}
}
+ &[io-rate-score="bad"], &[io-var-score="bad"] {
+ span.io-failure {
+ display:inline;
+ }
+
+ span.no-io-failure {
+ display:none;
+ }
+ }
+
&[latency-score="unknown"] {
li.success {
display: none;
diff --git a/web/app/assets/stylesheets/client/wizard/gearWizard.css.scss b/web/app/assets/stylesheets/client/wizard/gearWizard.css.scss
index 3a7572ec4..29d498f69 100644
--- a/web/app/assets/stylesheets/client/wizard/gearWizard.css.scss
+++ b/web/app/assets/stylesheets/client/wizard/gearWizard.css.scss
@@ -274,7 +274,7 @@
}
.watch-video {
- margin-top: 26px;
+ margin-top: 12px;
}
.help-content {
diff --git a/web/app/assets/stylesheets/dialogs/adjustGearSpeedDialog.css.scss b/web/app/assets/stylesheets/dialogs/adjustGearSpeedDialog.css.scss
new file mode 100644
index 000000000..2bdcb6d7f
--- /dev/null
+++ b/web/app/assets/stylesheets/dialogs/adjustGearSpeedDialog.css.scss
@@ -0,0 +1,160 @@
+@import "client/common.css.scss";
+@charset "UTF-8";
+#adjust-gear-speed-dialog {
+ min-height: 420px;
+ max-height: 420px;
+ width:800px;
+
+ h2 {
+ color: #FFFFFF;
+ font-size: 15px;
+ font-weight: normal;
+ margin-bottom: 6px;
+ white-space:nowrap;
+
+ }
+
+ h2.settings {
+ display:inline;
+ position:absolute;
+ left:0;
+ margin-left:0; // override global .settings from sessions.css
+ }
+
+ .ftue-box {
+ background-color: #222222;
+ font-size: 13px;
+ padding: 8px;
+ }
+
+ .dialog-inner {
+ line-height: 1.3em;
+ width:800px;
+ padding:25px;
+ font-size:15px;
+ color:#aaa;
+ @include border_box_sizing;
+
+ }
+
+ .dialog-column {
+
+ @include border_box_sizing;
+
+ &:nth-of-type(1) {
+ width:75%;
+ margin-top:38px;
+ }
+
+ &:nth-of-type(2) {
+ width:25%;
+ float:right;
+ }
+ }
+
+ .speed-options {
+ display:inline-block;
+ width:60%;
+ margin:auto;
+ margin-left:25%;
+ }
+
+ .speed-option {
+ @include border_box_sizing;
+ float:left;
+ width:33%;
+ text-align:center;
+
+ .iradio_minimal {
+ margin:auto;
+ display:inline-block;
+ }
+
+ label {
+ display:inline-block;
+ margin-left: 10px;
+ position: relative;
+ top: -3px;
+ }
+ }
+
+ .speed-text {
+ margin:10px 0;
+ }
+
+ .run-test-btn {
+ margin-top:5px;
+ margin-left:25px;
+ left:40%;
+ position:relative;
+ }
+
+ .frame-and-buffers {
+ display:inline-block;
+ margin-left:30%;
+
+ .framesize {
+ width:auto;
+ display:inline-block;
+ }
+
+ .buffers {
+ width:auto;
+ display:inline-block;
+ margin-left:20px;
+ }
+ h2 {
+ display:inline-block;
+ line-height:18px;
+ vertical-align: top;
+ }
+
+ .easydropdown-wrapper {
+ display:inline-block;
+ top:-3px;
+ margin-left:8px;
+ }
+
+
+ .select-frame-size {
+ margin-left:-2px;
+ }
+ }
+
+ .help-text {
+ margin-bottom:20px;
+ }
+
+ .basic {
+ margin:0 5px 20px 0;
+ }
+ .advanced {
+ display:none;
+ border-width:1px 0 0 0;
+ border-style:solid;
+ border-color:white;
+ padding-top:20px;
+ margin:0 5px 0 0;
+ .help-text {
+ text-align:left;
+ }
+ }
+
+ .test-results-header {
+ position:static;
+ }
+
+
+ .ftue-box.results {
+ margin-top:20px;
+ height: 268px !important;
+ padding:0;
+ @include border_box_sizing;
+ }
+
+ h2.results-text-header {
+ margin-top:5px;
+ }
+
+
+}
diff --git a/web/app/views/clients/_help.html.erb b/web/app/views/clients/_help.html.erb
index 66ac73135..7623897dc 100644
--- a/web/app/views/clients/_help.html.erb
+++ b/web/app/views/clients/_help.html.erb
@@ -30,8 +30,14 @@
Push 'Resync' when done modifying Framesize, Buffer In, or Buffer Out.
-
+
+
|