diff --git a/app/controllers/settings/preferences/reaching_controller.rb b/app/controllers/settings/preferences/reaching_controller.rb new file mode 100644 index 0000000000..bd3e6ae9b2 --- /dev/null +++ b/app/controllers/settings/preferences/reaching_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Settings::Preferences::ReachingController < Settings::Preferences::BaseController + private + + def after_update_redirect_path + settings_preferences_reaching_path + end +end diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index 634a1e40d9..62dd378866 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -61,19 +61,19 @@ class SearchQueryTransformer < Parslet::Transform when 'library' [StatusesIndex] else - [PublicStatusesIndex, StatusesIndex] + @options[:current_account].user&.setting_use_public_index ? [PublicStatusesIndex, StatusesIndex] : [StatusesIndex] end end def default_filter definition_should = [ - default_should1, - default_should2, - non_publicly_searchable, + public_index, searchability_limited, ] definition_should << searchability_public if %i(public).include?(@searchability) definition_should << searchability_private if %i(public unlisted private).include?(@searchability) + definition_should << searchable_by_me if %i(public unlisted private direct).include?(@searchability) + definition_should << self_posts if %i(public unlisted private direct).exclude?(@searchability) { bool: { @@ -83,7 +83,7 @@ class SearchQueryTransformer < Parslet::Transform } end - def default_should1 + def public_index { term: { _index: PublicStatusesIndex.index_name, @@ -91,24 +91,7 @@ class SearchQueryTransformer < Parslet::Transform } end - def default_should2 - { - bool: { - must: [ - { - term: { _index: StatusesIndex.index_name }, - }, - { - term: { - searchable_by: @options[:current_account].id, - }, - }, - ], - }, - } - end - - def non_publicly_searchable + def searchable_by_me { bool: { must: [ @@ -128,6 +111,21 @@ class SearchQueryTransformer < Parslet::Transform } end + def self_posts + { + bool: { + must: [ + { + term: { _index: StatusesIndex.index_name }, + }, + { + term: { account_id: @options[:current_account].id }, + }, + ], + }, + } + end + def searchability_public { bool: { @@ -349,6 +347,6 @@ class SearchQueryTransformer < Parslet::Transform end rule(query: sequence(:clauses)) do - Query.new(clauses, current_account: current_account) + Query.new(clauses, current_account: current_account, searchability: searchability) end end diff --git a/app/models/concerns/has_user_settings.rb b/app/models/concerns/has_user_settings.rb index c9051a3a4f..d4a8b36659 100644 --- a/app/models/concerns/has_user_settings.rb +++ b/app/models/concerns/has_user_settings.rb @@ -204,7 +204,15 @@ module HasUserSettings end def setting_default_searchability - settings['default_searchability'] || 'private' + settings['default_searchability'] || 'direct' + end + + def setting_default_searchability_of_search + settings['default_searchability_of_search'] + end + + def setting_use_public_index + settings['use_public_index'] end def setting_disallow_unlisted_public_searchability diff --git a/app/models/user_settings.rb b/app/models/user_settings.rb index 5e237e1461..28492c1394 100644 --- a/app/models/user_settings.rb +++ b/app/models/user_settings.rb @@ -26,6 +26,8 @@ class UserSettings setting :stay_privacy, default: false setting :default_reblog_privacy, default: nil setting :default_searchability, default: :direct, in: %w(public private direct limited) + setting :default_searchability_of_search, default: :public, in: %w(public private direct limited) + setting :use_public_index, default: true setting :disallow_unlisted_public_searchability, default: false setting :public_post_to_unlisted, default: false setting :reject_public_unlisted_subscription, default: false diff --git a/app/services/search_service.rb b/app/services/search_service.rb index af76dcc275..2b28dfbecc 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -11,7 +11,7 @@ class SearchService < BaseService @offset = options[:type].blank? ? 0 : options[:offset].to_i @resolve = options[:resolve] || false @following = options[:following] || false - @searchability = options[:searchability] || 'public' + @searchability = options[:searchability] || account.user&.setting_default_searchability_of_search.to_s || 'public' default_results.tap do |results| next if @query.blank? || @limit.zero? diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 4ac6124041..18dded05eb 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -14,34 +14,12 @@ %h4= t 'preferences.posting_defaults' .fields-row - .fields-group.fields-row__column.fields-row__column-6 - = ff.input :default_privacy, collection: Status.selectable_visibilities, wrapper: :with_label, include_blank: false, label_method: ->(visibility) { safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, required: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_privacy') - - .fields-group.fields-row__column.fields-row__column-6 - = ff.input :default_reblog_privacy, collection: Status.selectable_reblog_visibilities, wrapper: :with_label, kmyblue: true, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, required: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_reblog_privacy') - - .fields-row - .fields-group.fields-row__column.fields-row__column-6 - = ff.input :default_searchability, collection: Status.selectable_searchabilities, wrapper: :with_label, kmyblue: true, include_blank: false, label_method: lambda { |searchability| safe_join([I18n.t("statuses.searchabilities.#{searchability}"), I18n.t("statuses.searchabilities.#{searchability}_long")], ' - ') }, required: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_searchability') - - .fields-group.fields-row__column.fields-row__column-6 + .fields-group.fields-row__column.fields-row__column-12 = ff.input :default_language, collection: [nil] + filterable_languages, wrapper: :with_label, label_method: ->(locale) { locale.nil? ? I18n.t('statuses.default_language') : native_locale_name(locale) }, required: false, include_blank: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_language') - .fields-group - = ff.input :stay_privacy, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_stay_privacy') - - .fields-group - = ff.input :public_post_to_unlisted, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_public_post_to_unlisted'), hint: I18n.t('simple_form.hints.defaults.setting_public_post_to_unlisted') - - .fields-group - = ff.input :disallow_unlisted_public_searchability, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_disallow_unlisted_public_searchability'), hint: I18n.t('simple_form.hints.defaults.setting_disallow_unlisted_public_searchability') - .fields-group = ff.input :default_sensitive, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_default_sensitive'), hint: I18n.t('simple_form.hints.defaults.setting_default_sensitive') - .fields-group - = ff.input :'web.enable_login_privacy', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_enable_login_privacy'), hint: false - - if @dtl_enabled %h4= t 'preferences.dtl' diff --git a/app/views/settings/preferences/reaching/show.html.haml b/app/views/settings/preferences/reaching/show.html.haml new file mode 100644 index 0000000000..b3d22e8052 --- /dev/null +++ b/app/views/settings/preferences/reaching/show.html.haml @@ -0,0 +1,49 @@ +- 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_reaching_path, html: { method: :put, id: 'edit_preferences' } do |f| + = render 'shared/error_messages', object: current_user + + = f.simple_fields_for :settings, current_user.settings do |ff| + + %h4= t 'preferences.visibility' + + .fields-row + .fields-group.fields-row__column.fields-row__column-6 + = ff.input :default_privacy, collection: Status.selectable_visibilities, wrapper: :with_label, include_blank: false, label_method: ->(visibility) { safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, required: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_privacy') + + .fields-group.fields-row__column.fields-row__column-6 + = ff.input :default_reblog_privacy, collection: Status.selectable_reblog_visibilities, wrapper: :with_label, kmyblue: true, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, required: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_reblog_privacy') + + .fields-group + = ff.input :stay_privacy, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_stay_privacy') + + .fields-group + = ff.input :public_post_to_unlisted, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_public_post_to_unlisted'), hint: I18n.t('simple_form.hints.defaults.setting_public_post_to_unlisted') + + .fields-group + = ff.input :'web.enable_login_privacy', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_enable_login_privacy'), hint: false + + %h4= t 'preferences.searchability' + + .fields-row + .fields-group.fields-row__column.fields-row__column-12 + = ff.input :default_searchability, collection: Status.selectable_searchabilities, wrapper: :with_label, kmyblue: true, include_blank: false, label_method: lambda { |searchability| safe_join([I18n.t("statuses.searchabilities.#{searchability}"), I18n.t("statuses.searchabilities.#{searchability}_long")], ' - ') }, required: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_searchability') + + .fields-group + = ff.input :disallow_unlisted_public_searchability, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_disallow_unlisted_public_searchability'), hint: I18n.t('simple_form.hints.defaults.setting_disallow_unlisted_public_searchability') + + %h4= t 'preferences.search' + + .fields-row + .fields-group.fields-row__column.fields-row__column-12 + = ff.input :default_searchability_of_search, collection: Status.selectable_searchabilities, wrapper: :with_label, kmyblue: true, include_blank: false, label_method: lambda { |searchability| safe_join([I18n.t("statuses.searchabilities.#{searchability}"), I18n.t("statuses.searchabilities.#{searchability}_search_long")], ' - ') }, required: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_searchability_of_search') + + .fields-group + = ff.input :use_public_index, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_use_public_index') + + .actions + = f.button :button, t('generic.save_changes'), type: :submit diff --git a/config/locales/en.yml b/config/locales/en.yml index b05633ad47..55c71dc65e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1649,6 +1649,10 @@ en: other: Other posting_defaults: Posting defaults public_timelines: Public timelines + reaching: Visibility and search + search: Search + searchability: Searchability of your post + visibility: Visibility privacy: hint_html: "Customize how you want your profile and your posts to be found. A variety of features in Mastodon can help you reach a wider audience when enabled. Take a moment to review these settings to make sure they fit your use case." privacy: Privacy @@ -1817,12 +1821,16 @@ en: searchabilities: direct: Reactionners direct_long: Reacter of this post can find + direct_search_long: You can search you reacted posts only limited: Self only limited_long: Nobody can find, but you can + limited_search_long: You can search your posts only private: Followers and reactionners private_long: Your followers and reactionners can find + private_search_long: You can search you are following or reacted posts only public: Public public_long: Anyone can find + public_search_long: You can search all posts permitted to search show_more: Show more show_newer: Show newer show_older: Show older diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 0b36b6dc42..0d470ffb57 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1589,6 +1589,10 @@ ja: other: その他 posting_defaults: デフォルトの投稿設定 public_timelines: 公開タイムライン + reaching: 公開範囲と検索 + search: 検索 + searchability: あなたの投稿の検索許可 + visibility: 公開範囲 privacy: hint_html: "Customize how you want your profile and your posts to be found. A variety of features in Mastodon can help you reach a wider audience when enabled. Take a moment to review these settings to make sure they fit your use case." privacy: Privacy @@ -1750,12 +1754,16 @@ ja: searchabilities: direct: 反応者 direct_long: この投稿に反応した人しか検索できません + direct_search_long: あなたが反応した投稿のみが検索されます limited: 自分のみ limited_long: この投稿はあなたしか検索できません + limited_search_long: あなたの投稿のみが検索されます private: フォロワーと反応者 private_long: この投稿はフォロワーと反応者のみが検索できます + private_search_long: あなたのフォロー相手またはあなたが反応した投稿のみが検索されます public: 全て public_long: この投稿は誰でも検索できます + public_search_long: 検索が許可された全ての投稿が検索できます show_more: もっと見る show_newer: 新しいものを表示 show_older: 古いものを表示 diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 4a927ea211..c58eabf733 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -227,7 +227,8 @@ en: setting_default_language: Posting language setting_default_privacy: Posting privacy setting_default_reblog_privacy: Reblogging privacy - setting_default_searchability: Searchability + setting_default_searchability: Searchability of your own post + setting_default_searchability_of_search: Your search setting setting_default_sensitive: Always mark media as sensitive setting_delete_modal: Show confirmation dialog before deleting a post setting_disable_swiping: Disable swiping motions @@ -265,6 +266,7 @@ en: setting_unsafe_limited_distribution: Send limit posts with unsafe way to other servers setting_use_blurhash: Show colorful gradients for hidden media setting_use_pending_items: Slow mode + setting_use_public_index: Include permitted accounts post to results of search severity: Severity sign_in_token_attempt: Security code title: Title diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 699173a951..3261a44e66 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -236,7 +236,8 @@ ja: setting_default_language: 投稿する言語 setting_default_privacy: 投稿の公開範囲 setting_default_reblog_privacy: BTの公開範囲 - setting_default_searchability: 投稿の検索を許可する範囲 + setting_default_searchability: 自分の投稿の検索を許可する範囲 + setting_default_searchability_of_search: 自分が検索するときの検索許可設定 setting_default_sensitive: メディアを常に閲覧注意としてマークする setting_delete_modal: 投稿を削除する前に確認ダイアログを表示する setting_disable_swiping: スワイプでの切り替えを無効にする @@ -276,6 +277,7 @@ ja: setting_unsafe_limited_distribution: 安全でない方法で限定投稿を他サーバーに配信する (非推奨) setting_use_blurhash: 非表示のメディアを色付きのぼかしで表示する setting_use_pending_items: 手動更新モード + setting_use_public_index: Mastodonの標準設定によって検索が許可されたアカウントの公開投稿を検索結果に含める severity: 重大性 sign_in_token_attempt: セキュリティコード title: タイトル diff --git a/config/navigation.rb b/config/navigation.rb index 72b915e8bb..ce8c44d542 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -11,6 +11,7 @@ SimpleNavigation::Configuration.run do |navigation| n.item :preferences, safe_join([fa_icon('cog fw'), t('settings.preferences')]), settings_preferences_path, if: -> { current_user.functional? } do |s| s.item :appearance, safe_join([fa_icon('desktop fw'), t('settings.appearance')]), settings_preferences_appearance_path s.item :notifications, safe_join([fa_icon('bell fw'), t('settings.notifications')]), settings_preferences_notifications_path + s.item :reaching, safe_join([fa_icon('search fw'), t('preferences.reaching')]), settings_preferences_reaching_path s.item :other, safe_join([fa_icon('cog fw'), t('preferences.other')]), settings_preferences_other_path end diff --git a/config/routes/settings.rb b/config/routes/settings.rb index 64c7a5eb5b..7b7ed21dd6 100644 --- a/config/routes/settings.rb +++ b/config/routes/settings.rb @@ -10,6 +10,7 @@ namespace :settings do namespace :preferences do resource :appearance, only: [:show, :update], controller: :appearance resource :notifications, only: [:show, :update] + resource :reaching, only: [:show, :update], controller: :reaching resource :other, only: [:show, :update], controller: :other end