Skip to content
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

Merged
merged 10 commits into from May 15, 2017
Merged

Feature conversations muting #3017

merged 10 commits into from May 15, 2017

Conversation

Gargron
Copy link
Member

@Gargron Gargron commented May 12, 2017

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

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
@Gargron Gargron force-pushed the feature-conversations-muting branch from c75cf69 to f3ae643 Compare May 12, 2017 18:54
.rubocop.yml Outdated
@@ -26,7 +26,7 @@ Metrics/BlockNesting:

Metrics/ClassLength:
CountComments: false
Max: 200
Max: 250
Copy link
Contributor

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
Copy link
Contributor

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",
Copy link
Contributor

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?

Copy link
Member Author

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

@@ -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)
Copy link
Contributor

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?

@@ -10,7 +10,7 @@
#

class Conversation < ApplicationRecord
validates :uri, uniqueness: true
validates :uri, uniqueness: true, unless: 'uri.nil?'
Copy link
Contributor

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?

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?
Copy link
Contributor

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
Copy link
Contributor

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?
Copy link
Contributor

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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spec coverage?

@nightpool
Copy link
Member

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.

@Gargron
Copy link
Member Author

Gargron commented May 13, 2017

@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?

@nightpool
Copy link
Member

nightpool commented May 13, 2017 via email

@Gargron
Copy link
Member Author

Gargron commented May 13, 2017

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.

@Gargron
Copy link
Member Author

Gargron commented May 14, 2017

@mjankowski All fixed, I think

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants