From a0d8c1e1b5d0ae5e6ee5b5e9617dc3b5f1c7b40e Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 27 Oct 2013 13:02:41 -0400 Subject: [PATCH 01/10] VRFS-76 initial dev for band feature --- web/app/assets/javascripts/bandProfile.js | 0 web/app/views/clients/_bandProfile.html.erb | 11 +++++++++++ 2 files changed, 11 insertions(+) create mode 100644 web/app/assets/javascripts/bandProfile.js create mode 100644 web/app/views/clients/_bandProfile.html.erb diff --git a/web/app/assets/javascripts/bandProfile.js b/web/app/assets/javascripts/bandProfile.js new file mode 100644 index 000000000..e69de29bb diff --git a/web/app/views/clients/_bandProfile.html.erb b/web/app/views/clients/_bandProfile.html.erb new file mode 100644 index 000000000..ab0cbdbee --- /dev/null +++ b/web/app/views/clients/_bandProfile.html.erb @@ -0,0 +1,11 @@ + +
+
+
+ <%= image_tag "content/icon_profile.png", :size => "19x19" %> +
+ +

musician profile

+ + <%= render "screen_navigation" %> +
\ No newline at end of file From 3fd187c88ff8b3964f151e2e71c547d475bd6eda Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 27 Oct 2013 15:07:26 -0400 Subject: [PATCH 02/10] VRFS-595 retrieve session when Join is clicked to check for modified session settings --- web/app/assets/javascripts/alert.js | 4 +- web/app/assets/javascripts/sessionList.js | 83 ++++++++++++++++++++--- 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/web/app/assets/javascripts/alert.js b/web/app/assets/javascripts/alert.js index 077240d4e..7ba13363c 100644 --- a/web/app/assets/javascripts/alert.js +++ b/web/app/assets/javascripts/alert.js @@ -10,7 +10,9 @@ function events() { $('#btn-alert-ok').unbind("click"); $('#btn-alert-ok').click(function(evt) { - callback(sessionId); + if (callback) { + callback(sessionId); + } }); $('#btn-alert-cancel').unbind("click"); diff --git a/web/app/assets/javascripts/sessionList.js b/web/app/assets/javascripts/sessionList.js index 131c987aa..49af23e00 100644 --- a/web/app/assets/javascripts/sessionList.js +++ b/web/app/assets/javascripts/sessionList.js @@ -137,19 +137,69 @@ // wire up the Join Link to the T&Cs dialog var $parentRow = $('tr[id=' + session.id + ']', tbGroup); - if (session.approval_required) { - $('#join-link', $parentRow).click(function(evt) { - openAlert(session.id); - }); - } - else { - $('#join-link', $parentRow).click(function(evt) { - openTerms(session.id); - }); - } + $('#join-link', $parentRow).click(function(evt) { + joinClick(session.id); + }); } } + function joinClick(sessionId) { + var hasInvitation = false; + var session = null; + // we need to do a real-time check of the session in case the settings have + // changed while the user was sitting on the Find Session screen + $.ajax({ + type: "GET", + url: "/api/sessions/" + sessionId, + async: false, + success: function(response) { + session = response; + if ("invitations" in session) { + var invitation; + // user has invitations for this session + for (var i=0; i < session.invitations.length; i++) { + invitation = session.invitations[i]; + // session contains an invitation for this user + if (invitation.receiver_id === context.JK.currentUserId) { + hasInvitation = true; + } + } + } + + if (session) { + // if user has an invitation, always open terms and allow joining regardless of settings + if (hasInvitation) { + logger.debug("Found invitation for user " + context.JK.currentUserId + ", session " + sessionId); + openTerms(sessionId); + } + else { + if (session.musician_access) { + if (session.approval_required) { + openAlert(sessionId); + } + else { + openTerms(sessionId); + } + } + } + } + }, + error: function(xhr, textStatus, errorMessage) { + logger.debug("xhr.status = " + xhr.status); + if (xhr.status === 404) { + sessionNotJoinableAlert(); + } + else { + app.notify( + { title: "Unable to Join Session", + text: "There was an unexpected error while attempting to join the session." + }, + { no_cancel: true }); + } + } + }); + } + function openAlert(sessionId) { var alertDialog = new context.JK.AlertDialog(app, "YES", "You must be approved to join this session. Would you like to send a request to join?", @@ -159,6 +209,19 @@ app.layout.showDialog('alert'); } + function sessionNotJoinableAlert() { + var alertDialog = new context.JK.AlertDialog(app, "OK", + "This session is over or is no longer public and cannot be joined. Please click Refresh to update the session list.", + null, + function(evt) { + app.layout.closeDialog('alert'); + } + ); + + alertDialog.initialize(); + app.layout.showDialog('alert'); + } + function onCreateJoinRequest(sessionId) { var joinRequest = {}; joinRequest.music_session = sessionId; From a6c1b0d79d9c36a4dd26cbafb93fb7610cad5d82 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 27 Oct 2013 19:53:49 -0400 Subject: [PATCH 03/10] VRFS-76 band profile work --- web/app/assets/javascripts/bandProfile.js | 358 ++++++++++++++++++ web/app/assets/javascripts/profile.js | 13 +- .../stylesheets/client/bandProfile.css.scss | 218 +++++++++++ web/app/views/api_bands/show.rabl | 2 +- web/app/views/clients/_bandProfile.html.erb | 90 ++++- web/app/views/clients/_profile.html.erb | 2 +- web/app/views/clients/index.html.erb | 1 + 7 files changed, 676 insertions(+), 8 deletions(-) create mode 100644 web/app/assets/stylesheets/client/bandProfile.css.scss diff --git a/web/app/assets/javascripts/bandProfile.js b/web/app/assets/javascripts/bandProfile.js index e69de29bb..29d7ddeb1 100644 --- a/web/app/assets/javascripts/bandProfile.js +++ b/web/app/assets/javascripts/bandProfile.js @@ -0,0 +1,358 @@ +(function(context,$) { + + "use strict"; + + context.JK = context.JK || {}; + context.JK.BandProfileScreen = function(app) { + var logger = context.JK.logger; + var bandId; + var band = {}; + + function beforeShow(data) { + bandId = data.id; + } + + function afterShow(data) { + resetForm(); + events(); + renderActive(); + } + + function resetForm() { + $('#band-profile-instruments').empty(); + + $('#band-profile-about').show(); + $('#band-profile-history').hide(); + $('#band-profile-members').hide(); + $('#band-profile-social').hide(); + + $('.band-profile-nav a.active').removeClass('active'); + $('.band-profile-nav a.#band-profile-about-link').addClass('active'); + } + + /****************** MAIN PORTION OF SCREEN *****************/ + + function addFollowing() { + var newFollowing = {}; + newFollowing.band_id = userId; + + var url = "/api/users/" + context.JK.currentUserId + "/band_followings"; + $.ajax({ + type: "POST", + dataType: "json", + contentType: 'application/json', + url: url, + data: JSON.stringify(newFollowing), + processData: false, + success: function(response) { + renderActive(); // refresh stats + configureFollowingButton(true); + }, + error: app.ajaxError + }); + } + + function removeFollowing(bandId) { + var following = {}; + following.band_id = id; + + var url = "/api/users/" + context.JK.currentUserId + "/followings"; + $.ajax({ + type: "DELETE", + dataType: "json", + contentType: 'application/json', + url: url, + data: JSON.stringify(following), + processData: false, + success: function(response) { + renderActive(); // refresh stats + configureBandFollowingButton(id); + }, + error: app.ajaxError + }); + } + + function isFollowing() { + var alreadyFollowing = false; + + var url = "/api/users/" + context.JK.currentUserId + "/band_followings/" + bandId; + $.ajax({ + type: "GET", + dataType: "json", + url: url, + async: false, + processData: false, + success: function(response) { + if (response.id !== undefined) { + alreadyFollowing = true; + } + else { + alreadyFollowing = false; + } + }, + error: app.ajaxError + }); + + return alreadyFollowing; + } + + function configureFollowingButton(following, bandId) { + var $btnFollowBand = $('div[band-id=' + bandId + ']', '#profile-bands').find('#btn-follow-band'); + $btnFollowBand.unbind("click"); + + if (following) { + $btnFollowBand.text('UN-FOLLOW'); + $btnFollowBand.click(function() { + removeFollowing(true, bandId); + }); + } + else { + $btnFollowBand.text('FOLLOW'); + $btnFollowBand.click(addBandFollowing); + } + } + + // refreshes the currently active tab + function renderActive() { + if ($('#band-profile-about-link').hasClass('active')) { + renderAbout(); + } + else if ($('#band-profile-history-link').hasClass('active')) { + renderHistory(); + } + else if ($('#band-profile-members-link').hasClass('active')) { + renderMembers(); + } + else if ($('#band-profile-social-link').hasClass('active')) { + renderSocial(); + } + } + + /****************** ABOUT TAB *****************/ + function renderAbout() { + + $('#band-profile-about').show(); + $('#band-profile-history').hide(); + $('#band-profile-members').hide(); + $('#band-profile-social').hide(); + + $('.band-profile-nav a.active').removeClass('active'); + $('.band-profile-nav a.#band-profile-about-link').addClass('active'); + + bindAbout(); + } + + function bindAbout() { + var url = "/api/bands/" + bandId; + $.ajax({ + type: "GET", + dataType: "json", + url: url, + async: false, + processData:false, + success: function(response) { + band = response; + }, + error: app.ajaxError + }); + + if (band) { + + // name + $('#band-profile-name').html(band.name); + + // avatar + $('#band-profile-avatar').attr('src', context.JK.resolveAvatarUrl(band.photo_url)); + + // instruments + // if (user.instruments) { + // for (var i=0; i < user.instruments.length; i++) { + // var instrument = user.instruments[i]; + // var description = instrument.instrument_id; + // var proficiency = instrument.proficiency_level; + // var instrument_icon_url = context.JK.getInstrumentIcon45(description); + + // // add instrument info to layout + // var template = $('#template-profile-instruments').html(); + // var instrumentHtml = context.JK.fillTemplate(template, { + // instrument_logo_url: instrument_icon_url, + // instrument_description: description, + // proficiency_level: proficiencyDescriptionMap[proficiency], + // proficiency_level_css: proficiencyCssMap[proficiency] + // }); + + // $('#profile-instruments').append(instrumentHtml); + // } + // } + + // location + $('#band-profile-location').html(band.location); + + // stats + var text = band.follower_count > 1 || band.follower_count == 0 ? " Followers" : " Follower"; + $('#band-profile-follower-stats').html(band.follower_count + text); + + text = band.session_count > 1 || band.session_count == 0 ? " Sessions" : " Session"; + $('#band-profile-session-stats').html(band.session_count + text); + + text = band.recording_count > 1 || band.recording_count == 0 ? " Recordings" : " Recording"; + $('#band-profile-recording-stats').html(band.recording_count + text); + + $('#band-profile-biography').html(band.biography); + } + else { + + } + } + + /****************** SOCIAL TAB *****************/ + function renderSocial() { + $('#profile-social-friends').empty(); + $('#profile-social-followings').empty(); + $('#profile-social-followers').empty(); + + $('#profile-about').hide(); + $('#profile-history').hide(); + $('#profile-bands').hide(); + $('#profile-social').show(); + $('#profile-favorites').hide(); + + $('.profile-nav a.active').removeClass('active'); + $('.profile-nav a.#profile-social-link').addClass('active'); + + bindSocial(); + } + + function bindSocial() { + // FOLLOWERS + url = "/api/users/" + userId + "/followers"; + $.ajax({ + type: "GET", + dataType: "json", + url: url, + async: false, + processData:false, + success: function(response) { + $.each(response, function(index, val) { + var template = $('#template-band-profile-social').html(); + var followerHtml = context.JK.fillTemplate(template, { + avatar_url: context.JK.resolveAvatarUrl(val.photo_url), + userName: val.name, + location: val.location + }); + + $('#profile-social-followers').append(followerHtml); + }); + }, + error: app.ajaxError + }); + } + + /****************** HISTORY TAB *****************/ + function renderHistory() { + $('#profile-about').hide(); + $('#profile-history').show(); + $('#profile-bands').hide(); + $('#profile-social').hide(); + $('#profile-favorites').hide(); + + $('.profile-nav a.active').removeClass('active'); + $('.profile-nav a.#profile-history-link').addClass('active'); + + bindHistory(); + } + + function bindHistory() { + + } + + /****************** BANDS TAB *****************/ + function renderMembers() { + $('#band-profile-members').empty(); + + $('#band-profile-about').hide(); + $('#band-profile-history').hide(); + $('#band-profile-members').show(); + $('#band-profile-social').hide(); + + $('.band-profile-nav a.active').removeClass('active'); + $('.band-profile-nav a.#band-profile-bands-link').addClass('active'); + + bindMembers(); + } + + function bindMembers() { + var url = "/api/bands/" + bandId + "/musicians"; + $.ajax({ + type: "GET", + dataType: "json", + url: url, + async: false, + processData:false, + success: function(response) { + $.each(response, function(index, val) { + var template = $('#template-band-profile-members').html(); + var bandHtml = context.JK.fillTemplate(template, { + bandId: val.id, + band_url: "/#/bandProfile/" + val.id, + avatar_url: context.JK.resolveAvatarUrl(val.logo_url), + name: val.name, + location: val.location, + genres: formatGenres(val.genres) + }); + + $('#profile-bands').append(bandHtml); + + // wire up Band Follow button click handler + var following = isFollowingBand(val.id); + configureBandFollowingButton(following, val.id); + }); + }, + error: app.ajaxError + }); + } + + function formatGenres(genres) { + var formattedGenres = ''; + if (genres) { + for (var i=0; i < genres.length; i++) { + var genre = genres[i]; + formattedGenres += genre.description; + if (i < genres.length -1) { + formattedGenres += ', '; + } + } + } + return formattedGenres; + } + + // events for main screen + function events() { + // wire up panel clicks + $('#band-profile-about-link').click(renderAbout); + $('#band-profile-history-link').click(renderHistory); + $('#band-profile-bands-link').click(renderBands); + $('#band-profile-social-link').click(renderSocial); + $('#band-profile-favorites-link').click(renderFavorites); + + // wire up Follow click + var following = isFollowing(); + configureFollowingButton(following); + } + + function initialize() { + var screenBindings = { + 'beforeShow': beforeShow, + 'afterShow': afterShow + }; + app.bindScreen('profile', screenBindings); + } + + + this.initialize = initialize; + this.beforeShow = beforeShow; + this.afterShow = afterShow; + return this; + }; + + })(window,jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/profile.js b/web/app/assets/javascripts/profile.js index 3268d1834..6a9e7dde2 100644 --- a/web/app/assets/javascripts/profile.js +++ b/web/app/assets/javascripts/profile.js @@ -484,6 +484,7 @@ var template = $('#template-profile-bands').html(); var bandHtml = context.JK.fillTemplate(template, { bandId: val.id, + band_url: "/#/bandProfile/" + val.id, avatar_url: context.JK.resolveAvatarUrl(val.logo_url), name: val.name, location: val.location, @@ -503,11 +504,13 @@ function formatGenres(genres) { var formattedGenres = ''; - for (var i=0; i < genres.length; i++) { - var genre = genres[i]; - formattedGenres += genre.description; - if (i < genres.length -1) { - formattedGenres += ', '; + if (genres) { + for (var i=0; i < genres.length; i++) { + var genre = genres[i]; + formattedGenres += genre.description; + if (i < genres.length -1) { + formattedGenres += ', '; + } } } return formattedGenres; diff --git a/web/app/assets/stylesheets/client/bandProfile.css.scss b/web/app/assets/stylesheets/client/bandProfile.css.scss new file mode 100644 index 000000000..ada3d0a5c --- /dev/null +++ b/web/app/assets/stylesheets/client/bandProfile.css.scss @@ -0,0 +1,218 @@ +@import "client/common.css.scss"; + +.band-profile-header { + padding:20px; + height:120px; +} + +.band-profile-header h2 { + font-weight:200; + font-size: 28px; + float:left; + margin: 0px 150px 0px 0px; +} + +.band-profile-status { + font-size:12px; + float:left; + display:inline-block; + vertical-align:middle; + line-height:30px; +} + +.band-profile-photo { + height: 95px; + width: 15%; + float:left; +} + +.band-profile-nav { + width:85%; + position:relative; + float:right; + margin-right:-10px; +} + +.band-profile-nav a { + width:19%; + text-align:center; + height: 27px; + display: block; + float:left; + margin-right:5px; + vertical-align:bottom; + padding-top:65px; + background-color:#535353; + color:#ccc; + font-size:17px; + text-decoration:none; +} + +.band-profile-nav a:hover { + background-color:#666; + color:#fff; +} + +.band-profile-nav a.active { + background-color:#ed3618; + color:#fff; +} + +.band-profile-nav a.active:hover { + background-color:#ed3618; + cursor:default; +} + +.band-profile-nav a.last { + margin-right:0px !important; +} + +.avatar-profile { + float:left; + padding:2px; + width:88px; + height:88px; + background-color:#ed3618; + -webkit-border-radius:44px; + -moz-border-radius:44px; + border-radius:44px; +} + +.avatar-profile img { + width:88px; + height:88px; + -webkit-border-radius:44px; + -moz-border-radius:44px; + border-radius:44px; +} + +.band-profile-wrapper { + padding:10px 25px 10px 25px; + font-size:15px; + color:#ccc; + border-bottom: dotted 1px #444; + position:relative; + display:block; +} + +.band-profile-about-left { + width:16%; + float:left; + font-size:13px; + line-height:140%; + display:block; +} + +.band-profile-about-left h3 { + color:#fff; + margin-bottom:0px; + font-size:13px; + font-weight:bold; + display:inline; +} + +.band-profile-about-right { + float:right; + font-size:13px; + width:84%; + line-height:140%; + display:block; +} + +.band-profile-about-right .band-profile-instrument { + text-align:center; + margin-right:15px; + float:left; +} + +.proficiency-beginner { + font-size:10px; + color:#8ea415; + font-weight:600; +} + +.proficiency-intermediate { + font-size:10px; + color:#0b6672; + font-weight:600; +} + +.proficiency-expert { + font-size:10px; + color:#ed3618; + font-weight:600; +} + +.band-profile-members { + width:215px; + min-height:90px; + background-color:#242323; + position:relative; + float:left; + margin:10px 20px 10px 0px; + padding-bottom:5px; +} + +.band-profile-member-name { + float:left; + font-size:12px; + margin-top:12px; + font-weight:bold; +} + +.band-profile-member-location { + font-size:12px; + font-weight:200; +} + +.band-profile-member-genres { + float:left; + width:40%; + font-size:10px; + margin-left:10px; + padding-right:5px; +} + +.band-profile-social-left { + float:left; + width:32%; + margin-right:12px; + border-right:solid 1px #666; +} + +.band-profile-social-mid { + float:left; + width:31%; + margin-right:12px; + border-right:solid 1px #666; +} + +.band-profile-social-right { + float:left; + width:31%; +} + +.band-profile-social-left h2, .band-profile-social-mid h2, .band-profile-social-right h2 { + font-weight:200; + color:#fff; + font-size:20px; +} + +.band-profile-block { + clear:left; + white-space:nowrap; + display:block; + margin-bottom:10px; +} + +.band-profile-block-name { + display:inline-block; + margin-top:13px; + font-size:14px; + color:#fff; + font-weight:bold; +} + +.band-profile-block-city { + font-size:12px; +} diff --git a/web/app/views/api_bands/show.rabl b/web/app/views/api_bands/show.rabl index fc4b171d9..bcd2ed486 100644 --- a/web/app/views/api_bands/show.rabl +++ b/web/app/views/api_bands/show.rabl @@ -1,6 +1,6 @@ object @band -attributes :id, :name, :city, :state, :country, :website, :biography, :photo_url, :logo_url, :liker_count, :follower_count, :recording_count, :session_count +attributes :id, :name, :city, :state, :country, :location, :website, :biography, :photo_url, :logo_url, :liker_count, :follower_count, :recording_count, :session_count unless @band.users.nil? || @band.users.size == 0 child :users => :musicians do diff --git a/web/app/views/clients/_bandProfile.html.erb b/web/app/views/clients/_bandProfile.html.erb index ab0cbdbee..9b2389a1a 100644 --- a/web/app/views/clients/_bandProfile.html.erb +++ b/web/app/views/clients/_bandProfile.html.erb @@ -8,4 +8,92 @@

musician profile

<%= render "screen_navigation" %> -
\ No newline at end of file + +
+
+

+ +
+
+ +
+ FOLLOW +
+ +

+ +
+
+ +
+
+ + + +
+
+
+
+ +
+

Location:


+


+

Stats:


+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+

Followers

+
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/web/app/views/clients/_profile.html.erb b/web/app/views/clients/_profile.html.erb index 70ec227df..790c44cee 100644 --- a/web/app/views/clients/_profile.html.erb +++ b/web/app/views/clients/_profile.html.erb @@ -106,7 +106,7 @@
-
{name}
+
{name}
{location}

diff --git a/web/app/views/clients/index.html.erb b/web/app/views/clients/index.html.erb index f8f109faa..4ea476efc 100644 --- a/web/app/views/clients/index.html.erb +++ b/web/app/views/clients/index.html.erb @@ -20,6 +20,7 @@ <%= render "findSession" %> <%= render "session" %> <%= render "profile" %> +<%= render "bandProfile" %> <%= render "feed" %> <%= render "bands" %> <%= render "musicians" %> From 5beddc7a8525c0c69ef52518a4cb570bcb552a56 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 27 Oct 2013 21:50:31 -0400 Subject: [PATCH 04/10] VRFS-76 band profile work --- web/app/assets/javascripts/bandProfile.js | 90 ++++++++++++-------- web/app/assets/stylesheets/client/client.css | 1 + web/app/views/clients/_bandProfile.html.erb | 11 +-- web/app/views/clients/index.html.erb | 3 + 4 files changed, 63 insertions(+), 42 deletions(-) diff --git a/web/app/assets/javascripts/bandProfile.js b/web/app/assets/javascripts/bandProfile.js index 29d7ddeb1..e8bcda013 100644 --- a/web/app/assets/javascripts/bandProfile.js +++ b/web/app/assets/javascripts/bandProfile.js @@ -34,9 +34,9 @@ function addFollowing() { var newFollowing = {}; - newFollowing.band_id = userId; + newFollowing.band_id = bandId; - var url = "/api/users/" + context.JK.currentUserId + "/band_followings"; + var url = "/api/users/" + context.JK.currentUserId + "/followings"; $.ajax({ type: "POST", dataType: "json", @@ -52,9 +52,14 @@ }); } - function removeFollowing(bandId) { + function removeFollowing(isBand, id) { var following = {}; - following.band_id = id; + if (!isBand) { + following.user_id = id; + } + else { + following.band_id = id; + } var url = "/api/users/" + context.JK.currentUserId + "/followings"; $.ajax({ @@ -66,7 +71,12 @@ processData: false, success: function(response) { renderActive(); // refresh stats - configureBandFollowingButton(id); + if (isBand) { + configureFollowingButton(false); + } + else { + configureMemberFollowingButton(false, id); + } }, error: app.ajaxError }); @@ -96,19 +106,34 @@ return alreadyFollowing; } - function configureFollowingButton(following, bandId) { - var $btnFollowBand = $('div[band-id=' + bandId + ']', '#profile-bands').find('#btn-follow-band'); - $btnFollowBand.unbind("click"); + function configureFollowingButton(following) { + $('#btn-follow-band').unbind("click"); if (following) { - $btnFollowBand.text('UN-FOLLOW'); - $btnFollowBand.click(function() { + $('#btn-follow-band').text('STOP FOLLOWING'); + $('#btn-follow-band').click(function() { removeFollowing(true, bandId); }); } else { - $btnFollowBand.text('FOLLOW'); - $btnFollowBand.click(addBandFollowing); + $('#btn-follow-band').text('FOLLOW'); + $('#btn-follow-band').click(addFollowing); + } + } + + function configureMemberFollowingButton(following, userId) { + var $btnFollowMember = $('div[user-id=' + userId + ']', '#band-profile-members').find('#btn-follow-member'); + $btnFollowMember.unbind("click"); + + if (following) { + $btnFollowMember.text('UN-FOLLOW'); + $btnFollowMember.click(function() { + removeFollowing(false, userId); + }); + } + else { + $btnFollowMember.text('FOLLOW'); + $btnFollowMember.click(addFollowing); } } @@ -207,25 +232,22 @@ /****************** SOCIAL TAB *****************/ function renderSocial() { - $('#profile-social-friends').empty(); - $('#profile-social-followings').empty(); - $('#profile-social-followers').empty(); + $('#band-profile-social-followers').empty(); - $('#profile-about').hide(); - $('#profile-history').hide(); - $('#profile-bands').hide(); - $('#profile-social').show(); - $('#profile-favorites').hide(); + $('#band-profile-about').hide(); + $('#band-profile-history').hide(); + $('#band-profile-members').hide(); + $('#band-profile-social').show(); - $('.profile-nav a.active').removeClass('active'); - $('.profile-nav a.#profile-social-link').addClass('active'); + $('.band-profile-nav a.active').removeClass('active'); + $('.band-profile-nav a.#band-profile-social-link').addClass('active'); bindSocial(); } function bindSocial() { // FOLLOWERS - url = "/api/users/" + userId + "/followers"; + url = "/api/bands/" + bandId + "/followers"; $.ajax({ type: "GET", dataType: "json", @@ -241,7 +263,7 @@ location: val.location }); - $('#profile-social-followers').append(followerHtml); + $('#band-profile-social-followers').append(followerHtml); }); }, error: app.ajaxError @@ -250,14 +272,13 @@ /****************** HISTORY TAB *****************/ function renderHistory() { - $('#profile-about').hide(); - $('#profile-history').show(); - $('#profile-bands').hide(); - $('#profile-social').hide(); - $('#profile-favorites').hide(); + $('#band-profile-about').hide(); + $('#band-profile-history').show(); + $('#band-profile-members').hide(); + $('#band-profile-social').hide(); - $('.profile-nav a.active').removeClass('active'); - $('.profile-nav a.#profile-history-link').addClass('active'); + $('.band-profile-nav a.active').removeClass('active'); + $('.band-profile-nav a.#band-profile-history-link').addClass('active'); bindHistory(); } @@ -305,7 +326,7 @@ // wire up Band Follow button click handler var following = isFollowingBand(val.id); - configureBandFollowingButton(following, val.id); + configureMemberFollowingButton(following, val.id); }); }, error: app.ajaxError @@ -331,9 +352,8 @@ // wire up panel clicks $('#band-profile-about-link').click(renderAbout); $('#band-profile-history-link').click(renderHistory); - $('#band-profile-bands-link').click(renderBands); + $('#band-profile-members-link').click(renderMembers); $('#band-profile-social-link').click(renderSocial); - $('#band-profile-favorites-link').click(renderFavorites); // wire up Follow click var following = isFollowing(); @@ -345,7 +365,7 @@ 'beforeShow': beforeShow, 'afterShow': afterShow }; - app.bindScreen('profile', screenBindings); + app.bindScreen('bandProfile', screenBindings); } diff --git a/web/app/assets/stylesheets/client/client.css b/web/app/assets/stylesheets/client/client.css index fd8e50ffa..54b1d6db8 100644 --- a/web/app/assets/stylesheets/client/client.css +++ b/web/app/assets/stylesheets/client/client.css @@ -22,6 +22,7 @@ *= require ./sidebar *= require ./home *= require ./profile + *= require ./bandProfile *= require ./findSession *= require ./session *= require ./account diff --git a/web/app/views/clients/_bandProfile.html.erb b/web/app/views/clients/_bandProfile.html.erb index 9b2389a1a..ada1107c6 100644 --- a/web/app/views/clients/_bandProfile.html.erb +++ b/web/app/views/clients/_bandProfile.html.erb @@ -1,11 +1,11 @@ -
+
<%= image_tag "content/icon_profile.png", :size => "19x19" %>
-

musician profile

+

band profile

<%= render "screen_navigation" %>
@@ -33,7 +33,7 @@ about history members - social + social

@@ -60,16 +60,13 @@
-
+

Followers


-
-
-
diff --git a/web/app/views/clients/index.html.erb b/web/app/views/clients/index.html.erb index 4ea476efc..3099cb3a2 100644 --- a/web/app/views/clients/index.html.erb +++ b/web/app/views/clients/index.html.erb @@ -108,6 +108,9 @@ var profileScreen = new JK.ProfileScreen(JK.app); profileScreen.initialize(); + var bandProfileScreen = new JK.BandProfileScreen(JK.app); + bandProfileScreen.initialize(); + var accountScreen = new JK.AccountScreen(JK.app); accountScreen.initialize(); From f93685aaffe0bc0220ce5a39fbbe2c63de13690e Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Tue, 29 Oct 2013 01:30:51 -0400 Subject: [PATCH 05/10] VRFS-782 fix validation bug --- web/app/assets/javascripts/configureTrack.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web/app/assets/javascripts/configureTrack.js b/web/app/assets/javascripts/configureTrack.js index 01b32d7c5..c2d9b8fb0 100644 --- a/web/app/assets/javascripts/configureTrack.js +++ b/web/app/assets/javascripts/configureTrack.js @@ -696,7 +696,7 @@ function validateAudioSettings(allowEmptyInput) { var isValid = true; - var noTrackErrMsg = 'You must assign at least one input port to each of your tracks. Please update your settings to correct this.'; + var noTrackErrMsg = 'You can assign no more than 2 input ports to each of your tracks. Please update your settings to correct this.'; var noInstrumentErrMsg = 'You must specify what instrument is being played for each track. Please update your settings to correct this.'; var outputErrMsg = 'You must assign two output ports for stereo session audio to hear music. Please update your settings to correct this.'; @@ -725,12 +725,14 @@ // if Track 2 exists, verify Input and Instrument exist if (isValid) { - if ($('#track2-input > option').size() > 2) { + var track2Count = $('#track2-input > option').size(); + if (track2Count > 2) { errMsg = noTrackErrMsg; isValid = false; } - if (isValid && $('#track2-instrument > option:selected').length === 0) { + // only validate instrument if second track is selected + if (isValid && track2Count > 0 && $('#track2-instrument > option:selected').length === 0) { errMsg = noInstrumentErrMsg; isValid = false; } From d063ba2a370dc10daeaa8730ca28e8ca9a228247 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sat, 2 Nov 2013 02:10:35 -0400 Subject: [PATCH 06/10] VRFS-819 VRFS-76 band profile updates --- .gitignore | 1 + .../assets/images/content/icon_followers.png | Bin 0 -> 396 bytes web/app/assets/images/content/icon_friend.png | Bin 0 -> 1177 bytes .../assets/images/content/icon_recordings.png | Bin 0 -> 396 bytes .../images/content/icon_session_tiny.png | Bin 0 -> 332 bytes web/app/assets/javascripts/profile.js | 64 ++- .../stylesheets/client/content.css.scss | 370 ++++++++++-------- .../stylesheets/client/profile.css.scss | 23 +- web/app/views/api_users/band_index.rabl | 19 +- web/app/views/clients/_profile.html.erb | 23 +- 10 files changed, 309 insertions(+), 191 deletions(-) create mode 100644 web/app/assets/images/content/icon_followers.png create mode 100644 web/app/assets/images/content/icon_friend.png create mode 100644 web/app/assets/images/content/icon_recordings.png create mode 100644 web/app/assets/images/content/icon_session_tiny.png diff --git a/.gitignore b/.gitignore index 7393e2aa5..8927de757 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea *~ *.swp +HTML \ No newline at end of file diff --git a/web/app/assets/images/content/icon_followers.png b/web/app/assets/images/content/icon_followers.png new file mode 100644 index 0000000000000000000000000000000000000000..957258ceb7e77631be65cccceb869ecb3eee74ae GIT binary patch literal 396 zcmV;70dxL|P)#47LTc2(z#YeUOJ0IEJzpZgu{s z1kJ|b3=Sg|jp?B|`OC1Q_-Mvo&hLini0~7u@JFl3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s01qrNAVWhSWoBaTYH8|b=H{644~ki&n1%@flMjdqPq#o0Jmsh60h4(PS+pH!P#

_O^mg9T zc#`Doc;)+v_lG{}74p~Y`TzUzoY()0{s+n&KNu=3J7>|7H_YE99$IFe*||{qOkpb* zS5Tl?`1x}WOxYg(ms(-&lC$;LSKXA=yZ$EYr>vjHyDfIZF~engv$djkugPtGdgU@- zV99sa)P1ME^~LLaGtT>Jef~U`J6Bxk*7F}$m$vxdHJ`FJXSMP7CE{}ybj=De{qW>h zn%Rx=gOX|%2l{XP;uBxDKEIi}UTH<~p2v*+QSr;v3 p64340c*Jemsi;>sugzy*W^g@i5u1F=ZYHR(@O1TaS?83{1OU)vo7w;X literal 0 HcmV?d00001 diff --git a/web/app/assets/images/content/icon_recordings.png b/web/app/assets/images/content/icon_recordings.png new file mode 100644 index 0000000000000000000000000000000000000000..b530b2b690eeea86b275b0c7114bb9d008d2db0b GIT binary patch literal 396 zcmV;70dxL|P)RQ0~S#cA|ff0B3N2zFA@+^3Li1>ngu%&W z>k2IDW%ghnUP4?taG}L>1y~8knr~wtb%d;>ImEO%jhaeb#Uc*0w`>*IMnMZ#IMn?W z<9fi2GD=p`0G2R@eq~$70@ie%pklf$!#(y?_a|0R!6k-qqYkC5TbAJzqrTL6oM0X) z9X_qSs1!Q+S0!1ua%d@= qdH(-vG}Yok451SZ`Efyi0t^5xeMaD{f3nX20000&`NRrzw!)h865b@%+CAl zyv*vwar}}PB~V`udsZ{{6Cb6Cmgb{Gt1a!>SU&yX e{{7du3oroCmqvO8`=}lO0000 '; + } + } + // this template is in _findSession.html.erb + var musicianTemplate = $('#template-musician-info').html(); + musicianHtml += context.JK.fillTemplate(musicianTemplate, { + avatar_url: context.JK.resolveAvatarUrl(musician.photo_url), + profile_url: "/#/profile/" + musician.id, + musician_name: musician.name, + instruments: instrumentLogoHtml + }); + } + } + var template = $('#template-profile-bands').html(); + var bandHtml = context.JK.fillTemplate(template, { + bandId: val.id, + biography: val.biography, + band_url: "/#/bandProfile/" + val.id, + avatar_url: context.JK.resolveAvatarUrl(val.logo_url), + name: val.name, + location: val.location, + genres: formatGenres(val.genres), + follower_count: val.follower_count, + recording_count: val.recording_count, + session_count: val.session_count, + musicians: musicianHtml + }); - // wire up Band Follow button click handler - var following = isFollowingBand(val.id); - configureBandFollowingButton(following, val.id); + $('#profile-bands').append(bandHtml); + + // wire up Band Follow button click handler + var following = isFollowingBand(val.id); + configureBandFollowingButton(following, val.id); }); }, error: app.ajaxError @@ -518,7 +552,7 @@ function addBandFollowing(evt) { evt.stopPropagation(); - var bandId = $(this).parent().attr('band-id'); + var bandId = $(this).parent().parent().attr('band-id'); var newFollowing = {}; newFollowing.band_id = bandId; @@ -532,7 +566,7 @@ data: JSON.stringify(newFollowing), processData: false, success: function(response) { - renderActive(); // refresh stats + renderBands(); // refresh stats configureBandFollowingButton(true, bandId); }, error: app.ajaxError diff --git a/web/app/assets/stylesheets/client/content.css.scss b/web/app/assets/stylesheets/client/content.css.scss index 228a6edf2..6a23a30a8 100644 --- a/web/app/assets/stylesheets/client/content.css.scss +++ b/web/app/assets/stylesheets/client/content.css.scss @@ -1,271 +1,271 @@ /* This is simply Jeff's content.css file */ @charset "UTF-8"; #content { - background-color: #353535; - border: 1px solid #ed3618; - clear: both; - float: left; - margin-top: 39px; - height: auto; - width: auto; - position:relative; - padding-bottom:3px; + background-color: #353535; + border: 1px solid #ed3618; + clear: both; + float: left; + margin-top: 39px; + height: auto; + width: auto; + position:relative; + padding-bottom:3px; } .content-head { - height:21px; - padding:4px; - background-color:#ED3618; + height:21px; + padding:4px; + background-color:#ED3618; } .content-icon { - margin-right:10px; - float:left; + margin-right:10px; + float:left; } .content-head h1 { - margin: -6px 0px 0px 0px; - padding:0; - float:left; - font-weight:100; - font-size:24px; + margin: -6px 0px 0px 0px; + padding:0; + float:left; + font-weight:100; + font-size:24px; } .content-nav { - float:right; - margin-right:10px; + float:right; + margin-right:10px; } .home-icon { - float:left; - margin-right:20px; + float:left; + margin-right:20px; } .content-nav a.arrow-right { - float:left; - display:block; - margin-top:2px; - margin-right:10px; - width: 0; - height: 0; - border-top: 7px solid transparent; - border-bottom: 7px solid transparent; - border-left: 7px solid #FFF; + float:left; + display:block; + margin-top:2px; + margin-right:10px; + width: 0; + height: 0; + border-top: 7px solid transparent; + border-bottom: 7px solid transparent; + border-left: 7px solid #FFF; } .content-nav a.arrow-left { - float:left; - display:block; - margin-top:2px; - margin-right:20px; - width: 0; - height: 0; - border-top: 7px solid transparent; - border-bottom: 7px solid transparent; - border-right:7px solid #FFF; + float:left; + display:block; + margin-top:2px; + margin-right:20px; + width: 0; + height: 0; + border-top: 7px solid transparent; + border-bottom: 7px solid transparent; + border-right:7px solid #FFF; } #content-scroller, .content-scroller { - height:inherit; - position:relative; - display:block; - overflow:auto; + height:inherit; + position:relative; + display:block; + overflow:auto; } .content-wrapper { - padding:10px 30px 10px 36px; - font-size:15px; - color:#ccc; - border-bottom: dotted 1px #444; - overflow-x:hidden; - white-space:nowrap; + padding:10px 30px 10px 36px; + font-size:15px; + color:#ccc; + border-bottom: dotted 1px #444; + overflow-x:hidden; + white-space:nowrap; } .create-session-left { - width:50%; - float:left; + width:50%; + float:left; } .create-session-right { - width:45%; - float:right; - font-size:13px; + width:45%; + float:right; + font-size:13px; } .content-wrapper h2 { - color:#fff; - font-weight:600; - font-size:24px; + color:#fff; + font-weight:600; + font-size:24px; } .content-wrapper select, .content-wrapper textarea, .content-wrapper input[type=text], .content-wrapper input[type=password], div.friendbox, .ftue-inner input[type=text], .ftue-inner input[type=password], .dialog-inner textarea, .dialog-inner input[type=text] { - font-family:"Raleway", arial, sans-serif; - background-color:#c5c5c5; - border:none; - -webkit-box-shadow: inset 2px 2px 3px 0px #888; - box-shadow: inset 2px 2px 3px 0px #888; - color:#666; + font-family:"Raleway", arial, sans-serif; + background-color:#c5c5c5; + border:none; + -webkit-box-shadow: inset 2px 2px 3px 0px #888; + box-shadow: inset 2px 2px 3px 0px #888; + color:#666; } .create-session-description { - padding:5px; - width:100%; - height:80px; + padding:5px; + width:100%; + height:80px; } .friendbox { - padding:5px; - width:100%; - height:60px; + padding:5px; + width:100%; + height:60px; } .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; + 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; } .content-wrapper div.friendbox input[type=text] { - -webkit-box-shadow: inset 0px 0px 0px 0px #888; - box-shadow: inset 0px 0px 0px 0px #888; - color:#666; - font-style:italic; + -webkit-box-shadow: inset 0px 0px 0px 0px #888; + box-shadow: inset 0px 0px 0px 0px #888; + color:#666; + font-style:italic; } #genrelist, #musicianlist { - position:relative; - z-index:99; - width: 175px; - -webkit-border-radius: 6px; - border-radius: 6px; - background-color:#C5C5C5; - border: none; - color:#333; - font-weight:400; - padding:0px 0px 0px 8px; - height:20px; - line-height:20px; - overflow:hidden; - -webkit-box-shadow: inset 2px 2px 3px 0px #888; - box-shadow: inset 2px 2px 3px 0px #888; + position:relative; + z-index:99; + width: 175px; + -webkit-border-radius: 6px; + border-radius: 6px; + background-color:#C5C5C5; + border: none; + color:#333; + font-weight:400; + padding:0px 0px 0px 8px; + height:20px; + line-height:20px; + overflow:hidden; + -webkit-box-shadow: inset 2px 2px 3px 0px #888; + box-shadow: inset 2px 2px 3px 0px #888; } #musicianlist, .session-controls #genrelist { - width: 150px; + width: 150px; } #genrelist a, #musicianlist a { - color:#333; - text-decoration:none; + color:#333; + text-decoration:none; } .genre-wrapper, .musician-wrapper { - float:left; - width:175px; - height:127px; - overflow:auto; + float:left; + width:175px; + height:127px; + overflow:auto; } .musician-wrapper, .session-controls .genre-wrapper { - width:150px; + width:150px; } .genrecategory { - font-size:11px; - float:left; - width:135px; + font-size:11px; + float:left; + width:135px; } .filtercategory, .session-controls .genrecategory { - font-size:11px; - float:left; - width:110px; + font-size:11px; + float:left; + width:110px; } a.arrow-up { - float:right; - margin-right:5px; - display:block; - margin-top:6px; - width: 0; - height: 0; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #333; + float:right; + margin-right:5px; + display:block; + margin-top:6px; + width: 0; + height: 0; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #333; } a.arrow-down { - float:right; - margin-right:5px; - display:block; - margin-top:6px; - width: 0; - height: 0; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-top: 7px solid #333; + float:right; + margin-right:5px; + display:block; + margin-top:6px; + width: 0; + height: 0; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-top: 7px solid #333; } .settings-session-description { - padding:10px; - width:300px; + padding:10px; + width:300px; } #session-controls { - width:100%; - padding:11px 0px 11px 0px; - background-color:#4c4c4c; - min-height:20px; - overflow-x:hidden; - } + width:100%; + padding:11px 0px 11px 0px; + background-color:#4c4c4c; + min-height:20px; + overflow-x:hidden; + } #session-controls .searchbox { - float:left; - width:140px; - margin-left: 10px; - -webkit-border-radius: 6px; - border-radius: 6px; - background-color:#C5C5C5; - border: none; - color:#333; - font-weight:400; - padding:0px 0px 0px 8px; - height:20px; - line-height:20px; - overflow:hidden; - -webkit-box-shadow: inset 2px 2px 3px 0px #888; - box-shadow: inset 2px 2px 3px 0px #888; + float:left; + width:140px; + margin-left: 10px; + -webkit-border-radius: 6px; + border-radius: 6px; + background-color:#C5C5C5; + border: none; + color:#333; + font-weight:400; + padding:0px 0px 0px 8px; + height:20px; + line-height:20px; + overflow:hidden; + -webkit-box-shadow: inset 2px 2px 3px 0px #888; + box-shadow: inset 2px 2px 3px 0px #888; } #session-controls input[type=text] { - background-color:#c5c5c5; - border:none; - color:#666; + background-color:#c5c5c5; + border:none; + color:#666; } .avatar-tiny { - float:left; - padding:1px; - width:24px; - height:24px; - background-color:#ed3618; - -webkit-border-radius:12px; - -moz-border-radius:12px; - border-radius:12px; + float:left; + padding:1px; + width:24px; + height:24px; + background-color:#ed3618; + -webkit-border-radius:12px; + -moz-border-radius:12px; + border-radius:12px; } .ftue-background { - background-image:url(../images/content/bkg_ftue.jpg); - background-repeat:no-repeat; - background-size:cover; - min-height:475px; - min-width:672px; + background-image:url(../images/content/bkg_ftue.jpg); + background-repeat:no-repeat; + background-size:cover; + min-height:475px; + min-width:672px; } table.generaltable { @@ -350,3 +350,33 @@ ul.shortcuts { white-space:normal; } +.smallbutton { + font-size:10px !important; + padding:2px 8px !important; +} + +.whitespace { + white-space:normal; +} + +.w0 {width:0% !important} +.w5 {width:5% !important} +.w10 {width:10% !important} +.w15 {width:15% !important} +.w20 {width:20% !important} +.w25 {width:25% !important} +.w30 {width:30% !important} +.w35 {width:35% !important} +.w40 {width:40% !important} +.w45 {width:45% !important} +.w50 {width:50% !important} +.w55 {width:55% !important} +.w60 {width:60% !important} +.w65 {width:65% !important} +.w70 {width:70% !important} +.w75 {width:75% !important} +.w80 {width:80% !important} +.w85 {width:85% !important} +.w90 {width:90% !important} +.w95 {width:95% !important} +.w100 {width:100% !important} \ No newline at end of file diff --git a/web/app/assets/stylesheets/client/profile.css.scss b/web/app/assets/stylesheets/client/profile.css.scss index 594b4ff07..1c9bc1441 100644 --- a/web/app/assets/stylesheets/client/profile.css.scss +++ b/web/app/assets/stylesheets/client/profile.css.scss @@ -144,7 +144,7 @@ } .profile-bands { - width:215px; + width:100%; min-height:90px; background-color:#242323; position:relative; @@ -173,6 +173,15 @@ padding-right:5px; } +.profile-band-list-result { + width:100%; + min-height:85px; + background-color:#242323; + position:relative; + margin:10px 0px 10px 0px; + padding-bottom:5px; +} + .profile-social-left { float:left; width:32%; @@ -216,3 +225,15 @@ .profile-block-city { font-size:12px; } + +.profile-musicians { + margin-top:-3px; + font-size:11px; +} + +.profile-musicians td { + border-right:none; + border-top:none; + padding:3px; + vertical-align:middle; +} \ No newline at end of file diff --git a/web/app/views/api_users/band_index.rabl b/web/app/views/api_users/band_index.rabl index 6ac9c409c..dae20b3d6 100644 --- a/web/app/views/api_users/band_index.rabl +++ b/web/app/views/api_users/band_index.rabl @@ -1,7 +1,24 @@ collection @bands # do not retrieve all child collections when showing a list of bands -attributes :id, :name, :location, :photo_url, :logo_url +attributes :id, :name, :city, :state, :country, :location, :website, :biography, :photo_url, :logo_url, :liker_count, :follower_count, :recording_count, :session_count + +node :musicians do |band| + unless band.users.nil? || band.users.size == 0 + child :users => :musicians do + attributes :id, :first_name, :last_name, :name, :photo_url + + # TODO: figure out how to omit empty arrays + node :instruments do |user| + unless user.instruments.nil? || user.instruments.size == 0 + child :musician_instruments => :instruments do + attributes :instrument_id, :description, :proficiency_level, :priority + end + end + end + end + end +end node :genres do |band| unless band.genres.nil? || band.genres.size == 0 diff --git a/web/app/views/clients/_profile.html.erb b/web/app/views/clients/_profile.html.erb index 790c44cee..08c2d3e9f 100644 --- a/web/app/views/clients/_profile.html.erb +++ b/web/app/views/clients/_profile.html.erb @@ -66,6 +66,8 @@

+
+

@@ -106,12 +108,25 @@
-
{name}
+
+ {name}
{location} +

+
{genres}


+ {follower_count}   + {recording_count}   + {session_count}  +
+

+ {biography}

+ PROFILE   + FOLLOW +
+
+ + {musicians} +
-
-
{genres}
- FOLLOW
From 80086efad2c6a3ebebfa3808d4e41fab5e7e0bb8 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sat, 2 Nov 2013 09:59:04 -0400 Subject: [PATCH 07/10] VRFS-686 band profile members module --- ruby/lib/jam_ruby/models/band.rb | 4 + web/app/assets/javascripts/bandProfile.js | 101 ++++++++++++++---- .../stylesheets/client/bandProfile.css.scss | 4 +- web/app/controllers/api_bands_controller.rb | 17 +++ web/app/views/api_bands/musician_index.rabl | 11 ++ web/app/views/clients/_bandProfile.html.erb | 28 +++-- web/app/views/clients/_profile.html.erb | 2 - 7 files changed, 134 insertions(+), 33 deletions(-) create mode 100644 web/app/views/api_bands/musician_index.rabl diff --git a/ruby/lib/jam_ruby/models/band.rb b/ruby/lib/jam_ruby/models/band.rb index 05f0d4645..d853050b7 100644 --- a/ruby/lib/jam_ruby/models/band.rb +++ b/ruby/lib/jam_ruby/models/band.rb @@ -61,6 +61,10 @@ module JamRuby BandMusician.create(:band_id => self.id, :user_id => user_id, :admin => admin) end + def self.musician_index(band_id) + @musicians = User.joins(:band_musicians).where(:bands_musicians => {:band_id => "#{band_id}"}) + end + def self.recording_index(current_user, band_id) hide_private = false band = Band.find(band_id) diff --git a/web/app/assets/javascripts/bandProfile.js b/web/app/assets/javascripts/bandProfile.js index e8bcda013..c98f81525 100644 --- a/web/app/assets/javascripts/bandProfile.js +++ b/web/app/assets/javascripts/bandProfile.js @@ -7,6 +7,7 @@ var logger = context.JK.logger; var bandId; var band = {}; + var instrument_logo_map = context.JK.getInstrumentIconMap24(); function beforeShow(data) { bandId = data.id; @@ -32,9 +33,15 @@ /****************** MAIN PORTION OF SCREEN *****************/ - function addFollowing() { + function addFollowing(isBand, id) { var newFollowing = {}; - newFollowing.band_id = bandId; + + if (!isBand) { + newFollowing.user_id = id; + } + else { + newFollowing.band_id = id; + } var url = "/api/users/" + context.JK.currentUserId + "/followings"; $.ajax({ @@ -46,7 +53,12 @@ processData: false, success: function(response) { renderActive(); // refresh stats - configureFollowingButton(true); + if (isBand) { + configureBandFollowingButton(true); + } + else { + configureMemberFollowingButton(true); + } }, error: app.ajaxError }); @@ -72,7 +84,7 @@ success: function(response) { renderActive(); // refresh stats if (isBand) { - configureFollowingButton(false); + configureBandFollowingButton(false); } else { configureMemberFollowingButton(false, id); @@ -82,6 +94,30 @@ }); } + function isFollowingMember(userId) { + var alreadyFollowing = false; + + var url = "/api/users/" + context.JK.currentUserId + "/followings/" + userId; + $.ajax({ + type: "GET", + dataType: "json", + url: url, + async: false, + processData: false, + success: function(response) { + if (response.id !== undefined) { + alreadyFollowing = true; + } + else { + alreadyFollowing = false; + } + }, + error: app.ajaxError + }); + + return alreadyFollowing; + } + function isFollowing() { var alreadyFollowing = false; @@ -106,7 +142,7 @@ return alreadyFollowing; } - function configureFollowingButton(following) { + function configureBandFollowingButton(following) { $('#btn-follow-band').unbind("click"); if (following) { @@ -117,7 +153,9 @@ } else { $('#btn-follow-band').text('FOLLOW'); - $('#btn-follow-band').click(addFollowing); + $('#btn-follow-band').click(function() { + addFollowing(true, bandId); + }); } } @@ -133,7 +171,9 @@ } else { $btnFollowMember.text('FOLLOW'); - $btnFollowMember.click(addFollowing); + $btnFollowMember.click(function() { + addFollowing(false, userId); + }); } } @@ -297,7 +337,7 @@ $('#band-profile-social').hide(); $('.band-profile-nav a.active').removeClass('active'); - $('.band-profile-nav a.#band-profile-bands-link').addClass('active'); + $('.band-profile-nav a.#band-profile-members-link').addClass('active'); bindMembers(); } @@ -312,21 +352,42 @@ processData:false, success: function(response) { $.each(response, function(index, val) { + var instrumentLogoHtml = ''; + var musician = val; + if ("instruments" in musician) { + for (var j=0; j < musician.instruments.length; j++) { + var instrument = musician.instruments[j]; + var inst = '../assets/content/icon_instrument_default24.png'; + if (instrument.instrument_id in instrument_logo_map) { + inst = instrument_logo_map[instrument.instrument_id]; + } + instrumentLogoHtml += ' '; + } + } + var template = $('#template-band-profile-members').html(); - var bandHtml = context.JK.fillTemplate(template, { - bandId: val.id, - band_url: "/#/bandProfile/" + val.id, - avatar_url: context.JK.resolveAvatarUrl(val.logo_url), - name: val.name, - location: val.location, - genres: formatGenres(val.genres) + var memberHtml = context.JK.fillTemplate(template, { + userId: musician.id, + profile_url: "/#/profile/" + musician.id, + avatar_url: context.JK.resolveAvatarUrl(musician.photo_url), + name: musician.name, + location: musician.location, + friend_count: musician.friend_count, + follower_count: musician.follower_count, + recording_count: musician.recording_count, + session_count: musician.session_count, + instruments: instrumentLogoHtml }); - $('#profile-bands').append(bandHtml); + $('#band-profile-members').append(memberHtml); - // wire up Band Follow button click handler - var following = isFollowingBand(val.id); - configureMemberFollowingButton(following, val.id); + // wire up Follow button click handler + var following = isFollowingMember(musician.id); + configureMemberFollowingButton(following, musician.id); + + // TODO: wire up Friend button click handler + // var friend = isFriend(musician.id); + // configureMemberFriendButton(friend, musician.id); }); }, error: app.ajaxError @@ -357,7 +418,7 @@ // wire up Follow click var following = isFollowing(); - configureFollowingButton(following); + configureBandFollowingButton(following); } function initialize() { diff --git a/web/app/assets/stylesheets/client/bandProfile.css.scss b/web/app/assets/stylesheets/client/bandProfile.css.scss index ada3d0a5c..d1ab30b9c 100644 --- a/web/app/assets/stylesheets/client/bandProfile.css.scss +++ b/web/app/assets/stylesheets/client/bandProfile.css.scss @@ -34,7 +34,7 @@ } .band-profile-nav a { - width:19%; + width:24%; text-align:center; height: 27px; display: block; @@ -144,7 +144,7 @@ } .band-profile-members { - width:215px; + width:100%; min-height:90px; background-color:#242323; position:relative; diff --git a/web/app/controllers/api_bands_controller.rb b/web/app/controllers/api_bands_controller.rb index b815208d0..baf88d43c 100644 --- a/web/app/controllers/api_bands_controller.rb +++ b/web/app/controllers/api_bands_controller.rb @@ -47,6 +47,23 @@ class ApiBandsController < ApiController respond_with @band, responder: ApiResponder, :status => :ok end + def musician_index + unless params[:id].blank? + @musicians = Band.musician_index(params[:id]) + + else + render :json => { :message => "Band ID is required." }, :status => 400 + end + end + + def musician_create + end + + def musician_destroy + unless params[:id].blank? || params[:user_id].blank? + end + end + ###################### FOLLOWERS ######################## def liker_index # NOTE: liker_index.rabl template references the likers property diff --git a/web/app/views/api_bands/musician_index.rabl b/web/app/views/api_bands/musician_index.rabl new file mode 100644 index 000000000..6a85ccd42 --- /dev/null +++ b/web/app/views/api_bands/musician_index.rabl @@ -0,0 +1,11 @@ +collection @musicians + +attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :band_like_count, :follower_count, :following_count, :band_following_count, :recording_count, :session_count + +node :instruments do |musician| + unless musician.instruments.nil? || musician.instruments.size == 0 + child :musician_instruments => :instruments do + attributes :description, :proficiency_level, :priority, :instrument_id + end + end +end diff --git a/web/app/views/clients/_bandProfile.html.erb b/web/app/views/clients/_bandProfile.html.erb index ada1107c6..807aa901b 100644 --- a/web/app/views/clients/_bandProfile.html.erb +++ b/web/app/views/clients/_bandProfile.html.erb @@ -2,7 +2,7 @@
- <%= image_tag "content/icon_profile.png", :size => "19x19" %> + <%= image_tag "content/icon_bands.png", :size => "19x19" %>

band profile

@@ -30,10 +30,10 @@

@@ -76,12 +76,22 @@
-
{name}
+
+ {name}
{location} +

+
{instruments}


+ {friend_count}   + {follower_count}   + {recording_count}   + {session_count}  +
+

+ {biography}

+ PROFILE   + FOLLOW   + CONNECT
-
-
{genres}
- FOLLOW
diff --git a/web/app/views/clients/_profile.html.erb b/web/app/views/clients/_profile.html.erb index 08c2d3e9f..b2a684667 100644 --- a/web/app/views/clients/_profile.html.erb +++ b/web/app/views/clients/_profile.html.erb @@ -66,8 +66,6 @@
-
-

From 5e79e34634c8141dffd4b2314488d77f4e91ba50 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sat, 2 Nov 2013 23:35:18 -0400 Subject: [PATCH 08/10] added biography to user model --- db/manifest | 1 + db/up/add_user_bio.sql | 1 + ruby/lib/jam_ruby/models/user.rb | 10 +++++++--- web/app/assets/javascripts/bandProfile.js | 22 +-------------------- web/app/assets/javascripts/profile.js | 2 +- web/app/views/api_bands/musician_index.rabl | 2 +- web/app/views/api_users/band_index.rabl | 2 +- web/app/views/api_users/index.rabl | 2 +- web/app/views/api_users/show.rabl | 3 ++- web/app/views/clients/_bandProfile.html.erb | 2 +- 10 files changed, 17 insertions(+), 30 deletions(-) create mode 100644 db/up/add_user_bio.sql diff --git a/db/manifest b/db/manifest index 4bc66447b..13ef8931c 100755 --- a/db/manifest +++ b/db/manifest @@ -74,3 +74,4 @@ crash_dumps_idx.sql music_sessions_user_history_add_session_removed_at.sql user_progress_tracking.sql whats_next.sql +add_user_bio.sql \ No newline at end of file diff --git a/db/up/add_user_bio.sql b/db/up/add_user_bio.sql new file mode 100644 index 000000000..725ff5b70 --- /dev/null +++ b/db/up/add_user_bio.sql @@ -0,0 +1 @@ +alter table users add column biography VARCHAR(4000); \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 7af848254..037c490f2 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -422,7 +422,7 @@ module JamRuby # this easy_save routine guards against nil sets, but many of these fields can be set to null. # I've started to use it less as I go forward def easy_save(first_name, last_name, email, password, password_confirmation, musician, gender, - birth_date, internet_service_provider, city, state, country, instruments, photo_url) + birth_date, internet_service_provider, city, state, country, instruments, photo_url, biography = nil) # first name unless first_name.nil? @@ -495,13 +495,17 @@ module JamRuby self.photo_url = photo_url end + unless biography.nil? + self.biography = biography + end + self.updated_at = Time.now.getutc self.save end # helper method for creating / updating a User def self.save(id, updater_id, first_name, last_name, email, password, password_confirmation, musician, gender, - birth_date, internet_service_provider, city, state, country, instruments, photo_url) + birth_date, internet_service_provider, city, state, country, instruments, photo_url, biography) if id.nil? user = User.new() else @@ -513,7 +517,7 @@ module JamRuby end user.easy_save(first_name, last_name, email, password, password_confirmation, musician, gender, - birth_date, internet_service_provider, city, state, country, instruments, photo_url) + birth_date, internet_service_provider, city, state, country, instruments, photo_url, biography) return user end diff --git a/web/app/assets/javascripts/bandProfile.js b/web/app/assets/javascripts/bandProfile.js index c98f81525..d03ce3bdf 100644 --- a/web/app/assets/javascripts/bandProfile.js +++ b/web/app/assets/javascripts/bandProfile.js @@ -229,27 +229,6 @@ // avatar $('#band-profile-avatar').attr('src', context.JK.resolveAvatarUrl(band.photo_url)); - // instruments - // if (user.instruments) { - // for (var i=0; i < user.instruments.length; i++) { - // var instrument = user.instruments[i]; - // var description = instrument.instrument_id; - // var proficiency = instrument.proficiency_level; - // var instrument_icon_url = context.JK.getInstrumentIcon45(description); - - // // add instrument info to layout - // var template = $('#template-profile-instruments').html(); - // var instrumentHtml = context.JK.fillTemplate(template, { - // instrument_logo_url: instrument_icon_url, - // instrument_description: description, - // proficiency_level: proficiencyDescriptionMap[proficiency], - // proficiency_level_css: proficiencyCssMap[proficiency] - // }); - - // $('#profile-instruments').append(instrumentHtml); - // } - // } - // location $('#band-profile-location').html(band.location); @@ -372,6 +351,7 @@ avatar_url: context.JK.resolveAvatarUrl(musician.photo_url), name: musician.name, location: musician.location, + biography: musician.biography, friend_count: musician.friend_count, follower_count: musician.follower_count, recording_count: musician.recording_count, diff --git a/web/app/assets/javascripts/profile.js b/web/app/assets/javascripts/profile.js index 1e1feff0e..fc69c53bc 100644 --- a/web/app/assets/javascripts/profile.js +++ b/web/app/assets/javascripts/profile.js @@ -319,7 +319,7 @@ text = user.recording_count > 1 || user.recording_count == 0 ? " Recordings" : " Recording"; $('#profile-recording-stats').html(user.recording_count + text); - //$('#profile-biography').html(user.biography); + $('#profile-biography').html(user.biography); } else { diff --git a/web/app/views/api_bands/musician_index.rabl b/web/app/views/api_bands/musician_index.rabl index 6a85ccd42..57b723984 100644 --- a/web/app/views/api_bands/musician_index.rabl +++ b/web/app/views/api_bands/musician_index.rabl @@ -1,6 +1,6 @@ collection @musicians -attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :band_like_count, :follower_count, :following_count, :band_following_count, :recording_count, :session_count +attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :band_like_count, :follower_count, :following_count, :band_following_count, :recording_count, :session_count, :biography node :instruments do |musician| unless musician.instruments.nil? || musician.instruments.size == 0 diff --git a/web/app/views/api_users/band_index.rabl b/web/app/views/api_users/band_index.rabl index dae20b3d6..fb7b3a748 100644 --- a/web/app/views/api_users/band_index.rabl +++ b/web/app/views/api_users/band_index.rabl @@ -6,7 +6,7 @@ attributes :id, :name, :city, :state, :country, :location, :website, :biography, node :musicians do |band| unless band.users.nil? || band.users.size == 0 child :users => :musicians do - attributes :id, :first_name, :last_name, :name, :photo_url + attributes :id, :first_name, :last_name, :name, :photo_url, :biography # TODO: figure out how to omit empty arrays node :instruments do |user| diff --git a/web/app/views/api_users/index.rabl b/web/app/views/api_users/index.rabl index 8f9bbf9a7..7d9b57db6 100644 --- a/web/app/views/api_users/index.rabl +++ b/web/app/views/api_users/index.rabl @@ -1,4 +1,4 @@ collection @users # do not retrieve all child collections when showing a list of users -attributes :id, :first_name, :last_name, :name, :city, :state, :country, :email, :online, :musician, :photo_url \ No newline at end of file +attributes :id, :first_name, :last_name, :name, :city, :state, :country, :email, :online, :musician, :photo_url, :biography \ No newline at end of file diff --git a/web/app/views/api_users/show.rabl b/web/app/views/api_users/show.rabl index 99394b57b..9a35978ef 100644 --- a/web/app/views/api_users/show.rabl +++ b/web/app/views/api_users/show.rabl @@ -1,6 +1,7 @@ object @user -attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :band_like_count, :follower_count, :following_count, :band_following_count, :recording_count, :session_count +attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :band_like_count, :follower_count, :following_count, :band_following_count, :recording_count, :session_count, +:biography # give back more info if the user being fetched is yourself if @user == current_user diff --git a/web/app/views/clients/_bandProfile.html.erb b/web/app/views/clients/_bandProfile.html.erb index 807aa901b..6228fd0a1 100644 --- a/web/app/views/clients/_bandProfile.html.erb +++ b/web/app/views/clients/_bandProfile.html.erb @@ -86,7 +86,7 @@ {recording_count}   {session_count} 
-

+

{biography}

PROFILE   FOLLOW   From 2481172acb093aad0a99f79bd8b770a0a6f81e3a Mon Sep 17 00:00:00 2001 From: Seth Call Date: Sat, 2 Nov 2013 20:54:32 +0000 Subject: [PATCH 09/10] * VRFS-831 - moving to other machine. can't tell if my mac is being strange atm --- .../lib/jam_websockets/router.rb | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/websocket-gateway/lib/jam_websockets/router.rb b/websocket-gateway/lib/jam_websockets/router.rb index 99c6c5503..03e2208b1 100644 --- a/websocket-gateway/lib/jam_websockets/router.rb +++ b/websocket-gateway/lib/jam_websockets/router.rb @@ -437,7 +437,6 @@ module JamWebsockets reconnect_music_session_id = login.client_id if login.value_for_tag(5) @log.info("*** handle_login: token=#{token}; client_id=#{client_id}") - connection = nil reconnected = false # you don't have to supply client_id in login--if you don't, we'll generate one @@ -445,9 +444,26 @@ module JamWebsockets # give a unique ID to this client. This is used to prevent session messages # from echoing back to the sender, for instance. client_id = UUIDTools::UUID.random_create.to_s - else + end + + user = valid_login(username, password, token, client_id) + + connection = JamRuby::Connection.find_by_client_id(client_id) + # if this connection is reused by a different user, then whack the connection + # because it will recreate a new connection lower down + if !connection.nil? && !user.nil? && connection.user != user + @log.debug("user #{user.email} took client_id #{client_id} from user #{connection.user.email}") + connection.delete + connection = nil + end + + client.client_id = client_id + + if !user.nil? + @log.debug "user #{user} logged in with client_id #{client_id}" + # check if there's a connection for the client... if it's stale, reconnect it - if connection = JamRuby::Connection.find_by_client_id(client_id) + unless connection.nil? # FIXME: I think connection table needs to updated within connection_manager # otherwise this would be 1 line of code (connection.connect!) @@ -467,21 +483,10 @@ module JamWebsockets end if connection.stale? end - # if there's a client_id but no connection object, create new client_id - client_id = UUIDTools::UUID.random_create.to_s if !connection - end - - client.client_id = client_id - - user = valid_login(username, password, token, client_id) - - if !user.nil? - @log.debug "user #{user} logged in" # respond with LOGIN_ACK to let client know it was successful remote_ip = extract_ip(client) - @semaphore.synchronize do # remove from pending_queue @pending_clients.delete(client) @@ -696,7 +701,7 @@ module JamWebsockets @@log.debug "publishing to session:#{music_session_id} client:#{client_id} from client:#{sender_client_id}" # put it on the topic exchange3 for clients - self.class.client_exchange.publish(client_msg, :routing_key => "client.#{music_session_id}") + self.class.client_exchange.publish(client_msg, :routing_key => "client.#{client_id}") end end end From aea3434d02860d6abff14ac39e299a33f761287f Mon Sep 17 00:00:00 2001 From: Seth Call Date: Sun, 3 Nov 2013 15:23:46 -0600 Subject: [PATCH 10/10] * VRFS-831 - looks finished --- web/spec/controllers/claimed_recordings_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/spec/controllers/claimed_recordings_spec.rb b/web/spec/controllers/claimed_recordings_spec.rb index 6aecf0458..ae154c1d7 100644 --- a/web/spec/controllers/claimed_recordings_spec.rb +++ b/web/spec/controllers/claimed_recordings_spec.rb @@ -26,8 +26,7 @@ describe ApiClaimedRecordingsController do it "should show the right thing when one recording just finished" do controller.current_user = @user get :show, :id => @claimed_recording.id -# puts response.body - response.should be_success + response.should be_success json = JSON.parse(response.body) json.should_not be_nil json["id"].should == @claimed_recording.id