New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature conversations muting #3017
Conversation
Only uses ref attribute (not href) because href would be the alternate link that's always included also. Creates new conversation for every non-reply status. Carries over conversation for every reply. Keeps remote URIs verbatim, generates local URIs on the fly like the rest of them.
…ation (including replies, favourites, reblogs) from being created. API endpoints /api/v1/statuses/:id/mute and /api/v1/statuses/:id/unmute Currently no way to tell when a status/conversation is muted, so the web UI only has a "disable notifications" button, doesn't work as a toggle
For now always false on contained reblogs, since it's only relevant for statuses returned from the notifications endpoint, which are not nested Remove "Disable notifications" from detailed status view, since it's only relevant in the notifications column
c75cf69
to
f3ae643
Compare
.rubocop.yml
Outdated
@@ -26,7 +26,7 @@ Metrics/BlockNesting: | |||
|
|||
Metrics/ClassLength: | |||
CountComments: false | |||
Max: 200 | |||
Max: 250 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change should probably be in a separate PR ... but also, I think it's fine to leave this at 200 and let CC fail on it. It's a good hint that something needs a refactor, even if we choose to ignore for now.
@@ -105,6 +105,22 @@ def unfavourite | |||
render :show | |||
end | |||
|
|||
def mute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both of these actions could probably use a @conversation
, maybe set in before action?
@@ -142,6 +142,7 @@ | |||
"status.load_more": "حمّل المزيد", | |||
"status.media_hidden": "الصورة مستترة", | |||
"status.mention": "أذكُر @{name}", | |||
"status.mute_conversation": "Disable notifications", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will all these locales/*.json
(other than en
) not just fallback to en
if they don't exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Autogenerated by yarn run manage:translations
app/models/account.rb
Outdated
@@ -130,6 +130,10 @@ def mute!(other_account) | |||
mute_relationships.find_or_create_by!(target_account: other_account) | |||
end | |||
|
|||
def mute_conversation!(conversation) | |||
ConversationMute.find_or_create_by!(account: self, conversation: conversation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is inside Account
, could this just be conversation_mutes.where(conversation: conversation).first_or_create!
(or similar) to avoid the use of self
here?
app/models/conversation.rb
Outdated
@@ -10,7 +10,7 @@ | |||
# | |||
|
|||
class Conversation < ApplicationRecord | |||
validates :uri, uniqueness: true | |||
validates :uri, uniqueness: true, unless: 'uri.nil?' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about if: :uri?
to avoid eval'ing a string?
app/services/notify_service.rb
Outdated
blocked ||= send("blocked_#{@notification.type}?") # Type-dependent filters | ||
blocked | ||
end | ||
|
||
def conversation_muted? | ||
if @notification.target_status | ||
!@notification.target_status.conversation_id.nil? && ConversationMute.where(account: @recipient, conversation_id: @notification.target_status.conversation_id).exists? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might put this into something like @recipient.muting_conversation?(@notification.target_status.conversation)
, and have it handle nils itself...
@@ -0,0 +1,4 @@ | |||
require 'rails_helper' | |||
|
|||
RSpec.describe ConversationMute, type: :model do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either put something in here, or delete the file.
@@ -43,10 +43,19 @@ def blocked? | |||
blocked ||= (@notification.from_account.silenced? && !@recipient.following?(@notification.from_account)) # Hellban | |||
blocked ||= (@recipient.user.settings.interactions['must_be_follower'] && !@notification.from_account.following?(@recipient)) # Options | |||
blocked ||= (@recipient.user.settings.interactions['must_be_following'] && !@recipient.following?(@notification.from_account)) # Options | |||
blocked ||= conversation_muted? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spec coverage?
@@ -181,6 +181,10 @@ def reblogs_map(status_ids, account_id) | |||
select('reblog_of_id').where(reblog_of_id: status_ids).where(account_id: account_id).map { |s| [s.reblog_of_id, true] }.to_h | |||
end | |||
|
|||
def mutes_map(conversation_ids, account_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spec coverage?
To reiterate my comments from #2864: Currently, muting fails silently for statuses created before whenever this code is released, with no indication at all that this is the case. This is incredibly hostile to users, and will basically make it look like we're shipping a broken feature. An asynchronous one-time sidekiq backfill that populated conversation_ids would solve this problem, although we would have to figure out how it gets run. Failing that, adding a "populate_conversation_id_if_not_present" call to mute and unmute would probably be the second best choice. There's some smaller UI/UX polish that's probably needed here as well. If I have a chain of self-replies A -> B -> C, and I click "mute notifications" on C, I wouldn't expect that to mute notifications for A and B, which is what it does. I think changing it to "Mute conversation" or "Mute notifications for conversation" would fix this. |
@nightpool It's actually impossible to backfill this retroactively. I suggest that it shall fail with a 422 for statuses that don't have a conversation, how about that? |
Why would it be impossible to backfill for local statuses?
Even if it was impossible to backfill, that technical detail shouldn't
compromise the user experience—we could fall back to blacklisting on "in
reply to" or something similar
…On Sat, May 13, 2017 at 3:52 PM Eugen Rochko ***@***.***> wrote:
@nightpool <https://github.com/nightpool> It's actually impossible to
backfill this retroactively. I suggest that it shall fail with a 422 for
statuses that don't have a conversation, how about that?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3017 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAORV_xFPUUgY4xB3IPCy8_tDi0J6uILks5r5gn9gaJpZM4NZg-H>
.
|
I'm sorry but I will not do backfilling. First of all, it's not worth it, most conversations end within one day. Secondly, I will not be combing through 6M records just on mastodon.social alone to fill in this data. Microblogging is fast paced and ephermal, these old records will become almost completely irrelevant in just a few days. |
@mjankowski All fixed, I think |
Fix #500
Fix #59
Adds "muted" boolean property to status JSON.
POST /api/v1/statuses/:id/mute
POST /api/v1/statuses/:id/unmute
In the web UI: Displays "Disable notifications" vs "Re-enable notifications" for statuses in the notifications column.
Depends on #3016