mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FEATURE: Include a user's pending posts in the topic view
Also includes a refactor to TopicView's serializer which was not building our attributes using serializers properly.
This commit is contained in:
@@ -8,6 +8,8 @@ class NewPostResultSerializer < ApplicationSerializer
|
||||
:pending_count,
|
||||
:reason
|
||||
|
||||
has_one :pending_post, serializer: TopicPendingPostSerializer, root: false, embed: :objects
|
||||
|
||||
def post
|
||||
post_serializer = PostSerializer.new(object.post, scope: scope, root: false)
|
||||
post_serializer.draft_sequence = DraftSequence.current(scope.user, object.post.topic.draft_key)
|
||||
@@ -39,7 +41,7 @@ class NewPostResultSerializer < ApplicationSerializer
|
||||
end
|
||||
|
||||
def include_reason?
|
||||
reason.present?
|
||||
scope.is_staff? && reason.present?
|
||||
end
|
||||
|
||||
def action
|
||||
@@ -50,6 +52,14 @@ class NewPostResultSerializer < ApplicationSerializer
|
||||
object.pending_count
|
||||
end
|
||||
|
||||
def pending_post
|
||||
object.reviewable
|
||||
end
|
||||
|
||||
def include_pending_post?
|
||||
object.reviewable.present?
|
||||
end
|
||||
|
||||
def include_pending_count?
|
||||
pending_count.present?
|
||||
end
|
||||
|
12
app/serializers/topic_pending_post_serializer.rb
Normal file
12
app/serializers/topic_pending_post_serializer.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class TopicPendingPostSerializer < ApplicationSerializer
|
||||
attributes :id, :raw, :created_at
|
||||
|
||||
def raw
|
||||
object.payload['raw']
|
||||
end
|
||||
|
||||
def include_raw?
|
||||
object.payload && object.payload['raw'].present?
|
||||
end
|
||||
|
||||
end
|
140
app/serializers/topic_view_details_serializer.rb
Normal file
140
app/serializers/topic_view_details_serializer.rb
Normal file
@@ -0,0 +1,140 @@
|
||||
class TopicViewDetailsSerializer < ApplicationSerializer
|
||||
|
||||
def self.can_attributes
|
||||
[:can_move_posts,
|
||||
:can_edit,
|
||||
:can_delete,
|
||||
:can_recover,
|
||||
:can_remove_allowed_users,
|
||||
:can_invite_to,
|
||||
:can_invite_via_email,
|
||||
:can_create_post,
|
||||
:can_reply_as_new_topic,
|
||||
:can_flag_topic,
|
||||
:can_convert_topic]
|
||||
end
|
||||
|
||||
attributes(
|
||||
:notification_level,
|
||||
:notifications_reason_id,
|
||||
*can_attributes,
|
||||
:can_remove_self_id,
|
||||
:participants,
|
||||
:allowed_users
|
||||
)
|
||||
|
||||
has_one :created_by, serializer: BasicUserSerializer, embed: :objects
|
||||
has_one :last_poster, serializer: BasicUserSerializer, embed: :objects
|
||||
has_many :links, serializer: TopicLinkSerializer, embed: :objects
|
||||
has_many :participants, serializer: TopicPostCountSerializer, embed: :objects
|
||||
has_many :allowed_users, serializer: BasicUserSerializer, embed: :objects
|
||||
has_many :allowed_groups, serializer: BasicGroupSerializer, embed: :objects
|
||||
|
||||
def participants
|
||||
object.post_counts_by_user.reject { |p| object.participants[p].blank? }.map do |pc|
|
||||
{ user: object.participants[pc[0]], post_count: pc[1] }
|
||||
end
|
||||
end
|
||||
|
||||
def include_participants?
|
||||
object.post_counts_by_user.present?
|
||||
end
|
||||
|
||||
def include_links?
|
||||
object.links.present?
|
||||
end
|
||||
|
||||
def created_by
|
||||
object.topic.user
|
||||
end
|
||||
|
||||
def last_poster
|
||||
object.topic.last_poster
|
||||
end
|
||||
|
||||
def notification_level
|
||||
object.topic_user&.notification_level || TopicUser.notification_levels[:regular]
|
||||
end
|
||||
|
||||
def notifications_reason_id
|
||||
object.topic_user.notifications_reason_id
|
||||
end
|
||||
|
||||
def include_notifications_reason_id?
|
||||
object.topic_user.present?
|
||||
end
|
||||
|
||||
# confusingly this is an id, not a bool like all other `can` methods
|
||||
def can_remove_self_id
|
||||
scope.user.id
|
||||
end
|
||||
|
||||
def include_can_remove_self_id?
|
||||
scope.can_remove_allowed_users?(object.topic, scope.user)
|
||||
end
|
||||
|
||||
can_attributes.each do |ca|
|
||||
define_method(ca) { true }
|
||||
end
|
||||
|
||||
def include_can_move_posts?
|
||||
scope.can_move_posts?(object.topic)
|
||||
end
|
||||
|
||||
def include_can_edit?
|
||||
scope.can_edit?(object.topic)
|
||||
end
|
||||
|
||||
def include_can_delete?
|
||||
scope.can_delete?(object.topic)
|
||||
end
|
||||
|
||||
def include_can_recover?
|
||||
scope.can_recover_topic?(object.topic)
|
||||
end
|
||||
|
||||
def include_can_remove_allowed_users?
|
||||
scope.can_remove_allowed_users?(object.topic)
|
||||
end
|
||||
|
||||
def include_can_invite_to?
|
||||
scope.can_invite_to?(object.topic)
|
||||
end
|
||||
|
||||
def include_can_invite_via_email?
|
||||
scope.can_invite_via_email?(object.topic)
|
||||
end
|
||||
|
||||
def include_can_create_post?
|
||||
scope.can_create?(Post, object.topic)
|
||||
end
|
||||
|
||||
def include_can_reply_as_new_topic?
|
||||
scope.can_reply_as_new_topic?(object.topic)
|
||||
end
|
||||
|
||||
def include_can_flag_topic?
|
||||
object.actions_summary.any? { |a| a[:can_act] }
|
||||
end
|
||||
|
||||
def include_can_convert_topic?
|
||||
scope.can_convert_topic?(object.topic)
|
||||
end
|
||||
|
||||
def allowed_users
|
||||
object.topic.allowed_users.reject { |user| object.group_allowed_user_ids.include?(user.id) }
|
||||
end
|
||||
|
||||
def include_allowed_users?
|
||||
object.personal_message
|
||||
end
|
||||
|
||||
def allowed_groups
|
||||
object.topic.allowed_groups
|
||||
end
|
||||
|
||||
def include_allowed_groups?
|
||||
object.personal_message
|
||||
end
|
||||
|
||||
end
|
@@ -50,7 +50,6 @@ class TopicViewSerializer < ApplicationSerializer
|
||||
:posted,
|
||||
:unpinned,
|
||||
:pinned,
|
||||
:details,
|
||||
:current_post_number,
|
||||
:highest_post_number,
|
||||
:last_read_post_number,
|
||||
@@ -70,66 +69,14 @@ class TopicViewSerializer < ApplicationSerializer
|
||||
:participant_count,
|
||||
:destination_category_id,
|
||||
:pm_with_non_human_user,
|
||||
:pending_posts_count
|
||||
:queued_posts_count
|
||||
)
|
||||
|
||||
# TODO: Split off into proper object / serializer
|
||||
has_one :details, serializer: TopicViewDetailsSerializer, root: false, embed: :objects
|
||||
has_many :pending_posts, serializer: TopicPendingPostSerializer, root: false, embed: :objects
|
||||
|
||||
def details
|
||||
topic = object.topic
|
||||
|
||||
result = {
|
||||
created_by: BasicUserSerializer.new(topic.user, scope: scope, root: false),
|
||||
last_poster: BasicUserSerializer.new(topic.last_poster, scope: scope, root: false)
|
||||
}
|
||||
|
||||
if private_message?(topic)
|
||||
allowed_user_ids = Set.new
|
||||
|
||||
result[:allowed_groups] = object.topic.allowed_groups.map do |group|
|
||||
allowed_user_ids.merge(GroupUser.where(group: group).pluck(:user_id))
|
||||
BasicGroupSerializer.new(group, scope: scope, root: false)
|
||||
end
|
||||
|
||||
result[:allowed_users] = object.topic.allowed_users.select do |user|
|
||||
!allowed_user_ids.include?(user.id)
|
||||
end.map! do |user|
|
||||
BasicUserSerializer.new(user, scope: scope, root: false)
|
||||
end
|
||||
end
|
||||
|
||||
if object.post_counts_by_user.present?
|
||||
participants = object.post_counts_by_user.reject { |p| object.participants[p].blank? }.map do |pc|
|
||||
TopicPostCountSerializer.new({ user: object.participants[pc[0]], post_count: pc[1] }, scope: scope, root: false)
|
||||
end
|
||||
result[:participants] = participants if participants.length > 0
|
||||
end
|
||||
|
||||
if object.links.present?
|
||||
result[:links] = object.links.map do |user|
|
||||
TopicLinkSerializer.new(user, scope: scope, root: false)
|
||||
end
|
||||
end
|
||||
|
||||
if has_topic_user?
|
||||
result[:notification_level] = object.topic_user.notification_level
|
||||
result[:notifications_reason_id] = object.topic_user.notifications_reason_id
|
||||
else
|
||||
result[:notification_level] = TopicUser.notification_levels[:regular]
|
||||
end
|
||||
|
||||
result[:can_move_posts] = true if scope.can_move_posts?(object.topic)
|
||||
result[:can_edit] = true if scope.can_edit?(object.topic)
|
||||
result[:can_delete] = true if scope.can_delete?(object.topic)
|
||||
result[:can_recover] = true if scope.can_recover_topic?(object.topic)
|
||||
result[:can_remove_allowed_users] = true if scope.can_remove_allowed_users?(object.topic)
|
||||
result[:can_remove_self_id] = scope.user.id if scope.can_remove_allowed_users?(object.topic, scope.user)
|
||||
result[:can_invite_to] = true if scope.can_invite_to?(object.topic)
|
||||
result[:can_invite_via_email] = true if scope.can_invite_via_email?(object.topic)
|
||||
result[:can_create_post] = true if scope.can_create?(Post, object.topic)
|
||||
result[:can_reply_as_new_topic] = true if scope.can_reply_as_new_topic?(object.topic)
|
||||
result[:can_flag_topic] = actions_summary.any? { |a| a[:can_act] }
|
||||
result[:can_convert_topic] = true if scope.can_convert_topic?(object.topic)
|
||||
result
|
||||
object
|
||||
end
|
||||
|
||||
def message_bus_last_id
|
||||
@@ -141,7 +88,7 @@ class TopicViewSerializer < ApplicationSerializer
|
||||
end
|
||||
|
||||
def is_warning
|
||||
private_message?(object.topic) && object.topic.subtype == TopicSubtype.moderator_warning
|
||||
object.personal_message && object.topic.subtype == TopicSubtype.moderator_warning
|
||||
end
|
||||
|
||||
def include_is_warning?
|
||||
@@ -161,7 +108,7 @@ class TopicViewSerializer < ApplicationSerializer
|
||||
end
|
||||
|
||||
def include_message_archived?
|
||||
private_message?(object.topic)
|
||||
object.personal_message
|
||||
end
|
||||
|
||||
def message_archived
|
||||
@@ -214,16 +161,7 @@ class TopicViewSerializer < ApplicationSerializer
|
||||
end
|
||||
|
||||
def actions_summary
|
||||
result = []
|
||||
return [] unless post = object.posts&.first
|
||||
PostActionType.topic_flag_types.each do |sym, id|
|
||||
result << { id: id,
|
||||
count: 0,
|
||||
hidden: false,
|
||||
can_act: scope.post_can_act?(post, sym) }
|
||||
# TODO: other keys? :can_defer_flags, :acted, :can_undo
|
||||
end
|
||||
result
|
||||
object.actions_summary
|
||||
end
|
||||
|
||||
def has_deleted
|
||||
@@ -276,7 +214,7 @@ class TopicViewSerializer < ApplicationSerializer
|
||||
end
|
||||
|
||||
def include_pm_with_non_human_user?
|
||||
private_message?(object.topic)
|
||||
object.personal_message
|
||||
end
|
||||
|
||||
def pm_with_non_human_user
|
||||
@@ -297,18 +235,15 @@ class TopicViewSerializer < ApplicationSerializer
|
||||
object.topic.shared_draft.present?
|
||||
end
|
||||
|
||||
def pending_posts_count
|
||||
ReviewableQueuedPost.viewable_by(scope.user).where(topic_id: object.topic.id).pending.count
|
||||
def include_pending_posts?
|
||||
scope.authenticated? && object.queued_posts_enabled
|
||||
end
|
||||
|
||||
def include_pending_posts_count?
|
||||
scope.is_staff? && NewPostManager.queue_enabled?
|
||||
def queued_posts_count
|
||||
object.queued_posts_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def private_message?(topic)
|
||||
@private_message ||= topic.private_message?
|
||||
def include_queued_posts_count?
|
||||
scope.is_staff? && object.queued_posts_enabled
|
||||
end
|
||||
|
||||
end
|
||||
|
Reference in New Issue
Block a user