Class: UserCommScreener
- Inherits:
-
Object
- Object
- UserCommScreener
- Defined in:
- lib/user_comm_screener.rb
Overview
There are various ways within Discourse that a user can prevent other users communicating with them. The purpose of this class is to find which of the target users are ignoring, muting, or preventing private messages from the acting user, so we can take alternative action (such as raising an error or showing a helpful message) if so.
Users may Mute another user (the actor), which will:
* Prevent PMs from the actor
* Prevent notifications from the actor
Users may Ignore another user (the actor), which will:
* Do everything that Mute does as well as suppressing content made by
the actor (such as posts) from the UI
Users may also either:
a) disallow PMs from being sent to them or
b) disallow PMs except from a certain allowlist of users
A user may have this preference but have no Muted or Ignored users, which necessitates the difference between methods in this class.
An important note is that **all of these settings do not apply when the actor is a staff member**. So admins and moderators can PM and notify anyone they please.
The secondary usage of this class is to determine which users the actor themselves are muting, ignoring, or preventing private messages from. This is useful when wanting to alert the actor to these users in the UI in various ways, or prevent the actor from communicating with users they prefer not to talk with.
Instance Attribute Summary collapse
-
#acting_user ⇒ Object
readonly
Returns the value of attribute acting_user.
-
#preferences ⇒ Object
readonly
Returns the value of attribute preferences.
Instance Method Summary collapse
- #actor_allowing_communication ⇒ Object
- #actor_disallowing_all_pms? ⇒ Boolean
- #actor_disallowing_any_pms?(user_ids) ⇒ Boolean
- #actor_disallowing_pms?(user_id) ⇒ Boolean
-
#actor_ignoring?(user_id) ⇒ Boolean
The actor methods below are more fine-grained than the user ones, since we may want to display more detailed messages to the actor about their preferences than we do when we are informing the actor that they cannot communicate with certain users.
- #actor_muting?(user_id) ⇒ Boolean
- #actor_preventing_communication ⇒ Object
-
#allowing_actor_communication ⇒ Object
Users who have preferences are the only ones initially loaded by the query, so implicitly the leftover users have no preferences that mute, ignore, or disallow PMs from any other user.
-
#disallowing_pms_from_actor?(user_id) ⇒ Boolean
Whether the user is disallowing PMs from the actor specifically or in general, meaning the actor cannot send PMs to this target user.
-
#ignoring_or_muting_actor?(user_id) ⇒ Boolean
Whether the user is ignoring or muting the actor, meaning the actor cannot PM or send notifications to this target user.
-
#initialize(acting_user: nil, acting_user_id: nil, target_user_ids:) ⇒ UserCommScreener
constructor
A new instance of UserCommScreener.
-
#preventing_actor_communication ⇒ Object
Any users who are either ignoring, muting, or disallowing PMs from the actor.
Constructor Details
#initialize(acting_user: nil, acting_user_id: nil, target_user_ids:) ⇒ UserCommScreener
Returns a new instance of UserCommScreener.
104 105 106 107 108 109 110 |
# File 'lib/user_comm_screener.rb', line 104 def initialize(acting_user: nil, acting_user_id: nil, target_user_ids:) raise ArgumentError if acting_user.blank? && acting_user_id.blank? @acting_user = acting_user.present? ? acting_user : User.find(acting_user_id) target_user_ids = Array.wrap(target_user_ids) - [@acting_user.id] @target_users = User.where(id: target_user_ids).pluck(:id, :username).to_h @preferences = load_preference_map end |
Instance Attribute Details
#acting_user ⇒ Object (readonly)
Returns the value of attribute acting_user.
35 36 37 |
# File 'lib/user_comm_screener.rb', line 35 def acting_user @acting_user end |
#preferences ⇒ Object (readonly)
Returns the value of attribute preferences.
35 36 37 |
# File 'lib/user_comm_screener.rb', line 35 def preferences @preferences end |
Instance Method Details
#actor_allowing_communication ⇒ Object
146 147 148 |
# File 'lib/user_comm_screener.rb', line 146 def actor_allowing_communication @target_users.keys - actor_preventing_communication end |
#actor_disallowing_all_pms? ⇒ Boolean
187 188 189 |
# File 'lib/user_comm_screener.rb', line 187 def actor_disallowing_all_pms? !acting_user.user_option. end |
#actor_disallowing_any_pms?(user_ids) ⇒ Boolean
183 184 185 |
# File 'lib/user_comm_screener.rb', line 183 def actor_disallowing_any_pms?(user_ids) user_ids.any? { |user_id| actor_disallowing_pms?(user_id) } end |
#actor_disallowing_pms?(user_id) ⇒ Boolean
176 177 178 179 180 181 |
# File 'lib/user_comm_screener.rb', line 176 def actor_disallowing_pms?(user_id) validate_user_id!(user_id) return true if actor_disallowing_all_pms? return false if !acting_user.user_option.enable_allowed_pm_users actor_preferences[:disallowed_pms_from].include?(user_id) end |
#actor_ignoring?(user_id) ⇒ Boolean
The actor methods below are more fine-grained than the user ones, since we may want to display more detailed messages to the actor about their preferences than we do when we are informing the actor that they cannot communicate with certain users.
In this spirit, actor_disallowing_pms? is intentionally different from disallowing_pms_from_actor? above.
166 167 168 169 |
# File 'lib/user_comm_screener.rb', line 166 def actor_ignoring?(user_id) validate_user_id!(user_id) actor_preferences[:ignoring].include?(user_id) end |
#actor_muting?(user_id) ⇒ Boolean
171 172 173 174 |
# File 'lib/user_comm_screener.rb', line 171 def actor_muting?(user_id) validate_user_id!(user_id) actor_preferences[:muting].include?(user_id) end |
#actor_preventing_communication ⇒ Object
150 151 152 153 154 155 |
# File 'lib/user_comm_screener.rb', line 150 def actor_preventing_communication ( actor_preferences[:ignoring] + actor_preferences[:muting] + actor_preferences[:disallowed_pms_from] ).uniq end |
#allowing_actor_communication ⇒ Object
Users who have preferences are the only ones initially loaded by the query, so implicitly the leftover users have no preferences that mute, ignore, or disallow PMs from any other user.
116 117 118 |
# File 'lib/user_comm_screener.rb', line 116 def allowing_actor_communication (preferences.allowing_actor_communication.map(&:user_id) + users_with_no_preference).uniq end |
#disallowing_pms_from_actor?(user_id) ⇒ Boolean
Whether the user is disallowing PMs from the actor specifically or in general, meaning the actor cannot send PMs to this target user. Ignoring or muting implicitly disallows PMs, so we need to take into account those preferences here too.
141 142 143 144 |
# File 'lib/user_comm_screener.rb', line 141 def disallowing_pms_from_actor?(user_id) validate_user_id!(user_id) preferences.disallowing_pms?(user_id) || ignoring_or_muting_actor?(user_id) end |
#ignoring_or_muting_actor?(user_id) ⇒ Boolean
Whether the user is ignoring or muting the actor, meaning the actor cannot PM or send notifications to this target user.
131 132 133 134 |
# File 'lib/user_comm_screener.rb', line 131 def ignoring_or_muting_actor?(user_id) validate_user_id!(user_id) preferences.ignoring_or_muting?(user_id) end |
#preventing_actor_communication ⇒ Object
Any users who are either ignoring, muting, or disallowing PMs from the actor. Ignoring and muting implicitly ignore PMs which is why they fall under this umbrella as well.
124 125 126 |
# File 'lib/user_comm_screener.rb', line 124 def preventing_actor_communication preferences.preventing_actor_communication.map(&:user_id) end |