FEATURE: Hide user status when user is hiding public profile and presence (#24300)

Users can hide their public profile and presence information by checking 
“Hide my public profile and presence features” on the 
`u/{username}/preferences/interface` page. In that case, we also don't 
want to return user status from the server.

This work has been started in https://github.com/discourse/discourse/pull/23946. 
The current PR fixes all the remaining places in Core.

Note that the actual fix is quite simple – https://github.com/discourse/discourse/pull/24300/commits/a5802f484db92ff3f7e535ed25e1591d1f19b03b. 
But we had a fair amount of duplication in the code responsible for 
the user status serialization, so I had to dry that up first. The refactoring 
as well as adding some additional tests is the main part of this PR.
This commit is contained in:
Andrei Prigorshnev
2024-02-26 17:40:48 +04:00
committed by GitHub
parent 41790f7739
commit b3a1199493
34 changed files with 480 additions and 172 deletions
+2
View File
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class BasicUserSerializer < ApplicationSerializer
include UserStatusMixin
attributes :id, :username, :name, :avatar_template
def name
@@ -1,13 +0,0 @@
# frozen_string_literal: true
class BasicUserWithStatusSerializer < BasicUserSerializer
attributes :status
def include_status?
SiteSetting.enable_user_status && user.has_status?
end
def status
UserStatusSerializer.new(user.user_status, root: false)
end
end
@@ -0,0 +1,16 @@
# frozen_string_literal: true
module UserStatusMixin
def self.included(klass)
klass.attributes :status
end
def include_status?
@options[:include_status] && SiteSetting.enable_user_status &&
!object.user_option&.hide_profile_and_presence && object.has_status?
end
def status
UserStatusSerializer.new(object.user_status, root: false).as_json
end
end
+6 -9
View File
@@ -3,6 +3,7 @@
class CurrentUserSerializer < BasicUserSerializer
include UserTagNotificationsMixin
include UserSidebarMixin
include UserStatusMixin
attributes :name,
:unread_notifications,
@@ -65,7 +66,6 @@ class CurrentUserSerializer < BasicUserSerializer
:can_review,
:draft_count,
:pending_posts_count,
:status,
:grouped_unread_notifications,
:display_sidebar_tags,
:sidebar_tags,
@@ -82,6 +82,11 @@ class CurrentUserSerializer < BasicUserSerializer
has_one :user_option, embed: :object, serializer: CurrentUserOptionSerializer
def initialize(object, options = {})
super
options[:include_status] = true
end
def sidebar_sections
SidebarSection
.public_sections
@@ -304,14 +309,6 @@ class CurrentUserSerializer < BasicUserSerializer
Draft.has_topic_draft(object)
end
def include_status?
SiteSetting.enable_user_status && object.has_status?
end
def status
UserStatusSerializer.new(object.user_status, root: false)
end
def unseen_reviewable_count
Reviewable.unseen_reviewable_count(object)
end
+2
View File
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class FoundUserSerializer < ApplicationSerializer
include UserStatusMixin
attributes :id, :username, :name, :avatar_template
def include_name?
@@ -1,13 +1,10 @@
# frozen_string_literal: true
class FoundUserWithStatusSerializer < FoundUserSerializer
attributes :status
include UserStatusMixin
def include_status?
SiteSetting.enable_user_status && object.has_status?
end
def status
UserStatusSerializer.new(object.user_status, root: false)
def initialize(object, options = {})
super
options[:include_status] = true
end
end
+7 -9
View File
@@ -2,8 +2,14 @@
class GroupUserSerializer < BasicUserSerializer
include UserPrimaryGroupMixin
include UserStatusMixin
attributes :name, :title, :last_posted_at, :last_seen_at, :added_at, :timezone, :status
attributes :name, :title, :last_posted_at, :last_seen_at, :added_at, :timezone
def initialize(object, options = {})
super
options[:include_status] = true
end
def timezone
user.user_option.timezone
@@ -12,12 +18,4 @@ class GroupUserSerializer < BasicUserSerializer
def include_added_at?
object.respond_to? :added_at
end
def include_status?
SiteSetting.enable_user_status && user.has_status?
end
def status
UserStatusSerializer.new(user.user_status, root: false)
end
end
@@ -3,7 +3,12 @@
class GroupUserWithCustomFieldsSerializer < UserWithCustomFieldsSerializer
include UserPrimaryGroupMixin
attributes :name, :title, :last_posted_at, :last_seen_at, :added_at, :timezone, :status
attributes :name, :title, :last_posted_at, :last_seen_at, :added_at, :timezone
def initialize(object, options = {})
super
options[:include_status] = true
end
def timezone
user.user_option.timezone
@@ -12,12 +17,4 @@ class GroupUserWithCustomFieldsSerializer < UserWithCustomFieldsSerializer
def include_added_at?
object.respond_to? :added_at
end
def include_status?
SiteSetting.enable_user_status && user.has_status?
end
def status
UserStatusSerializer.new(user.user_status, root: false)
end
end
+2 -2
View File
@@ -581,12 +581,12 @@ class PostSerializer < BasicPostSerializer
if @topic_view && (mentioned_users = @topic_view.mentioned_users[object.id])
mentioned_users
else
query = User
query = User.includes(:user_option)
query = query.includes(:user_status) if SiteSetting.enable_user_status
query = query.where(username: object.mentions)
end
users.map { |user| BasicUserWithStatusSerializer.new(user, root: false) }
users.map { |user| BasicUserSerializer.new(user, root: false, include_status: true).as_json }
end
def include_mentioned_users?
+8 -10
View File
@@ -1,8 +1,15 @@
# frozen_string_literal: true
class UserCardSerializer < BasicUserSerializer
include UserStatusMixin
attr_accessor :topic_post_count
def initialize(object, options = {})
super
options[:include_status] = true
end
def self.staff_attributes(*attrs)
attributes(*attrs)
attrs.each do |attr|
@@ -70,8 +77,7 @@ class UserCardSerializer < BasicUserSerializer
:flair_color,
:featured_topic,
:timezone,
:pending_posts_count,
:status
:pending_posts_count
untrusted_attributes :bio_excerpt, :website, :website_name, :location, :card_background_upload_url
@@ -223,14 +229,6 @@ class UserCardSerializer < BasicUserSerializer
object.card_background_upload&.url
end
def include_status?
SiteSetting.enable_user_status && user.has_status?
end
def status
UserStatusSerializer.new(user.user_status, root: false)
end
private
def custom_field_keys
@@ -2,7 +2,8 @@
# A basic user serializer, with custom fields
class UserWithCustomFieldsSerializer < BasicUserSerializer
attributes :custom_fields
include UserStatusMixin
attribute :custom_fields
def custom_fields
fields = custom_field_keys