diff --git a/web/app/assets/javascripts/accounts.js b/web/app/assets/javascripts/accounts.js index c01cb12ed..c8dc122d9 100644 --- a/web/app/assets/javascripts/accounts.js +++ b/web/app/assets/javascripts/accounts.js @@ -28,15 +28,20 @@ var audioProfiles = prettyPrintAudioProfiles(context.jamClient.TrackGetDevices()); + var badAudioConfigs = context.JK.getBadAudioConfigs(); + var template = context.JK.fillTemplate($('#template-account-main').html(), { email: userDetail.email, name: userDetail.name, location : userDetail.location, instruments : prettyPrintInstruments(userDetail.instruments), photoUrl : context.JK.resolveAvatarUrl(userDetail.photo_url), - profiles : audioProfiles + validProfiles : audioProfiles, + invalidProfiles : badAudioConfigs.length > 0 ? badAudioConfigs.join(", ") : "N/A" }); - $('#account-content-scroller').html(template ); + $('#account-content-scroller').html(template); + + badAudioConfigs.join(", "); } function prettyPrintAudioProfiles(devices) { diff --git a/web/app/assets/javascripts/accounts_audio_profile.js b/web/app/assets/javascripts/accounts_audio_profile.js index b174689bc..853dec0b1 100644 --- a/web/app/assets/javascripts/accounts_audio_profile.js +++ b/web/app/assets/javascripts/accounts_audio_profile.js @@ -30,21 +30,30 @@ function populateAccountAudio() { - // load Audio Driver dropdown - var devices = context.jamClient.TrackGetDevices(); + $('#account-audio-content-scroller table tbody').html(''); + var badAudioConfigs = context.JK.getBadAudioConfigs(); + + // render valid device profiles var options = { - devices: devices + configurations: context.JK.getGoodAudioConfigs(), + valid: 1 } var template = context._.template($('#template-account-audio').html(), options, {variable: 'data'}); - appendAudio(template); + // render invalid device profiles + options = { + configurations: badAudioConfigs, + valid: 0 + } + template = context._.template($('#template-account-audio').html(), options, {variable: 'data'}); + appendAudio(template); } function appendAudio(template) { - $('#account-audio-content-scroller table tbody').replaceWith(template); + $('#account-audio-content-scroller table tbody').append(template); } function resetForm() { diff --git a/web/app/assets/javascripts/createSession.js.erb b/web/app/assets/javascripts/createSession.js.erb index 16b8214dd..441585424 100644 --- a/web/app/assets/javascripts/createSession.js.erb +++ b/web/app/assets/javascripts/createSession.js.erb @@ -186,7 +186,7 @@ context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.create); }, error: function() { - app.ajaxError(arguments); + app.notifyServerError(arguments0, "Unable to Create Session"); $('#btn-create-session').removeClass('button-disabled'); $('#btn-create-session').unbind('click', false); } diff --git a/web/app/assets/javascripts/fakeJamClient.js b/web/app/assets/javascripts/fakeJamClient.js index 0039b4acf..c5286a53f 100644 --- a/web/app/assets/javascripts/fakeJamClient.js +++ b/web/app/assets/javascripts/fakeJamClient.js @@ -140,6 +140,14 @@ return ['a']; } + function FTUEGetAllAudioConfigurations() { + return ['a']; + } + + function FTUEGetGoodAudioConfigurations() { + return ['a']; + } + function RegisterVolChangeCallBack(functionName) { dbg('RegisterVolChangeCallBack'); } @@ -664,6 +672,8 @@ this.FTUEStartLatency = FTUEStartLatency; this.FTUEGetExpectedLatency = FTUEGetExpectedLatency; this.FTUEGetGoodConfigurationList = FTUEGetGoodConfigurationList; + this.FTUEGetAllAudioConfigurations = FTUEGetAllAudioConfigurations; + this.FTUEGetGoodAudioConfigurations = FTUEGetGoodAudioConfigurations; // Session this.SessionAddTrack = SessionAddTrack; diff --git a/web/app/assets/javascripts/ftue.js b/web/app/assets/javascripts/ftue.js index d090b7f91..86ae14cc8 100644 --- a/web/app/assets/javascripts/ftue.js +++ b/web/app/assets/javascripts/ftue.js @@ -465,9 +465,14 @@ ]; var optionsHtml = ''; var deviceOptionFunc = function (deviceKey, index, list) { - optionsHtml += ''; + optionsHtml += ''; }; + var badDeviceOptionFunc = function(deviceKey, index, list) { + optionsHtml += ''; + }; + + var badAudioConfigs = context.JK.getBadAudioConfigs(); + for (var i = 0; i < funcs.length; i++) { optionsHtml = ''; @@ -476,10 +481,11 @@ $select.empty(); var sortedDeviceKeys = context._.keys(devices).sort(); context._.each(sortedDeviceKeys, deviceOptionFunc); + context._.each(badAudioConfigs, badDeviceOptionFunc); $select.html(optionsHtml); context.JK.dropdown($select); $select.removeAttr("disabled"); - $('[layout-wizard-step="2"] .settings-asio select').removeAttr("disabled").easyDropDown('enable') + $('[layout-wizard-step="2"] .settings-asio select').removeAttr("disabled").easyDropDown('enable'); // Set selects to lowest possible values to start: $('#asio-framesize').val('2.5').change(); $('#asio-input-latency').val('0').change(); @@ -505,6 +511,12 @@ drivers[driverKey] + ''; }; + var badDeviceOptionFunc = function(deviceKey, index, list) { + optionsHtml += ''; + }; + + var badAudioConfigs = context.JK.getBadAudioConfigs(); + var optionsHtml = ''; var selectors = [ '[layout-wizard-step="0"] .settings-2-device select', @@ -513,6 +525,7 @@ ]; var sortedDeviceKeys = context._.keys(drivers).sort(); context._.each(sortedDeviceKeys, driverOptionFunc); + context._.each(badAudioConfigs, badDeviceOptionFunc); $.each(selectors, function (index, selector) { var $select = $(selector); $select.empty(); diff --git a/web/app/assets/javascripts/invitationDialog.js.erb b/web/app/assets/javascripts/invitationDialog.js.erb index 875cfb704..c0b2a3794 100644 --- a/web/app/assets/javascripts/invitationDialog.js.erb +++ b/web/app/assets/javascripts/invitationDialog.js.erb @@ -106,7 +106,7 @@ } else { rest.createEmailInvitations(emails, $('#txt-message').val()) .error(function() { - app.ajaxError(arguments); + app.ajaxError(); app.layout.closeDialog('inviteUsers'); }).success(function() { app.notifyAlert('Invites sent', 'You sent '+emails.length.toString()+' email invites'); diff --git a/web/app/assets/javascripts/sidebar.js b/web/app/assets/javascripts/sidebar.js index 79204b04e..5c085f6a0 100644 --- a/web/app/assets/javascripts/sidebar.js +++ b/web/app/assets/javascripts/sidebar.js @@ -101,7 +101,7 @@ userId: val.id, cssClass: css, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), - userName: val.name, + userName: val.name.length > 20 ? val.name.substring(0,20) + "..." : val.name, status: val.online ? 'Available' : 'Offline', extra_info: '', hoverAction: val.musician ? "musician" : "fan", diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js index 6ed8f2539..5392abc05 100644 --- a/web/app/assets/javascripts/utils.js +++ b/web/app/assets/javascripts/utils.js @@ -642,7 +642,25 @@ var result = context.jamClient.FTUEGetGoodConfigurationList(); console.log("hasOneConfiguredDevice: ", result); return result.length > 0; - } + }; + + context.JK.getGoodAudioConfigs = function() { + return context.jamClient.FTUEGetGoodAudioConfigurations(); + }; + + context.JK.getBadAudioConfigs = function() { + var badAudioConfigs = []; + var allAudioConfigs = context.jamClient.FTUEGetAllAudioConfigurations(); + var goodAudioConfigs = context.JK.getGoodAudioConfigs(); + + for (var i=0; i < allAudioConfigs.length; i++) { + if ($.inArray(allAudioConfigs[i], goodAudioConfigs) === -1) { + badAudioConfigs.push(allAudioConfigs[i]); + } + } + + return badAudioConfigs; + }; /* diff --git a/web/app/assets/stylesheets/client/account.css.scss b/web/app/assets/stylesheets/client/account.css.scss index 341969dac..35beafe14 100644 --- a/web/app/assets/stylesheets/client/account.css.scss +++ b/web/app/assets/stylesheets/client/account.css.scss @@ -162,7 +162,13 @@ } } + tr.invalid-profile { + background-color:red; + } + img.invalid-profile { + vertical-align:middle; + } .button-grey { margin-right:6px; diff --git a/web/app/controllers/api_invited_users_controller.rb b/web/app/controllers/api_invited_users_controller.rb index 3618dce56..87210a778 100644 --- a/web/app/controllers/api_invited_users_controller.rb +++ b/web/app/controllers/api_invited_users_controller.rb @@ -31,8 +31,16 @@ iu.save iu end + else + iu = InvitedUser.new + iu.sender = current_user + iu.save + @invited_users = [iu] + end + if err = @invited_users.detect {|iu| iu.errors.any? } + response.status = :unprocessable_entity + respond_with err end - respond_with @invited_users, :responder => ApiResponder, :location => invitations_url(@invited_users) end end diff --git a/web/app/views/clients/_account.html.erb b/web/app/views/clients/_account.html.erb index 8409ae2ae..b9baa122f 100644 --- a/web/app/views/clients/_account.html.erb +++ b/web/app/views/clients/_account.html.erb @@ -106,7 +106,8 @@
- Approved Profiles: {profiles} + Approved Profiles: {validProfiles}
+ Invalid Profiles: {invalidProfiles}
diff --git a/web/app/views/clients/_account_audio_profile.html.erb b/web/app/views/clients/_account_audio_profile.html.erb index c16a0394b..9470b27a2 100644 --- a/web/app/views/clients/_account_audio_profile.html.erb +++ b/web/app/views/clients/_account_audio_profile.html.erb @@ -34,25 +34,28 @@ -
ADD NEW PROFILE
BACK
+
+
+
+
+
+ — INVALID CONFIGURATION OR DEVICE NOT CONNECTED +
diff --git a/web/spec/requests/invited_users_api_spec.rb b/web/spec/requests/invited_users_api_spec.rb index 199a406b7..8097453e2 100644 --- a/web/spec/requests/invited_users_api_spec.rb +++ b/web/spec/requests/invited_users_api_spec.rb @@ -25,17 +25,15 @@ describe "Invited Users API ", :type => :api do end it "create with no note" do - post '/api/invited_users.json', {:email => 'tester@jamkazam.com'}.to_json, "CONTENT_TYPE" => 'application/json' - last_response.status.should eql(201) + post '/api/invited_users.json', {:emails => ['tester@jamkazam.com']}.to_json, "CONTENT_TYPE" => 'application/json' + last_response.status.should eql(200) UserMailer.deliveries.length.should == 1 - # now fetch it's data - location_header = last_response.headers["Location"] - get location_header - # parse json and test - body = JSON.parse(last_response.body) + bodies = JSON.parse(last_response.body) + expect(bodies.size).to eq(1) + body = bodies[0] body["id"].should_not be_nil body["created_at"].should_not be_nil body["email"].should == "tester@jamkazam.com" @@ -44,14 +42,12 @@ describe "Invited Users API ", :type => :api do end it "create with a note" do - post '/api/invited_users.json', {:email => 'tester@jamkazam.com', :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' - last_response.status.should eql(201) + post '/api/invited_users.json', {:emails => ['tester@jamkazam.com'], :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' + last_response.status.should eql(200) - # now fetch it's data - location_header = last_response.headers["Location"] - get location_header - - body = JSON.parse(last_response.body) + bodies = JSON.parse(last_response.body) + expect(bodies.length).to eq(1) + body = bodies[0] body["id"].should_not be_nil body["created_at"].should_not be_nil body["email"].should == "tester@jamkazam.com" @@ -63,7 +59,7 @@ describe "Invited Users API ", :type => :api do user.can_invite = false user.save - post '/api/invited_users.json', {:email => 'tester@jamkazam.com', :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' + post '/api/invited_users.json', {:emails => ['tester@jamkazam.com'], :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' last_response.status.should eql(422) body = JSON.parse(last_response.body) body["errors"].should_not be_nil @@ -79,7 +75,7 @@ describe "Invited Users API ", :type => :api do end it "cant create with blank email" do - post '/api/invited_users.json', {:email => "", :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' + post '/api/invited_users.json', {:emails => [""], :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' last_response.status.should eql(422) body = JSON.parse(last_response.body) body["errors"].should_not be_nil @@ -87,7 +83,7 @@ describe "Invited Users API ", :type => :api do end it "cant create with invalid email" do - post '/api/invited_users.json', {:email => "blurp", :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' + post '/api/invited_users.json', {:emails => ["blurp"], :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' last_response.status.should eql(422) body = JSON.parse(last_response.body) body["errors"].should_not be_nil @@ -95,14 +91,12 @@ describe "Invited Users API ", :type => :api do end it "list" do - post '/api/invited_users.json', {:email => "tester@jamkazam.com", :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' - last_response.status.should eql(201) + post '/api/invited_users.json', {:emails => ["tester@jamkazam.com"], :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' + last_response.status.should eql(200) - # now fetch it's data - location_header = last_response.headers["Location"] - get location_header - - body = JSON.parse(last_response.body) + bodies = JSON.parse(last_response.body) + expect(bodies.length).to eq(1) + body = bodies[0] id = body["id"] get '/api/invited_users.json', "CONTENT_TYPE" => 'application/json' @@ -115,14 +109,12 @@ describe "Invited Users API ", :type => :api do end it "show" do - post '/api/invited_users.json', {:email => "tester@jamkazam.com", :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' - last_response.status.should eql(201) + post '/api/invited_users.json', {:emails => ["tester@jamkazam.com"], :note => "please join"}.to_json, "CONTENT_TYPE" => 'application/json' + last_response.status.should eql(200) - # now fetch it's data - location_header = last_response.headers["Location"] - get location_header - - body = JSON.parse(last_response.body) + bodies = JSON.parse(last_response.body) + expect(bodies.length).to eq(1) + body = bodies[0] id = body["id"] get "/api/invited_users/#{id}.json", "CONTENT_TYPE" => 'application/json'