mirror of
https://github.com/discourse/discourse.git
synced 2025-04-01 03:59:24 +08:00
the private message stream is different to normal streams, improving the ui a bit and collapsing conversations
This commit is contained in:
parent
b9c4bf9870
commit
e91ed83586
@ -2,14 +2,22 @@ class UserActionsController < ApplicationController
|
|||||||
def index
|
def index
|
||||||
requires_parameters(:user_id)
|
requires_parameters(:user_id)
|
||||||
per_chunk = 60
|
per_chunk = 60
|
||||||
render json: UserAction.stream(
|
|
||||||
|
opts = {
|
||||||
user_id: params[:user_id].to_i,
|
user_id: params[:user_id].to_i,
|
||||||
offset: params[:offset],
|
offset: params[:offset],
|
||||||
limit: per_chunk,
|
limit: per_chunk,
|
||||||
action_types: (params[:filter] || "").split(","),
|
action_types: (params[:filter] || "").split(",").map(&:to_i),
|
||||||
guardian: guardian,
|
guardian: guardian,
|
||||||
ignore_private_messages: params[:filter] ? false : true
|
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
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -131,6 +131,56 @@ LEFT JOIN categories c on c.id = t.category_id
|
|||||||
data
|
data
|
||||||
end
|
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)
|
def self.log_action!(hash)
|
||||||
require_parameters(hash, :action_type, :user_id, :acting_user_id, :target_topic_id, :target_post_id)
|
require_parameters(hash, :action_type, :user_id, :acting_user_id, :target_topic_id, :target_post_id)
|
||||||
transaction(requires_new: true) do
|
transaction(requires_new: true) do
|
||||||
|
@ -37,7 +37,7 @@ Discourse::Application.configure do
|
|||||||
config.handlebars.precompile = true
|
config.handlebars.precompile = true
|
||||||
|
|
||||||
# this setting enable rack_cache so it caches various requests in redis
|
# 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
|
# allows users to use mini profiler
|
||||||
config.enable_mini_profiler = false
|
config.enable_mini_profiler = false
|
||||||
|
@ -6,6 +6,10 @@ class PostCreator
|
|||||||
|
|
||||||
attr_reader :errors, :opts
|
attr_reader :errors, :opts
|
||||||
|
|
||||||
|
def self.create(user,opts)
|
||||||
|
self.new(user,opts).create
|
||||||
|
end
|
||||||
|
|
||||||
# Acceptable options:
|
# Acceptable options:
|
||||||
#
|
#
|
||||||
# raw - raw text of post
|
# raw - raw text of post
|
||||||
@ -14,6 +18,7 @@ class PostCreator
|
|||||||
# acting_user - The user performing the action might be different than the user
|
# 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
|
# who is the post "author." For example when copying posts to a new
|
||||||
# topic.
|
# topic.
|
||||||
|
# created_at - Post creation time (optional)
|
||||||
#
|
#
|
||||||
# When replying to a topic:
|
# When replying to a topic:
|
||||||
# topic_id - topic we're replying to
|
# topic_id - topic we're replying to
|
||||||
|
@ -206,4 +206,55 @@ describe UserAction do
|
|||||||
@user.user_actions.where(action_type: UserAction::BOOKMARK).first.should be_nil
|
@user.user_actions.where(action_type: UserAction::BOOKMARK).first.should be_nil
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user