diff --git a/db/manifest b/db/manifest index 06a48eb7d..004eb74e6 100755 --- a/db/manifest +++ b/db/manifest @@ -200,4 +200,5 @@ median_aggregate.sql current_scores_use_median.sql current_scores_ams_index_sms_index_use_user_instrument.sql locidispid_in_score_histories.sql -define_environment_in_db.sql \ No newline at end of file +define_environment_in_db.sql +drop_session_invite_constraint.sql \ No newline at end of file diff --git a/db/up/drop_session_invite_constraint.sql b/db/up/drop_session_invite_constraint.sql new file mode 100644 index 000000000..a49ea7878 --- /dev/null +++ b/db/up/drop_session_invite_constraint.sql @@ -0,0 +1 @@ +ALTER TABLE invitations DROP CONSTRAINT invitations_uniqkey; \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/feed.rb b/ruby/lib/jam_ruby/models/feed.rb index 6ac48f792..cd68b8bd4 100644 --- a/ruby/lib/jam_ruby/models/feed.rb +++ b/ruby/lib/jam_ruby/models/feed.rb @@ -1,4 +1,3 @@ - module JamRuby class Feed < ActiveRecord::Base @@ -73,15 +72,10 @@ module JamRuby end - if target_user + if target_user - if target_user != user.id - require_public_recordings = "claimed_recordings.is_public = TRUE AND" - require_public_sessions = "music_sessions.fan_access = TRUE AND" - end - - query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND #{require_public_recordings} (claimed_recordings.user_id = '#{target_user}' OR (recordings.band_id IN (SELECT band_id FROM bands_musicians where user_id='#{target_user}')))") - query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id AND #{require_public_sessions} music_sessions_user_history.user_id = '#{target_user}'") + query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND (claimed_recordings.user_id = '#{target_user}' OR (recordings.band_id IN (SELECT band_id FROM bands_musicians where user_id='#{target_user}')))") + query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id AND music_sessions_user_history.user_id = '#{target_user}'") query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions.id") if sort == 'plays' query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)") @@ -93,13 +87,8 @@ module JamRuby elsif target_band - unless Band.find(target_band).users.include?(user) - require_public_recordings = "claimed_recordings.is_public = TRUE AND" - require_public_sessions = "music_sessions.fan_access = TRUE AND" - end - - query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND #{require_public_recordings} recordings.band_id = '#{target_band}'") - query = query.where("music_sessions IS NULL OR #{require_public_sessions} music_sessions.band_id = '#{target_band}'") + query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND recordings.band_id = '#{target_band}'") + query = query.where("music_sessions IS NULL OR music_sessions.band_id = '#{target_band}'") query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions.id") if sort == 'plays' query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)") @@ -109,8 +98,8 @@ module JamRuby query = query.where('recordings.id is NULL OR claimed_recordings.id IS NOT NULL') #query = query.where('music_sessions.id is NULL OR music_sessions_user_history.id IS NOT NULL') else - query = query.joins('LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND claimed_recordings.is_public = TRUE') - query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id AND music_sessions.fan_access = TRUE") + query = query.joins('LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE') + query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id") query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions.id") if sort == 'plays' query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)") @@ -121,9 +110,6 @@ module JamRuby query = query.where('music_sessions.id is NULL OR music_sessions_user_history.id IS NOT NULL') end - - - if params[:hash] if query.length == 0 { query:query, next: nil} diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb index c22444066..6ea00de1d 100644 --- a/ruby/lib/jam_ruby/models/music_session.rb +++ b/ruby/lib/jam_ruby/models/music_session.rb @@ -524,7 +524,7 @@ module JamRuby # retrieve users that have invitations but have not submitted an RSVP request for this session def pending_invitations - User.find_by_sql(%Q{select u.id, u.email, u.photo_url, u.first_name, u.last_name + User.find_by_sql(%Q{select distinct u.id, u.email, u.photo_url, u.first_name, u.last_name from users u inner join invitations i on u.id = i.receiver_id left join rsvp_requests rr on rr.user_id = i.receiver_id diff --git a/ruby/lib/jam_ruby/models/notification.rb b/ruby/lib/jam_ruby/models/notification.rb index e21e358c8..0993ab157 100644 --- a/ruby/lib/jam_ruby/models/notification.rb +++ b/ruby/lib/jam_ruby/models/notification.rb @@ -762,7 +762,7 @@ module JamRuby return if music_session.nil? rsvp_requests = RsvpRequest.index(music_session) - target_users = rsvp_requests.map { |r| r.user } + target_users = rsvp_requests.where(:canceled => false).map { |r| r.user } # remove the creator from the array target_users = target_users.uniq - [music_session.creator] @@ -804,7 +804,7 @@ module JamRuby return if music_session.nil? rsvp_requests = RsvpRequest.index(music_session) - target_users = rsvp_requests.map { |r| r.user } + target_users = rsvp_requests.where(:canceled => false).map { |r| r.user } pending_invites = music_session.pending_invitations # remove the creator from the array @@ -847,7 +847,7 @@ module JamRuby return if music_session.nil? rsvp_requests = RsvpRequest.index(music_session) - target_users = rsvp_requests.map { |r| r.user } + target_users = rsvp_requests.where(:canceled => false).map { |r| r.user } # remove the creator from the array target_users = target_users.uniq - [music_session.creator] @@ -884,12 +884,12 @@ module JamRuby end end - def send_scheduled_session_comment(music_session, creator, comment) + def send_scheduled_session_comment(music_session, creator, comment, send_to_cancelled = false) return if music_session.nil? || creator.nil? || comment.blank? rsvp_requests = RsvpRequest.index(music_session) - target_users = rsvp_requests.map { |r| r.user } + target_users = send_to_cancelled ? rsvp_requests.map { |r| r.user } : rsvp_requests.where(:canceled => false).map { |r| r.user } target_users = target_users.concat([music_session.creator]) pending_invites = music_session.pending_invitations diff --git a/ruby/lib/jam_ruby/models/rsvp_request.rb b/ruby/lib/jam_ruby/models/rsvp_request.rb index 3558df969..689aad72e 100644 --- a/ruby/lib/jam_ruby/models/rsvp_request.rb +++ b/ruby/lib/jam_ruby/models/rsvp_request.rb @@ -33,6 +33,7 @@ module JamRuby rs.music_session_id = '#{music_session.id}' } ) + .order('rsvp_requests.created_at DESC') if options[:status] == 'approved' query = query.where("rrrs.chosen = true AND canceled != TRUE") @@ -98,11 +99,12 @@ module JamRuby end # verify user has not already submitted RSVP request for this slot - user_slot = RsvpRequest.joins(:rsvp_requests_rsvp_slots) + rsvp = RsvpRequest.joins(:rsvp_requests_rsvp_slots) .where(:user_id => user.id) + .where(:canceled => false) .where(rsvp_requests_rsvp_slots: {rsvp_slot_id: id}) - if !user_slot.blank? + if !rsvp.blank? raise StateError, "You have already submitted an RSVP request for this slot." end @@ -264,7 +266,7 @@ module JamRuby session_info_comment.user = user session_info_comment.comment = params[:message] session_info_comment.save - Notification.send_scheduled_session_comment(music_session, user, params[:message]) + Notification.send_scheduled_session_comment(music_session, user, params[:message], true) end end end diff --git a/ruby/spec/jam_ruby/models/feed_spec.rb b/ruby/spec/jam_ruby/models/feed_spec.rb index 54ec1955e..dc790f13c 100644 --- a/ruby/spec/jam_ruby/models/feed_spec.rb +++ b/ruby/spec/jam_ruby/models/feed_spec.rb @@ -255,7 +255,7 @@ describe Feed do end describe "public feed" do - it "only public" do + it "public and private" do claimed_recording1 = FactoryGirl.create(:claimed_recording) claimed_recording1.is_public = false claimed_recording1.save! @@ -267,7 +267,7 @@ describe Feed do claimed_recording1.recording.music_session.music_session.save! feeds, start = Feed.index(claimed_recording1.user) - feeds.length.should == 0 + feeds.length.should == 1 end end @@ -302,7 +302,7 @@ describe Feed do feeds[0].music_session.should == music_session.music_session end - it "shows private sessions to you, not to others" do + it "shows private sessions to you and to others" do user1.bands << band user1.save! music_session = FactoryGirl.create(:active_music_session, band: band, fan_access: false) @@ -315,7 +315,7 @@ describe Feed do feeds, start = Feed.index(user2, band: band.id) - feeds.length.should == 0 + feeds.length.should == 1 end it "shows public recordings to you and to others" do @@ -334,7 +334,7 @@ describe Feed do feeds[0].recording.should == claimed_recording1.recording end - it "shows private recordings to you, not to others" do + it "shows private recordings to you and to others" do claimed_recording1 = FactoryGirl.create(:claimed_recording) claimed_recording1.is_public = false claimed_recording1.recording.band = band @@ -349,7 +349,7 @@ describe Feed do feeds[0].recording.should == claimed_recording1.recording feeds, start = Feed.index(user1, band: band.id) - feeds.length.should == 0 + feeds.length.should == 1 end end @@ -380,7 +380,7 @@ describe Feed do end - it "shows private sessions to you, not to others" do + it "shows private sessions to you and to others" do music_session = FactoryGirl.create(:active_music_session, fan_access: false) music_session.music_session.fan_access.should be_false FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user1) @@ -392,7 +392,7 @@ describe Feed do feeds, start = Feed.index(user2, user: user1.id) - feeds.length.should == 0 + feeds.length.should == 1 end it "shows public recordings to you and to others" do @@ -409,7 +409,7 @@ describe Feed do feeds[0].recording.should == claimed_recording1.recording end - it "shows private recordings to you, not to others" do + it "shows private recordings to you and to others" do claimed_recording1 = FactoryGirl.create(:claimed_recording) claimed_recording1.is_public = false claimed_recording1.save! @@ -419,7 +419,7 @@ describe Feed do feeds[0].recording.should == claimed_recording1.recording feeds, start = Feed.index(user1, user: claimed_recording1.user.id) - feeds.length.should == 0 + feeds.length.should == 1 end it "shows band recordings to you even though you did not claim a recording" do diff --git a/web/Gemfile b/web/Gemfile index 79d35c7d5..dfe7723e3 100644 --- a/web/Gemfile +++ b/web/Gemfile @@ -78,6 +78,7 @@ gem 'iso-639' gem 'language_list' gem 'rubyzip' gem 'slim' +gem 'htmlentities' group :development, :test do gem 'rspec-rails', '2.14.2' diff --git a/web/app/assets/javascripts/JamServer.js b/web/app/assets/javascripts/JamServer.js index 7460a0238..6ef8260a2 100644 --- a/web/app/assets/javascripts/JamServer.js +++ b/web/app/assets/javascripts/JamServer.js @@ -508,7 +508,7 @@ logger.error("server.connect should never be called if we are already connected. cancelling.") return; } - + if(!clientType) { clientType = context.JK.clientType(); } diff --git a/web/app/assets/javascripts/dialog/commentDialog.js b/web/app/assets/javascripts/dialog/commentDialog.js index 794ee141b..958d6ec27 100644 --- a/web/app/assets/javascripts/dialog/commentDialog.js +++ b/web/app/assets/javascripts/dialog/commentDialog.js @@ -71,7 +71,7 @@ user_id: userId, hoverAction: musician ? "musician" : "fan", name: userName, - comment: comment, + comment: context._.unescape(comment), timeago: timeago }; diff --git a/web/app/assets/javascripts/dialog/rsvpSubmitDialog.js b/web/app/assets/javascripts/dialog/rsvpSubmitDialog.js index 895927135..be8bf3afa 100644 --- a/web/app/assets/javascripts/dialog/rsvpSubmitDialog.js +++ b/web/app/assets/javascripts/dialog/rsvpSubmitDialog.js @@ -40,8 +40,7 @@ $.each(response.open_slots, function(index, val) { var instrument = val.instrument_id; - var instrumentTitleCase = context.JK.toTitleCase(instrument); - $('.rsvp-instruments', $dialog).append('' + instrumentTitleCase + "
"); + $('.rsvp-instruments', $dialog).append('' + val.description + " (" + val.proficiency_desc + ")
"); }); } } diff --git a/web/app/assets/javascripts/inviteMusicians.js b/web/app/assets/javascripts/inviteMusicians.js index 60d60b067..d7f6b933c 100644 --- a/web/app/assets/javascripts/inviteMusicians.js +++ b/web/app/assets/javascripts/inviteMusicians.js @@ -41,14 +41,19 @@ friendSelectorDialog.setCallback(friendSelectorCallback); inviteAction = 'update'; - friendInput = '#friend-input-'+inviteAction; + friendInput = '#friend-input-' + inviteAction; if (0 == $(elemSelector + ' .friendbox').length) { _appendFriendSelector($(elemSelector)); - $('#btn-save-invites').click(function() { - createInvitations(updateSessionID); - }); } + + $('#btn-save-invites').unbind('click'); + + $('#btn-save-invites').click(function() { + createInvitations(updateSessionID); + app.layout.closeDialog('select-invites'); + }); + $.ajax({ url: "/api/invitations", data: { session_id: sessionId, sender: context.JK.currentUserId } @@ -112,10 +117,6 @@ } } - function _inviteExists(userID) { - return 0 <= existingInvites.indexOf(userID); - } - function addInvitation(value, data) { if (undefined === data) { data = value.data; @@ -123,11 +124,9 @@ } if (0 > invitedFriends.indexOf(data)) { var template = $('#template-added-invitation').html(); - var imgStyle = _inviteExists(data) ? 'display:none' : ''; var invitationHtml = context.JK.fillTemplate(template, {userId: data, - userName: value, - imageStyle: imgStyle}); + userName: value}); $('.selected-friends').append(invitationHtml); $(friendInput).select(); invitedFriends.push(data); @@ -162,22 +161,20 @@ function createInvitations(sessionId, onComplete) { var callCount = 0; - var totalInvitations = invitedFriends.length - existingInvites.length; + var totalInvitations = invitedFriends.length; invitedFriends.map(function(invite_id) { - if (!_inviteExists(invite_id)) { - callCount++; - var invite = { - music_session: sessionId, - receiver: invite_id - }; - $.ajax({ - type: "POST", - url: "/api/invitations", - data: invite - }).done(function(response) { - callCount--; - }).fail(app.ajaxError); - } + callCount++; + var invite = { + music_session: sessionId, + receiver: invite_id + }; + $.ajax({ + type: "POST", + url: "/api/invitations", + data: invite + }).done(function(response) { + callCount--; + }).fail(app.ajaxError); }); // TODO - this is the second time I've used this pattern. // refactor to make a common utility for this. @@ -221,16 +218,16 @@ function _friendSelectorHTML() { var fInput = friendInput ? friendInput.substring(1,friendInput.length) : ''; return context.JK.fillTemplate($('#template-session-invite-musicians').html(), - {choose_friends_id: 'btn-choose-friends-'+inviteAction, - selected_friends_id: 'selected-friends-'+inviteAction, + {choose_friends_id: 'btn-choose-friends-' + inviteAction, + selected_friends_id: 'selected-friends-' + inviteAction, friend_input: fInput, instructions: addInstructions}); } function _appendFriendSelector(elemSelector) { elemSelector.append(_friendSelectorHTML()); - $('#selected-friends-'+inviteAction).on("click", ".invitation a", removeInvitation); - $('#btn-choose-friends-'+inviteAction).click(function(){ + $('#selected-friends-' + inviteAction).on("click", ".invitation a", removeInvitation); + $('#btn-choose-friends-' + inviteAction).click(function(){ var obj = {}; invitedFriends.map(function(uid) { obj[uid] = true; }); friendSelectorDialog.showDialog(obj); diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js index 619ea3036..9d51abb2a 100644 --- a/web/app/assets/javascripts/jam_rest.js +++ b/web/app/assets/javascripts/jam_rest.js @@ -226,14 +226,10 @@ } function cancelRsvpRequest(sessionId, rsvpRequestId, cancelAll) { - var cancel = "yes"; - if (cancelAll) { - cancel = "all"; - } return $.ajax({ url: '/api/rsvp_requests/' + rsvpRequestId, type: "DELETE", - data : JSON.stringify({"session_id": sessionId, "cancelled": cancel}), + data : JSON.stringify({"session_id": sessionId, "cancelled": cancelAll}), dataType : 'json', contentType: 'application/json' }); diff --git a/web/app/assets/javascripts/sessionList.js b/web/app/assets/javascripts/sessionList.js index 4321cc183..705ccafae 100644 --- a/web/app/assets/javascripts/sessionList.js +++ b/web/app/assets/javascripts/sessionList.js @@ -142,7 +142,7 @@ var rsvpUsersHtml = '', openSlotsHtml = '', latencyHtml = '', notationFileHtml = ''; context._.each(session.pending_rsvp_requests, function(pending_rsvp_request) { - if(pending_rsvp_request.user_id == context.JK.currentUserId) { + if(pending_rsvp_request.user_id === context.JK.currentUserId) { pendingRsvpId = pending_rsvp_request.id; } }); @@ -185,6 +185,29 @@ } } + // notation files + if (session.music_notations) { + for (i=0; i < session.music_notations.length; i++) { + notationFileHtml += createNotationFile(session.music_notations[i]); + } + } + + var sessionVals = buildSessionObject(session, notationFileHtml, rsvpUsersHtml, openSlotsHtml, latencyHtml); + sessionVals.scheduled_start = session.pretty_scheduled_start_with_timezone; + + var row = context.JK.fillTemplate($inactiveSessionTemplate.html(), sessionVals); + + // initial page load + if (!$rowToUpdate) { + $(tbGroup).append(row); + } + // inline update after an RSVP submission / cancellation + else { + $rowToUpdate.replaceWith(row); + } + + var $parentRow = $('tr[data-session-id=' + session.id + ']', tbGroup); + var showRsvpLink = true; var noLinkText = ''; @@ -194,7 +217,10 @@ noLinkText.find('a').click(function() { ui.launchRsvpCancelDialog(session.id, approvedRsvpId) .one(EVENTS.RSVP_CANCELED, function() { - // VRFS-1891 + rest.getSessionHistory(session.id) + .done(function(response) { + renderInactiveSession(response, tbGroup, $parentRow); + }); }) .one(EVENTS.DIALOG_CLOSED, function() { $(this).unbind(EVENTS.RSVP_CANCELED); @@ -208,7 +234,10 @@ noLinkText.find('a').click(function() { ui.launchRsvpCancelDialog(session.id, pendingRsvpId) .one(EVENTS.RSVP_CANCELED, function() { - // VRFS-1891 + rest.getSessionHistory(session.id) + .done(function(response) { + renderInactiveSession(response, tbGroup, $parentRow); + }); }) .one(EVENTS.DIALOG_CLOSED, function() { $(this).unbind(EVENTS.RSVP_CANCELED); @@ -224,35 +253,10 @@ showRsvpLink = false; noLinkText = 'You need an invitation to RSVP to this session.'; } - - // notation files - if (session.music_notations) { - for (i=0; i < session.music_notations.length; i++) { - notationFileHtml += createNotationFile(session.music_notations[i]); - } - } - - var sessionVals = buildSessionObject(session, notationFileHtml, rsvpUsersHtml, openSlotsHtml, latencyHtml); - sessionVals.scheduled_start = session.pretty_scheduled_start_with_timezone; - sessionVals.rsvp_link_display_style = showRsvpLink ? "block" : "none"; - - var row = context.JK.fillTemplate($inactiveSessionTemplate.html(), sessionVals); - - // initial page load - if (!$rowToUpdate) { - $(tbGroup).append(row); - } - // inline update after an RSVP submission / cancellation - else { - $rowToUpdate.replaceWith(row); - } - - var $parentRow = $('tr[data-session-id=' + session.id + ']', tbGroup); if (showRsvpLink) { - $('.rsvp-msg', $parentRow).hide(); - var $parentRow = $('tr[data-session-id=' + session.id + ']', tbGroup); + $('.rsvp-link', $parentRow).show(); $('.rsvp-link', $parentRow).click(function(evt) { ui.launchRsvpSubmitDialog(session.id) @@ -270,6 +274,7 @@ } else { $('.rsvp-msg', $parentRow).html(noLinkText).show(); + $('.rsvp-link', $parentRow).hide(); } } diff --git a/web/app/assets/javascripts/web/session_info.js b/web/app/assets/javascripts/web/session_info.js index d95684437..3886a6068 100644 --- a/web/app/assets/javascripts/web/session_info.js +++ b/web/app/assets/javascripts/web/session_info.js @@ -39,7 +39,7 @@ user_id: userId, hoverAction: "musician", name: userName, - comment: comment, + comment: context._.unescape(comment), timeago: timeago }); @@ -150,11 +150,18 @@ rest.getRsvpRequests(musicSessionId) .done(function(rsvps) { if (rsvps && rsvps.length > 0) { - // should only be 1 RSVP for this session and user + // the first RSVP should be the most recent (users may have many RSVPs to same session if they cancel + // and resubmit); use its status to determine what CTA to present var rsvp = rsvps[0]; if (rsvp.canceled) { - $('.call-to-action').html('Your RSVP request to this session has been cancelled.'); - $btnAction.hide(); + $('.call-to-action').html("Tell the session organizer you'd like to play in this session"); + $btnAction.html('RSVP NOW!'); + $btnAction.click(function(e) { + ui.launchRsvpSubmitDialog(musicSessionId) + .one(EVENTS.RSVP_SUBMITTED, function() { + location.reload(); + }) + }); } else { var declined = true; diff --git a/web/app/assets/javascripts/web/sessions.js b/web/app/assets/javascripts/web/sessions.js index 4686f34dc..e6727fb91 100644 --- a/web/app/assets/javascripts/web/sessions.js +++ b/web/app/assets/javascripts/web/sessions.js @@ -39,7 +39,7 @@ user_id: userId, hoverAction: musician ? "musician" : "fan", name: userName, - comment: comment, + comment: context._.unescape(comment), timeago: timeago }); diff --git a/web/app/controllers/api_controller.rb b/web/app/controllers/api_controller.rb index 85d425c82..b27e41e9b 100644 --- a/web/app/controllers/api_controller.rb +++ b/web/app/controllers/api_controller.rb @@ -1,6 +1,7 @@ class ApiController < ApplicationController @@log = Logging.logger[ApiController] + @@html_encoder = HTMLEntities.new # define common error handlers rescue_from 'JamRuby::StateError' do |exception| diff --git a/web/app/controllers/api_feeds_controller.rb b/web/app/controllers/api_feeds_controller.rb index 693fbe73e..b2e2c08cd 100644 --- a/web/app/controllers/api_feeds_controller.rb +++ b/web/app/controllers/api_feeds_controller.rb @@ -4,14 +4,14 @@ class ApiFeedsController < ApiController def index data = Feed.index(current_user, - start: params[:since], - limit: params[:limit], - sort: params[:sort], - time_range: params[:time_range], - type: params[:type], - user: params[:user], - band: params[:band], - hash: true) + start: params[:since], + limit: params[:limit], + sort: params[:sort], + time_range: params[:time_range], + type: params[:type], + user: params[:user], + band: params[:band], + hash: true) @feeds = data[:query] diff --git a/web/app/controllers/api_invitations_controller.rb b/web/app/controllers/api_invitations_controller.rb index 58a3965e6..b1c91ddb5 100644 --- a/web/app/controllers/api_invitations_controller.rb +++ b/web/app/controllers/api_invitations_controller.rb @@ -15,19 +15,19 @@ class ApiInvitationsController < ApiController raise PermissionError, "You can only ask for your own sent invitations" end if session_id = params[:session_id] - @invitations = Invitation.where(:sender_id => sender_id, :music_session_id => session_id) + @invitations = Invitation.where(:sender_id => sender_id, :music_session_id => session_id).uniq_by { |i| i.receiver_id } else - @invitations = Invitation.where(:sender_id => current_user.id) + @invitations = Invitation.where(:sender_id => current_user.id).uniq_by { |i| i.receiver_id } end elsif !receiver_id.nil? if current_user.id != receiver_id raise PermissionError, "You can only ask for your own received invitations" end - @invitations = Invitation.where(:receiver_id => current_user.id) + @invitations = Invitation.where(:receiver_id => current_user.id).uniq_by { |i| i.receiver_id } else # default to invitations you've received - @invitations = Invitation.where(:receiver_id => current_user.id) + @invitations = Invitation.where(:receiver_id => current_user.id).uniq_by { |i| i.receiver_id } end end diff --git a/web/app/controllers/api_music_sessions_controller.rb b/web/app/controllers/api_music_sessions_controller.rb index eae4ec2fb..f3f460b50 100644 --- a/web/app/controllers/api_music_sessions_controller.rb +++ b/web/app/controllers/api_music_sessions_controller.rb @@ -469,7 +469,7 @@ class ApiMusicSessionsController < ApiController comment = MusicSessionComment.new comment.music_session_id = params[:id] comment.creator_id = params[:user_id] - comment.comment = params[:comment] + comment.comment = @@html_encoder.encode(params[:comment]) comment.ip_address = request.remote_ip comment.save @@ -496,7 +496,7 @@ class ApiMusicSessionsController < ApiController comment = SessionInfoComment.new comment.music_session_id = params[:id] comment.creator_id = current_user.id - comment.comment = params[:comment] + comment.comment = @@html_encoder.encode(params[:comment]) comment.save if comment.errors.any? diff --git a/web/app/controllers/api_recordings_controller.rb b/web/app/controllers/api_recordings_controller.rb index 75e3ea6f4..66c5625f9 100644 --- a/web/app/controllers/api_recordings_controller.rb +++ b/web/app/controllers/api_recordings_controller.rb @@ -108,7 +108,7 @@ class ApiRecordingsController < ApiController comment = RecordingComment.new comment.recording_id = params[:id] comment.creator_id = params[:user_id] - comment.comment = params[:comment] + comment.comment = @@html_encoder.encode(params[:comment]) comment.ip_address = request.remote_ip comment.save diff --git a/web/app/helpers/feeds_helper.rb b/web/app/helpers/feeds_helper.rb index 1f9f135b6..c77c382cd 100644 --- a/web/app/helpers/feeds_helper.rb +++ b/web/app/helpers/feeds_helper.rb @@ -1,4 +1,6 @@ module FeedsHelper + PRIVATE_TEXT = "Private" + def session_artist_name(music_session) (music_session.band.nil? ? nil : music_session.band.name) || music_session.creator.name end @@ -47,8 +49,20 @@ module FeedsHelper end end - def session_description(music_session) - music_session.description + def session_name(music_session, user) + if music_session.fan_access || music_session.unique_users.include?(user) + music_session.name + else + PRIVATE_TEXT + end + end + + def session_description(music_session, user) + if music_session.fan_access || music_session.unique_users.include?(user) + music_session.description + else + PRIVATE_TEXT + end end # grabs 1st genre @@ -80,12 +94,22 @@ module FeedsHelper duration(recording.duration, options) end - def recording_name(recording) - recording.candidate_claimed_recording.name + def recording_name(recording, user) + r = recording.candidate_claimed_recording + if r.is_public || recording.users.include?(user) + r.name + else + PRIVATE_TEXT + end end - def recording_description(recording) - recording.candidate_claimed_recording.description + def recording_description(recording, user) + r = recording.candidate_claimed_recording + if r.is_public || recording.users.include?(user) + r.description + else + PRIVATE_TEXT + end end def recording_genre(recording) diff --git a/web/app/views/api_feeds/show.rabl b/web/app/views/api_feeds/show.rabl index e502fcbf7..fc877a6ec 100644 --- a/web/app/views/api_feeds/show.rabl +++ b/web/app/views/api_feeds/show.rabl @@ -7,7 +7,7 @@ glue :music_session do 'music_session' end - attributes :id, :description, :genres, :created_at, :session_removed_at, :comment_count, :like_count, :play_count, :fan_access, :is_over?, :has_mount? + attributes :id, :genres, :created_at, :session_removed_at, :comment_count, :like_count, :play_count, :fan_access, :is_over?, :has_mount? node do |history| { @@ -18,7 +18,8 @@ glue :music_session do artist_datakey: session_artist_datakey(history), artist_hoveraction: session_artist_hoveraction(history), utc_created_at: history.created_at.getutc.iso8601, - description: session_description(history), + name: session_name(history, current_user), + description: session_description(history, current_user), status: session_text(history), duration: session_duration_value(history), duration_secs: history.created_at.to_i, @@ -88,8 +89,8 @@ glue :recording do artist_hoveraction: recording_artist_hoveraction(recording), artist_datakey: recording_artist_datakey(recording), utc_created_at: recording.created_at.getutc.iso8601, - name: recording_name(recording), - description: recording_description(recording), + name: recording_name(recording, current_user), + description: recording_description(recording, current_user), genre: recording_genre(recording) } } @@ -140,7 +141,7 @@ glue :recording do child(:claimed_recordings => :claimed_recordings) { - attributes :id, :name, :description, :is_public, :genre_id, :has_mix?, :user_id + attributes :id, :is_public, :genre_id, :has_mix?, :user_id child(:user => :creator) { attributes :id, :first_name, :last_name, :photo_url diff --git a/web/app/views/clients/_findSession.html.erb b/web/app/views/clients/_findSession.html.erb index d37595e00..5b642c0f2 100644 --- a/web/app/views/clients/_findSession.html.erb +++ b/web/app/views/clients/_findSession.html.erb @@ -202,7 +202,7 @@ - + <%= image_tag "content/icon_join.png", :size => "19x22" %> @@ -220,7 +220,7 @@ - + {musician_name} diff --git a/web/app/views/clients/_hoverBand.html.erb b/web/app/views/clients/_hoverBand.html.erb index 491199b31..3bc440c21 100644 --- a/web/app/views/clients/_hoverBand.html.erb +++ b/web/app/views/clients/_hoverBand.html.erb @@ -52,7 +52,7 @@ diff --git a/web/app/views/users/_feed_music_session.html.haml b/web/app/views/users/_feed_music_session.html.haml index d7dda270b..33be9304f 100644 --- a/web/app/views/users/_feed_music_session.html.haml +++ b/web/app/views/users/_feed_music_session.html.haml @@ -11,8 +11,10 @@ = timeago(feed_item.created_at, class: 'small created_at') / name and description .left.ml20.w30 + .name.dotdotdot + = session_name(feed_item, current_user) .description.dotdotdot - = session_description(feed_item) + = session_description(feed_item, current_user) / timeline and controls .right.w40 / recording play controls diff --git a/web/app/views/users/_feed_music_session_ajax.html.haml b/web/app/views/users/_feed_music_session_ajax.html.haml index dddf4a630..44e9cff84 100644 --- a/web/app/views/users/_feed_music_session_ajax.html.haml +++ b/web/app/views/users/_feed_music_session_ajax.html.haml @@ -14,6 +14,8 @@ %time.small.created_at.timeago{datetime: '{{data.feed_item.helpers.utc_created_at}}'}= '{{data.feed_item.created_at}}' / name and description .left.ml20.w30 + .name.dotdotdot + %span.name-text {{data.feed_item.helpers.name}} .description.dotdotdot = '{{data.feed_item.helpers.description}}' / timeline and controls diff --git a/web/app/views/users/_feed_recording.html.haml b/web/app/views/users/_feed_recording.html.haml index 389175298..e81203183 100644 --- a/web/app/views/users/_feed_recording.html.haml +++ b/web/app/views/users/_feed_recording.html.haml @@ -15,9 +15,9 @@ / name and description .name-and-description .name.dotdotdot - = recording_name(feed_item) + = recording_name(feed_item, current_user) .description.dotdotdot - = recording_description(feed_item) + = recording_description(feed_item, current_user) / timeline and controls .recording-controls-holder / recording play controls diff --git a/web/spec/controllers/api_feeds_controller_spec.rb b/web/spec/controllers/api_feeds_controller_spec.rb index e89a32f95..e6b73e23f 100644 --- a/web/spec/controllers/api_feeds_controller_spec.rb +++ b/web/spec/controllers/api_feeds_controller_spec.rb @@ -124,6 +124,9 @@ describe ApiFeedsController do get :index, { user: music_session.creator.id } json = JSON.parse(response.body, :symbolize_names => true) json[:entries].length.should == 1 + + json[:entries][0][:helpers][:name].should == music_session.music_session.name + json[:entries][0][:helpers][:description].should == music_session.music_session.description end it "user viewing someone else's profile" do @@ -135,7 +138,10 @@ describe ApiFeedsController do get :index, { user: music_session.creator.id } json = JSON.parse(response.body, :symbolize_names => true) - json[:entries].length.should == 0 + json[:entries].length.should == 1 + + json[:entries][0][:helpers][:name].should == "Private" + json[:entries][0][:helpers][:description].should == "Private" end end @@ -155,6 +161,9 @@ describe ApiFeedsController do get :index, { band: band.id } json = JSON.parse(response.body, :symbolize_names => true) json[:entries].length.should == 1 + + json[:entries][0][:helpers][:name].should == claimed_recording1.name + json[:entries][0][:helpers][:description].should == claimed_recording1.description end it "user viewing someone else's band" do @@ -171,7 +180,10 @@ describe ApiFeedsController do get :index, { band: band.id } json = JSON.parse(response.body, :symbolize_names => true) - json[:entries].length.should == 0 + json[:entries].length.should == 1 + + json[:entries][0][:helpers][:name].should == "Private" + json[:entries][0][:helpers][:description].should == "Private" end end end diff --git a/web/spec/features/welcome_spec.rb b/web/spec/features/welcome_spec.rb index 6207af5ae..78da6b97a 100644 --- a/web/spec/features/welcome_spec.rb +++ b/web/spec/features/welcome_spec.rb @@ -218,7 +218,7 @@ describe "Welcome", :js => true, :type => :feature, :capybara_feature => true d visit "/" find('h1', text: 'Play music together over the Internet as if in the same room') - should_not have_selector('.feed-entry.music-session-history-entry') + should have_selector('.feed-entry.music-session-history-entry') # try to mess with the music session history by removing all user histories (which makes it a bit invalid) # but we really don't want the front page to ever crash if we can help it diff --git a/web/spec/requests/invitations_api_spec.rb b/web/spec/requests/invitations_api_spec.rb index 68d751341..47475f373 100644 --- a/web/spec/requests/invitations_api_spec.rb +++ b/web/spec/requests/invitations_api_spec.rb @@ -106,9 +106,7 @@ describe "Invitation API ", :type => :api do invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session.music_session) post '/api/invitations.json', {:music_session => music_session.id, :receiver => other_user.id}.to_json, "CONTENT_TYPE" => 'application/json' - last_response.status.should eql(409) - response = JSON.parse(last_response.body) - response["errors"]["resource"][0].should == "resource already exists" + last_response.status.should eql(201) end