From 55f5053a4ad9149dc9da54587c3244f9dd9e03a9 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 13 Jan 2013 20:43:48 -0500 Subject: [PATCH] VRFS-201 create session screen --- app/assets/javascripts/createSession.js | 148 ++++++++++++------ .../stylesheets/client/createSession.css.scss | 44 ++---- .../stylesheets/client/jamkazam.css.scss | 8 + .../stylesheets/client/screen_common.css.scss | 93 +++++++---- app/views/clients/_createSession.html.erb | 54 +++---- .../step_definitions/create_session_steps.rb | 8 +- spec/javascripts/createSession.spec.js | 27 ++-- 7 files changed, 224 insertions(+), 158 deletions(-) diff --git a/app/assets/javascripts/createSession.js b/app/assets/javascripts/createSession.js index 9fb5b7388..fd3494d69 100644 --- a/app/assets/javascripts/createSession.js +++ b/app/assets/javascripts/createSession.js @@ -84,42 +84,63 @@ Message from Seth on sequence for creating/joining sessions: var errors = []; var $form = $('#create-session-form'); - // Genres - var genresCount = $('select[name="genres"]', $form).find(':selected').length; - if (genresCount === 0) { - errors.push(['select[name="genres"]', "Please select at least one genre."]); - } - if (genresCount > 3) { - errors.push(['select[name="genres"]', "Please select no more than three genres."]); + // Description can't be empty + var description = $('#description').val(); + if (!description) { + errors.push(['#description', "Please enter a description."]); } - // Description can't be empty - var description = $('textarea[name="description"]').val(); - if (!description) { - errors.push(['textarea[name="description"]', "Please enter a description."]); + var genres = getSelectedGenres(); + + if (genres.length == 0) { + errors.push(['#genre-list-items', "Please select a genre."]); + } + + if (genres.length > 3) { + errors.push(['#genre-list-items', "No more than 3 genres are allowed."]); } return (errors.length) ? errors : null; } + function getSelectedGenres() { + var selectedGenres = []; + $('#genre-list-items :checked').each(function() { + selectedGenres.push($(this).val()); + }); + + return selectedGenres; + } + function submitForm(evt) { - evt.preventDefault(); + evt.preventDefault(); + var formErrors = validateForm(); if (formErrors) { app.notify({ - title: "Form Problems", + title: "Validation Errors", text: JSON.stringify(formErrors) }); return false; } var $this = $(evt.currentTarget); logger.debug($this.length); - var data = $this.formToObject(); + var data = {}; data.client_id = app.clientId; + data.description = $('#description').val() data.as_musician = true; - data.legal_terms = true; // this overrides the default of 'on', which isn't satisfying our concept of boolean - if (typeof(data.genres) === "string") { - data.genres = [data.genres]; + data.legal_terms = true; // this overrides the default of 'on', which isn't satisfying our concept of boolean + + data.genres = getSelectedGenres(); + + data.musician_access = $('#musician-access option:selected').val() === "true" ? true : false; + data.approval_required = $("input[name='musician-access-option']:checked").val() === "true" ? true : false; + + data.fan_access = $('#fan-access option:selected').val() === "true" ? true : false; + data.fan_chat = $("input[name='fan-chat-option']:checked").val() === "true" ? true : false; + + if ($('#band-list option:selected').val() != '') { + data.band = $('#band-list option:selected').val(); } // FIXME: Hard-code tracks for now. Needs to default to: @@ -131,20 +152,7 @@ Message from Seth on sequence for creating/joining sessions: { instrument_id: "keyboard", sound: "mono" } ]; - // music_session["musician_access"].should be_true - // music_session["invitations"].should == [] - // music_session["fan_invitations"].should == [] - // music_session["approval_required"].should be_false - // music_session["fan_chat"].should be_true - // music_session["fan_access"].should be_true - // music_session["participants"].length.should == 1 - // participant = music_session["participants"][0] - // participant["ip_address"].should == client.ip_address - // participant["client_id"].should == client.client_id - // participant["tracks"].length.should == 1 - // track = participant["tracks"][0] - // track["instrument_id"].should == "electric guitar" - // track["sound"].should == "mono" + var jsonData = JSON.stringify(data); var url = "/api/sessions"; $.ajax({ @@ -199,36 +207,68 @@ Message from Seth on sequence for creating/joining sessions: $('#added-invitations').on("click", ".invitation span", removeInvitation); $('#genre-list-header').on("click", toggleGenreBox); $('#genre-list-arrow').on("click", toggleGenreBox); + $('#genre-list-items input[type=checkbox]').each(function() { + $(this).on("click", updateGenreCount); + }); $('#musician-access').change(toggleMusicianAccess); $('#fan-access').change(toggleFanAccess); } + // Used to disable checkboxes once 3 genres are selected. + function updateGenreCount() { + var genreCount = parseInt($('#genre-count').val()); + if ($(this).attr('checked')) { + genreCount++; + } + else { + genreCount--; + } + + $('#genre-count').val(genreCount); + + var disabled = false; + if (genreCount == 3) { + disabled = true; + } + + $('#genre-list-items input[type=checkbox]').each(function() { + if (!$(this).attr('checked')) { + if (disabled) { + $(this).attr('disabled', 'disabled'); + } + else { + $(this).removeAttr('disabled'); + } + } + }); + } + function removeInvitation(evt) { $(evt.currentTarget).closest('.invitation').remove(); } function toggleMusicianAccess() { var value = $("#musician-access option:selected").val(); - if (value == "private") { - $("[name='musician-access-option']").attr('disabled', 'disabled'); - $("[name='musician-access-option']").parent().addClass("op50"); + if (value == "false") { + $("input[name='musician-access-option']").attr('disabled', 'disabled'); + $("input[name='musician-access-option']").parent().addClass("op50"); } else { - $("[name='musician-access-option']").removeAttr('disabled'); - $("[name='musician-access-option']").parent().removeClass("op50"); + $("input[name='musician-access-option']").removeAttr('disabled'); + $("input[name='musician-access-option']").parent().removeClass("op50"); } } function toggleFanAccess() { var value = $("#fan-access option:selected").val(); - if (value == "private") { - $("[name='fan-chat-option']").attr('disabled', 'disabled'); - $("[name='fan-chat-option']").parent().addClass("op50"); + if (value == "false") { + $("input[name='fan-chat-option']").attr('disabled', 'disabled'); + $("input[name='fan-chat-option']").parent().addClass("op50"); } else { - $("[name='fan-chat-option']").removeAttr('disabled'); - $("[name='fan-chat-option']").parent().removeClass("op50"); + $("input[name='fan-chat-option']").removeAttr('disabled'); + $("input[name='fan-chat-option']").parent().removeClass("op50"); } } @@ -237,6 +277,7 @@ Message from Seth on sequence for creating/joining sessions: $.ajax({ type: "GET", url: url, + async: false, // do this synchronously so the event handlers in events() can be wired up success: genresLoaded }); } @@ -246,7 +287,6 @@ Message from Seth on sequence for creating/joining sessions: var template = $('#template-genre-option').html(); var genreOptionHtml = context.JK.fillTemplate(template, {value: this.id, label: this.description}); $('#genre-list-items').append(genreOptionHtml); - //$('#genre-list-items').append("
" + this.description + "
"); }); } @@ -281,8 +321,24 @@ Message from Seth on sequence for creating/joining sessions: }); } + function loadFriends() { + var url = "/api/users/" + context.JK.currentUserId + "/friends"; + $.ajax({ + type: "GET", + url: url, + success: friendsLoaded + }); + } + + function friendsLoaded(response) { + $.each(response, function() { + $('#hdn-friends').append(); + $('#band-list').append(bandOptionHtml); + }); + } + function enterText(div,v) { - cv = $(div).value; + cv = $(dcreateSessioniv).value; if (cv != v && v != '' && cv != '') { $(div).value = cv; } @@ -292,8 +348,8 @@ Message from Seth on sequence for creating/joining sessions: } function initialize() { - events(); loadGenres(); + events(); loadBands(); var screenBindings = { 'afterShow': afterShow, 'beforeShow': beforeShow }; app.bindScreen('createSession', screenBindings); @@ -303,10 +359,10 @@ Message from Seth on sequence for creating/joining sessions: this.initialize = initialize; this.resetForm = resetForm; this.submitForm = submitForm; + this.validateForm = validateForm; this.loadGenres = loadGenres; this.loadBands = loadBands; - this.validateForm = validateForm; - this.toggleGenreBox = toggleGenreBox; + this.loadFriends = loadFriends; return this; }; diff --git a/app/assets/stylesheets/client/createSession.css.scss b/app/assets/stylesheets/client/createSession.css.scss index 2f4cdc506..7dc1e2bf0 100644 --- a/app/assets/stylesheets/client/createSession.css.scss +++ b/app/assets/stylesheets/client/createSession.css.scss @@ -1,23 +1,3 @@ -.content-scroller { - height:inherit; - position:relative; - display:block; - overflow:auto; -} - -.content-wrapper { - padding:20px 30px 20px 36px; - font-size:15px; - color:#ccc; - border-bottom: dotted 1px #444; -} - -.content-wrapper h2 { - color:#fff; - font-weight:600; - font-size:24px; -} - .session-left { width:50%; float:left; @@ -55,18 +35,6 @@ display:block; } -.invite-friend { - margin:0px 4px 4px 4px; - float:left; - display:block; - background-color:#666; - color:#fff; - font-size:12px; - -webkit-border-radius: 7px; - border-radius: 7px; - padding:2px 2px 2px 4px; -} - div.friendbox { background-color:#c5c5c5; border:none; @@ -80,4 +48,16 @@ div.friendbox input[type=text] { box-shadow: inset 0px 0px 0px 0px #888; color:#666; font-style:italic; +} + +.invite-friend { + margin:0px 4px 4px 4px; + float:left; + display:block; + background-color:#666; + color:#fff; + font-size:12px; + -webkit-border-radius: 7px; + border-radius: 7px; + padding:2px 2px 2px 4px; } \ No newline at end of file diff --git a/app/assets/stylesheets/client/jamkazam.css.scss b/app/assets/stylesheets/client/jamkazam.css.scss index 8454608b0..73993c0dd 100644 --- a/app/assets/stylesheets/client/jamkazam.css.scss +++ b/app/assets/stylesheets/client/jamkazam.css.scss @@ -250,4 +250,12 @@ input[type="text"] { .op50 { opacity: .5; -ms-filter: "alpha(opacity=50)"; +} + +.left { + float:left; +} + +.right { + float:right; } \ No newline at end of file diff --git a/app/assets/stylesheets/client/screen_common.css.scss b/app/assets/stylesheets/client/screen_common.css.scss index c2ad031c3..45a30a05d 100644 --- a/app/assets/stylesheets/client/screen_common.css.scss +++ b/app/assets/stylesheets/client/screen_common.css.scss @@ -8,16 +8,75 @@ .screen.secondary { border: 1px solid $ColorScreenPrimary; background-color:$ColorScreenBackground; + .footer button { + margin:1em 0em 1em 1em; + } + + .breadcrumb { + margin-bottom:3em; + } + + .breadcrumb p { + float:left; + } + + p { + margin: 1em; + cursor: pointer; + font-size: 120%; + line-height: 150%; + } + + ul { + margin-left: 2em; + list-style: disc; + } + + li { + margin-bottom:1.5em; + } + + p.current { + font-weight: bold; + } +} + +.content { + background-color: #353535; + clear: both; + float: left; + height: auto; + width: auto; + position:relative; +} + +.content-scroller { + height:inherit; + position:relative; + display:block; + overflow:auto; +} + +.content-wrapper { + padding:20px 30px 20px 36px; + font-size:15px; + color:#ccc; + border-bottom: dotted 1px #444; +} + +.content-wrapper h2 { + color:#fff; + font-weight:600; + font-size:24px; } .content-head { - height:21px; padding:4px; background-color:#ED3618; h1 { - margin: -6px 0px 0px 0px; + margin: -3px 0px 0px 0px; padding:0; float:left; font-weight:100; @@ -72,36 +131,6 @@ z-index:5; background-color:$translucent1; width:100%; - /*text-align:right;*/ -} - -.screen.secondary .footer button { - margin:1em 0em 1em 1em; -} - -.screen.secondary .breadcrumb { - margin-bottom:3em; -} - -.screen.secondary .breadcrumb p { - float:left; -} - -.screen.secondary p { - margin: .5em; - cursor: pointer; - font-size: 120%; -} -.screen.secondary p.current { - font-weight: bold; -} - -.left { - float:left; -} - -.right { - float:right; } textarea { diff --git a/app/views/clients/_createSession.html.erb b/app/views/clients/_createSession.html.erb index 33a8ef579..8e127112b 100644 --- a/app/views/clients/_createSession.html.erb +++ b/app/views/clients/_createSession.html.erb @@ -18,7 +18,7 @@

