diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/settings/preferences/filters_controller.rb | 9 | ||||
-rw-r--r-- | app/controllers/settings/preferences_controller.rb | 3 | ||||
-rw-r--r-- | app/lib/feed_manager.rb | 39 | ||||
-rw-r--r-- | app/lib/user_settings_decorator.rb | 10 | ||||
-rw-r--r-- | app/models/user.rb | 1 | ||||
-rw-r--r-- | app/views/settings/preferences/filters/show.html.haml | 22 | ||||
-rw-r--r-- | app/views/settings/preferences/other/show.html.haml | 5 |
7 files changed, 75 insertions, 14 deletions
diff --git a/app/controllers/settings/preferences/filters_controller.rb b/app/controllers/settings/preferences/filters_controller.rb new file mode 100644 index 000000000..c58a698ef --- /dev/null +++ b/app/controllers/settings/preferences/filters_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Settings::Preferences::FiltersController < Settings::PreferencesController + private + + def after_update_redirect_path + settings_preferences_filters_path + end +end diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index eb7d2ca07..089d94a31 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -11,6 +11,7 @@ class Settings::PreferencesController < Settings::BaseController user_settings.update(user_settings_params.to_h) if current_user.update(user_params) + Rails.cache.delete("filter_settings:#{current_user.account_id}") I18n.locale = current_user.locale redirect_to after_update_redirect_path, notice: I18n.t('generic.changes_saved_msg') else @@ -73,6 +74,8 @@ class Settings::PreferencesController < Settings::BaseController :setting_boost_every, :setting_boost_jitter, :setting_boost_random, + :setting_filter_to_unknown, + :setting_filter_from_unknown, notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account trending_tag), interactions: %i(must_be_follower must_be_following must_be_following_dm) ) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 0ec341e3f..88fa592a7 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -2,6 +2,7 @@ require 'singleton' +# rubocop:disable Metrics/ClassLength class FeedManager include Singleton include Redisable @@ -23,7 +24,7 @@ class FeedManager def filter?(timeline_type, status, receiver_id) if [:home, :list].include?(timeline_type) - filter_from_home?(status, receiver_id, build_crutches(receiver_id, [status])) + filter_from_home?(status, receiver_id, build_crutches(receiver_id, [status]), filter_options_for(receiver_id)) elsif timeline_type == :mentions filter_from_mentions?(status, receiver_id) elsif timeline_type == :direct @@ -142,9 +143,10 @@ class FeedManager statuses = query.to_a crutches = build_crutches(into_account.id, statuses) + filter_options = filter_options_for(receiver_id) statuses.each do |status| - next if filter_from_home?(status, into_account.id, crutches) + next if filter_from_home?(status, into_account.id, crutches, filter_options) add_to_feed(:home, into_account.id, status, aggregate) end @@ -242,9 +244,9 @@ class FeedManager (context == :home ? Mute.where(account_id: receiver_id, target_account_id: account_ids).any? : Mute.where(account_id: receiver_id, target_account_id: account_ids, hide_notifications: true).any?) end - def filter_from_home?(status, receiver_id, crutches) + def filter_from_home?(status, receiver_id, crutches, filter_options) return false if receiver_id == status.account_id - return true unless status.published? && (status.conversation&.public? || crutches[:following][status.conversation&.account_id]) + return true unless status.published? && (status.conversation&.public? || status.conversation&.account_id == receiver_id || crutches[:following][status.conversation&.account_id]) return true if status.reply? && (status.in_reply_to_id.nil? || status.in_reply_to_account_id.nil?) return true if phrase_filtered?(status, receiver_id, :home) @@ -264,18 +266,25 @@ class FeedManager if status.reply? && !status.in_reply_to_account_id.nil? should_filter = receiver_id != status.in_reply_to_account_id + should_filter &&= receiver_id != status.conversation&.account_id should_filter &&= status.account_id != status.in_reply_to_account_id - should_filter &&= !(crutches[:following][status.in_reply_to_account_id] && crutches[:following][status.conversation&.account_id]) + should_filter &&= if filter_options[:to_unknown] + !(crutches[:following][status.in_reply_to_account_id] && crutches[:following][status.conversation&.account_id]) + else + !crutches[:following][status.in_reply_to_account_id] + end return !!should_filter elsif status.reblog? should_filter = status.reblog.reply? should_filter &&= status.reblog.account_id != status.reblog.in_reply_to_account_id - should_filter &&= !(crutches[:following][status.reblog.in_reply_to_account_id] && crutches[:following][status.reblog.conversation&.account_id]) - - should_filter ||= !crutches[:following][status.reblog.account_id] if status.reblog.account.silenced? - should_filter ||= !crutches[:following][status.reblog.conversation&.account_id] if status.reblog.conversation&.account&.silenced? + should_filter &&= if filter_options[:to_unknown] + !(crutches[:following][status.reblog.in_reply_to_account_id] && crutches[:following][status.reblog.conversation&.account_id]) + else + !crutches[:following][status.reblog.in_reply_to_account_id] + end + should_filter ||= !crutches[:following][status.reblog.account_id] if filter_options[:from_account] || status.reblog.account.silenced? should_filter ||= crutches[:hiding_reblogs][status.account_id] should_filter ||= crutches[:blocked_by][status.reblog.account_id] should_filter ||= crutches[:domain_blocking][status.reblog.account.domain] @@ -423,6 +432,17 @@ class FeedManager redis.zrem(timeline_key, status.id) end + def filter_options_for(receiver_id) + Rails.cache.fetch("filter_settings:#{receiver_id}", expires_in: 1.month) do + return {} if (settings = User.find_by(account_id: receiver_id)&.settings).blank? + + { + to_unknown: settings.filter_to_unknown, + from_unknown: settings.filter_from_unknown, + } + end + end + def build_crutches(receiver_id, statuses) crutches = {} @@ -450,3 +470,4 @@ class FeedManager crutches end end +# rubocop:enable Metrics/ClassLength diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index 28f40dc73..7b67a5a58 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -60,6 +60,8 @@ class UserSettingsDecorator user.settings['boost_every'] = boost_every_preference if change?('setting_boost_every') user.settings['boost_jitter'] = boost_jitter_preference if change?('setting_boost_jitter') user.settings['boost_random'] = boost_random_preference if change?('setting_boost_random') + user.settings['filter_to_unknown'] = filter_to_unknown_preference if change?('setting_filter_to_unknown') + user.settings['filter_from_unknown'] = filter_from_unknown_preference if change?('setting_filter_from_unknown') end def merged_notification_emails @@ -226,6 +228,14 @@ class UserSettingsDecorator boolean_cast_setting 'setting_boost_random' end + def filter_to_unknown_preference + boolean_cast_setting 'setting_filter_to_unknown' + end + + def filter_from_unknown_preference + boolean_cast_setting 'setting_filter_from_unknown' + end + def boolean_cast_setting(key) ActiveModel::Type::Boolean.new.cast(settings[key]) end diff --git a/app/models/user.rb b/app/models/user.rb index 8e10d6e9d..9d1af7db6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -119,6 +119,7 @@ class User < ApplicationRecord :style_wide_media, :publish_in, :unpublish_in, :unpublish_delete, :boost_every, :boost_jitter, :boost_random, + :filter_to_unknown, :filter_from_unknown, to: :settings, prefix: :setting, allow_nil: false attr_reader :invite_code, :sign_in_token_attempt diff --git a/app/views/settings/preferences/filters/show.html.haml b/app/views/settings/preferences/filters/show.html.haml new file mode 100644 index 000000000..f91010724 --- /dev/null +++ b/app/views/settings/preferences/filters/show.html.haml @@ -0,0 +1,22 @@ +- content_for :page_title do + = t('settings.preferences') + +- content_for :heading_actions do + = button_tag t('generic.save_changes'), class: 'button', form: 'edit_preferences' + += simple_form_for current_user, url: settings_preferences_filters_path, html: { method: :put, id: 'edit_preferences' } do |f| + = render 'shared/error_messages', object: current_user + + %h4= t 'preferences.filtering' + + .fields-group + = f.input :setting_filter_to_unknown, as: :boolean, wrapper: :with_label + = f.input :setting_filter_from_unknown, as: :boolean, wrapper: :with_label + + %h4= t 'preferences.public_timelines' + + .fields-group + = f.input :chosen_languages, collection: filterable_languages.sort, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + + .actions + = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index efe8cd0db..87a03a515 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -41,10 +41,5 @@ .fields-group = f.input :setting_default_content_type, collection: ['text/plain', 'text/markdown', 'text/html'], wrapper: :with_label, include_blank: false, label_method: lambda { |item| safe_join([t("simple_form.labels.defaults.setting_default_content_type_#{item.split('/')[1]}"), content_tag(:span, t("simple_form.hints.defaults.setting_default_content_type_#{item.split('/')[1]}"), class: 'hint')]) }, required: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' - %h4= t 'preferences.public_timelines' - - .fields-group - = f.input :chosen_languages, collection: filterable_languages.sort, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' - .actions = f.button :button, t('generic.save_changes'), type: :submit |