diff --git a/app/models/conversation.rb b/app/models/conversation.rb index f337ef4a7e0..ff5e793076d 100644 --- a/app/models/conversation.rb +++ b/app/models/conversation.rb @@ -29,6 +29,11 @@ class Conversation < ActiveRecord::Base validates_length_of :subject, :maximum => maximum_string_length, :allow_nil => true + attr_accessor :latest_messages_from_stream_item + self.send_to_stream_update_block = lambda { |conversation| + User.where(:id => conversation.conversation_message_participants.distinct.except(:order).pluck(:user_id)).to_a + } + def participants(reload = false) if !@participants || reload Conversation.preload_participants([self]) diff --git a/app/models/conversation_participant.rb b/app/models/conversation_participant.rb index 4cdb3098e16..7a3b1e413c6 100644 --- a/app/models/conversation_participant.rb +++ b/app/models/conversation_participant.rb @@ -348,6 +348,7 @@ class ConversationParticipant < ActiveRecord::Base update_cached_data save end + self.conversation.queue_update_stream_items end def update_attributes(hash) diff --git a/app/models/stream_item.rb b/app/models/stream_item.rb index 8a1b1eb9f63..47e3715b541 100644 --- a/app/models/stream_item.rb +++ b/app/models/stream_item.rb @@ -61,6 +61,8 @@ class StreamItem < ActiveRecord::Base res.total_root_discussion_entries = data.delete(:total_root_discussion_entries) when 'Submission' data['body'] = nil + when 'Conversation' + res.latest_messages_from_stream_item = data.delete(:latest_messages) end if data.has_key?('users') users = data.delete('users') @@ -125,6 +127,18 @@ class StreamItem < ActiveRecord::Base if res['participant_count'] <= 8 res['participants'] = conversation.participants.map{ |u| prepare_user(u) } end + + messages = conversation.conversation_messages.human.order(:created_at => :desc).limit(LATEST_ENTRY_LIMIT).to_a.reverse + res['latest_messages'] = messages.map do |message| + { + "id" => message.id, + "created_at" => message.created_at, + "author_id" => message.author_id, + "message" => message.body.present? ? message.body[0, 4.kilobytes] : "", + "participating_user_ids" => message.conversation_message_participants.active.pluck(:user_id).sort + } + end + res end @@ -152,7 +166,7 @@ class StreamItem < ActiveRecord::Base item.try(:destroy) end - ROOT_DISCUSSION_ENTRY_LIMIT = 3 + LATEST_ENTRY_LIMIT = 3 def generate_data(object) self.context ||= object.try(:context) unless object.is_a?(Message) @@ -161,7 +175,7 @@ class StreamItem < ActiveRecord::Base res = object.attributes res['user_ids_that_can_see_responses'] = object.user_ids_who_have_posted_and_admins if object.require_initial_post? res['total_root_discussion_entries'] = object.root_discussion_entries.active.count - res[:root_discussion_entries] = object.root_discussion_entries.active.reverse[0,ROOT_DISCUSSION_ENTRY_LIMIT].reverse.map do |entry| + res[:root_discussion_entries] = object.root_discussion_entries.active.order(:created_at => :desc).limit(LATEST_ENTRY_LIMIT).to_a.reverse.map do |entry| hash = entry.attributes hash['user_short_name'] = entry.user.short_name if entry.user hash['message'] = hash['message'][0, 4.kilobytes] if hash['message'].present? @@ -420,6 +434,10 @@ class StreamItem < ActiveRecord::Base res.readonly! end end + when Conversation + if res.latest_messages_from_stream_item + res.latest_messages_from_stream_item.select!{|m| m["participating_user_ids"].include?(viewing_user_id)} + end end res diff --git a/lib/api/v1/stream_item.rb b/lib/api/v1/stream_item.rb index 94fa49c5b96..7db6d43ff9e 100644 --- a/lib/api/v1/stream_item.rb +++ b/lib/api/v1/stream_item.rb @@ -58,7 +58,7 @@ module Api::V1::StreamItem hash['total_root_discussion_entries'] = data.total_root_discussion_entries hash['require_initial_post'] = data.require_initial_post hash['user_has_posted'] = data.respond_to?(:user_has_posted) ? data.user_has_posted : nil - hash['root_discussion_entries'] = (data.root_discussion_entries || [])[0,StreamItem::ROOT_DISCUSSION_ENTRY_LIMIT].map do |entry| + hash['root_discussion_entries'] = (data.root_discussion_entries || [])[0,StreamItem::LATEST_ENTRY_LIMIT].map do |entry| { 'user' => { 'user_id' => entry.user_id, @@ -75,6 +75,7 @@ module Api::V1::StreamItem hash['private'] = data.private hash['participant_count'] = data.participant_count hash['html_url'] = conversation_url(stream_item.asset_id) + hash['latest_messages'] = data.latest_messages_from_stream_item if data.latest_messages_from_stream_item.present? when 'Message' hash['message_id'] = stream_item.asset_id # this type encompasses a huge number of different types of messages, diff --git a/spec/apis/v1/stream_items_api_spec.rb b/spec/apis/v1/stream_items_api_spec.rb index 359974da18e..b9328baacb7 100644 --- a/spec/apis/v1/stream_items_api_spec.rb +++ b/spec/apis/v1/stream_items_api_spec.rb @@ -295,8 +295,8 @@ describe UsersController, type: :request do it "should format Conversation" do @sender = User.create!(:name => 'sender') @conversation = Conversation.initiate([@user, @sender], false) - @conversation.add_message(@sender, "hello") - @message = @conversation.conversation_messages.last + @message = @conversation.add_message(@sender, "hello") + json = api_call(:get, "/api/v1/users/activity_stream.json", { :controller => "users", :action => "activity_stream", :format => 'json' }).first expect(json).to eq({ @@ -308,12 +308,20 @@ describe UsersController, type: :request do 'updated_at' => StreamItem.last.updated_at.as_json, 'title' => nil, 'message' => nil, - 'private' => false, 'html_url' => "http://www.example.com/conversations/#{@conversation.id}", - - 'participant_count' => 2 + 'participant_count' => 2, + 'latest_messages' => [ + {'id' => @message.id, "created_at" => @message.created_at.as_json, + "author_id" => @sender.id, "message" => "hello", + "participating_user_ids" => [@user.id, @sender.id]}] }) + + @conversation.conversation_participants.where(:user_id => @user).first.remove_messages(@message) + # should update the latest messages and not show them the one they can't see anymore + json = api_call(:get, "/api/v1/users/activity_stream.json", + { :controller => "users", :action => "activity_stream", :format => 'json' }).first + expect(json["latest_messages"]).to be_blank end it "should format Message" do