session info


Description:
- +

@@ -29,13 +29,14 @@
-
+ +
Band:
@@ -44,24 +45,24 @@ Musician Access:
-  Open   -  By Approval +  Open   +  By Approval


Fan Access:
-  Chat   -  No Fan Chat +  Chat   +  No Fan Chat
@@ -72,9 +73,16 @@
+
+ +
Invite friends and contacts to join you on JamKazam from:

@@ -104,34 +112,22 @@
- - diff --git a/features/step_definitions/create_session_steps.rb b/features/step_definitions/create_session_steps.rb index c8f797a60..47208d853 100644 --- a/features/step_definitions/create_session_steps.rb +++ b/features/step_definitions/create_session_steps.rb @@ -20,15 +20,13 @@ When /^I create a public music session$/ do page.find("[layout-link='createSession']").click sleep 1 - # fill out minimially required elements of the form - page.choose 'music_access_true' # public session - # pick a genre, any genre - page.select 'African', :from => 'genres' + page.find("input[value='african']").click + #page.select 'african', :from => 'genre-list-items' page.fill_in 'description', :with => @session_description # create the session - click_button 'Create Session' + click_button 'btn-create-session' # verify that the 'in-session' page is showing, with our description showing page.find("#session-info").should have_content @session_description diff --git a/spec/javascripts/createSession.spec.js b/spec/javascripts/createSession.spec.js index 5a1ec1cc1..bd8bacc55 100644 --- a/spec/javascripts/createSession.spec.js +++ b/spec/javascripts/createSession.spec.js @@ -13,13 +13,13 @@ var selectors = { form: '#create-session-form', - genres: '#create-session-form select[name="genres"]', - description: '#create-session-form textarea[name="description"]' + genres: '#genre-list-items', + description: '#description' }; function makeValid() { - var genre = ''; - $(selectors.genres).html(genre); + var genre = '
1
'; + $(selectors.genres).append(genre); $(selectors.description).val('XYZ'); } @@ -47,7 +47,7 @@ }); it("should populate genres select", function() { css.loadGenres(); - expect($(selectors.genres + ' option').length).toEqual(2); + expect($(selectors.genres + ' .list-item-text').length).toEqual(2); }); }); @@ -111,7 +111,6 @@ describe("validateForm", function() { - beforeEach(function() { makeValid(); }); @@ -122,18 +121,18 @@ }); it("should fail with > 3 genres", function() { - var htm = '' + - '' + - '' + - ''; - $(selectors.genres).html(htm); + var htm = '
2
' + + '
3
' + + '
4
' + + '
5
'; + $(selectors.genres).append(htm); var errs = css.validateForm(); // Verify that we have an error. expect(errs).toBeTruthy(); // Verify that the error is a two-part list expect(errs[0].length).toEqual(2); // Verify that the first part is a selector for the problem. - expect(errs[0][0]).toEqual('select[name="genres"]'); + expect(errs[0][0]).toEqual('#genre-list-items'); }); it("should fail with 0 genres", function() { @@ -142,7 +141,7 @@ // Verify that we have an error. expect(errs).toBeTruthy(); // Verify that the first part is a selector for the problem. - expect(errs[0][0]).toEqual('select[name="genres"]'); + expect(errs[0][0]).toEqual('#genre-list-items'); }); it("should fail with empty description", function() { @@ -151,7 +150,7 @@ // Verify that we have an error. expect(errs).toBeTruthy(); // Verify that the first part is a selector for the problem. - expect(errs[0][0]).toEqual('textarea[name="description"]'); + expect(errs[0][0]).toEqual('#description'); }); });