the private message stream is different to normal streams, improving the ui a bit and collapsing conversations

This commit is contained in:
Sam 2013-05-20 16:44:06 +10:00
parent b9c4bf9870
commit e91ed83586
5 changed files with 118 additions and 4 deletions

View File

@ -2,14 +2,22 @@ class UserActionsController < ApplicationController
def index
requires_parameters(:user_id)
per_chunk = 60
render json: UserAction.stream(
opts = {
user_id: params[:user_id].to_i,
offset: params[:offset],
limit: per_chunk,
action_types: (params[:filter] || "").split(","),
action_types: (params[:filter] || "").split(",").map(&:to_i),
guardian: guardian,
ignore_private_messages: params[:filter] ? false : true
)
}
if opts[:action_types] == [UserAction::GOT_PRIVATE_MESSAGE] ||
opts[:action_types] == [UserAction::NEW_PRIVATE_MESSAGE]
render json: UserAction.private_message_stream(opts[:action_types][0], opts)
else
render json: UserAction.stream(opts)
end
end
def show

View File

@ -131,6 +131,56 @@ LEFT JOIN categories c on c.id = t.category_id
data
end
# slightly different to standard stream, it collapses replies
def self.private_message_stream(action_type, opts)
user_id = opts[:user_id]
return [] unless opts[:guardian].can_see_private_messages?(user_id)
builder = SqlBuilder.new("
SELECT
t.title, :action_type action_type, p.created_at, t.id topic_id,
:user_id AS target_user_id, au.name AS target_name, au.username AS target_username,
coalesce(p.post_number, 1) post_number,
p.reply_to_post_number,
pu.email ,pu.username, pu.name, pu.id user_id,
pu.email acting_email, pu.username acting_username, pu.name acting_name, pu.id acting_user_id,
p.cooked
FROM topics t
JOIN posts p ON p.topic_id = t.id and p.post_number = t.highest_post_number
JOIN users pu ON pu.id = p.user_id
JOIN users au ON au.id = :user_id
WHERE archetype = 'private_message' and EXISTS (
select 1 from user_actions a where a.user_id = :user_id and a.target_topic_id = t.id and action_type = :action_type)
ORDER BY p.created_at desc
/*offset*/
/*limit*/
")
builder.offset((opts[:offset] || 0).to_i)
builder.limit((opts[:limit] || 60).to_i)
data = builder.exec(user_id: user_id, action_type: action_type).to_a
data.each do |row|
row["action_type"] = row["action_type"].to_i
row["created_at"] = DateTime.parse(row["created_at"])
# we should probably cache the excerpts in the db at some point
row["excerpt"] = PrettyText.excerpt(row["cooked"],300) if row["cooked"]
row["cooked"] = nil
row["avatar_template"] = User.avatar_template(row["email"])
row["acting_avatar_template"] = User.avatar_template(row["acting_email"])
row.delete("email")
row.delete("acting_email")
row["slug"] = Slug.for(row["title"])
end
data
end
def self.log_action!(hash)
require_parameters(hash, :action_type, :user_id, :acting_user_id, :target_topic_id, :target_post_id)
transaction(requires_new: true) do

View File

@ -37,7 +37,7 @@ Discourse::Application.configure do
config.handlebars.precompile = true
# this setting enable rack_cache so it caches various requests in redis
config.enable_rack_cache = true
# config.enable_rack_cache = true
# allows users to use mini profiler
config.enable_mini_profiler = false

View File

@ -6,6 +6,10 @@ class PostCreator
attr_reader :errors, :opts
def self.create(user,opts)
self.new(user,opts).create
end
# Acceptable options:
#
# raw - raw text of post
@ -14,6 +18,7 @@ class PostCreator
# acting_user - The user performing the action might be different than the user
# who is the post "author." For example when copying posts to a new
# topic.
# created_at - Post creation time (optional)
#
# When replying to a topic:
# topic_id - topic we're replying to

View File

@ -206,4 +206,55 @@ describe UserAction do
@user.user_actions.where(action_type: UserAction::BOOKMARK).first.should be_nil
end
end
describe 'private messages' do
let(:user) do
Fabricate(:user)
end
let(:target_user) do
Fabricate(:user)
end
let(:private_message) do
PostCreator.create( user,
raw: 'this is a private message',
title: 'this is the pm title',
target_usernames: target_user.username,
archetype: Archetype::private_message
)
end
let!(:response) do
PostCreator.create(user, raw: 'oops I forgot to mention this', topic_id: private_message.topic_id)
end
let!(:private_message2) do
PostCreator.create( target_user,
raw: 'this is a private message',
title: 'this is the pm title',
target_usernames: user.username,
archetype: Archetype::private_message
)
end
it 'should collapse the inbox correctly' do
stream = UserAction.private_message_stream(UserAction::GOT_PRIVATE_MESSAGE, user_id: target_user.id, guardian: Guardian.new(target_user))
# inbox should collapse this initial and reply message into one item
stream.count.should == 1
# outbox should also collapse
stream = UserAction.private_message_stream(UserAction::NEW_PRIVATE_MESSAGE, user_id: user.id, guardian: Guardian.new(user))
stream.count.should == 1
# anon should see nothing
stream = UserAction.private_message_stream(UserAction::NEW_PRIVATE_MESSAGE, user_id: user.id, guardian: Guardian.new(nil))
stream.count.should == 0
end
end
end