diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx b/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx index b01c0ede8b7a78..b8acc4b4f2e08e 100644 --- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx +++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx @@ -9,7 +9,7 @@ import { supportsPassiveEvents } from 'detect-passive-events'; import Overlay from 'react-overlays/Overlay'; import { Icon } from 'mastodon/components/icon'; -import { enableLoginPrivacy } from 'mastodon/initial_state'; +import { enableLoginPrivacy, enableLocalPrivacy } from 'mastodon/initial_state'; import { IconButton } from '../../../components/icon_button'; @@ -246,6 +246,10 @@ class PrivacyDropdown extends PureComponent { this.selectableOptions = this.selectableOptions.filter((opt) => opt.value !== 'login'); } + if (!enableLocalPrivacy) { + this.selectableOptions = this.selectableOptions.filter((opt) => opt.value !== 'public_unlisted'); + } + if (this.props.noDirect) { this.selectableOptions = this.selectableOptions.filter((opt) => opt.value !== 'direct'); } diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js index 902158bc77bb15..91582714293639 100644 --- a/app/javascript/mastodon/initial_state.js +++ b/app/javascript/mastodon/initial_state.js @@ -61,6 +61,7 @@ * @property {string} dtl_tag * @property {boolean} enable_emoji_reaction * @property {boolean} enable_login_privacy + * @property {boolean} enable_local_privacy * @property {boolean} enable_dtl_menu * @property {boolean=} expand_spoilers * @property {boolean} hide_recent_emojis @@ -130,6 +131,7 @@ export const displayMediaExpand = getMeta('display_media_expand'); export const domain = getMeta('domain'); export const dtlTag = getMeta('dtl_tag'); export const enableEmojiReaction = getMeta('enable_emoji_reaction'); +export const enableLocalPrivacy = getMeta('enable_local_privacy'); export const enableLoginPrivacy = getMeta('enable_login_privacy'); export const enableDtlMenu = getMeta('enable_dtl_menu'); export const expandSpoilers = getMeta('expand_spoilers'); diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 612ee01d9b4b1b..c57fa01761b122 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -58,7 +58,7 @@ import { import { REDRAFT } from '../actions/statuses'; import { STORE_HYDRATE } from '../actions/store'; import { TIMELINE_DELETE } from '../actions/timelines'; -import { me } from '../initial_state'; +import { enableLocalPrivacy, me } from '../initial_state'; import { unescapeHTML } from '../utils/html'; import { uuid } from '../uuid'; @@ -138,6 +138,9 @@ function clearAll(state) { if (state.get('stay_privacy') && !state.get('in_reply_to')) { map.set('default_privacy', state.get('privacy')); } + if (map.get('privacy') && !enableLocalPrivacy) { + map.set('privacy', 'public'); + } if (!state.get('in_reply_to')) { map.set('posted_on_this_session', true); } diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 08b546561db108..a2de73bd14b695 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -47,6 +47,7 @@ class Form::AdminSettings streaming_other_servers_emoji_reaction enable_emoji_reaction check_lts_version_only + enable_public_unlisted_visibility ).freeze INTEGER_KEYS = %i( @@ -74,6 +75,7 @@ class Form::AdminSettings streaming_other_servers_emoji_reaction enable_emoji_reaction check_lts_version_only + enable_public_unlisted_visibility ).freeze UPLOAD_KEYS = %i( diff --git a/app/models/status.rb b/app/models/status.rb index 9f0299a5110272..b532f58a3083a6 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -449,11 +449,13 @@ def searchable_visibility class << self def selectable_visibilities - visibilities.keys - %w(direct limited) + vs = visibilities.keys - %w(direct limited) + vs -= %w(public_unlisted) unless Setting.enable_public_unlisted_visibility + vs end def selectable_reblog_visibilities - %w(unset) + visibilities.keys - %w(direct limited) + %w(unset) + selectable_visibilities end def selectable_searchabilities diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 8f67f7e75416dd..c4e9927c740371 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -37,6 +37,7 @@ def meta status_page_url: Setting.status_page_url, sso_redirect: sso_redirect, dtl_tag: DTL_ENABLED ? DTL_TAG : nil, + enable_local_privacy: Setting.enable_public_unlisted_visibility, } if object.current_account diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb index c8b4740bff1f06..9b52277bf04d1b 100644 --- a/app/serializers/rest/instance_serializer.rb +++ b/app/serializers/rest/instance_serializer.rb @@ -108,7 +108,6 @@ def registrations # for third party apps def fedibird_capabilities capabilities = [ - :kmyblue_visibility_public_unlisted, :enable_wide_emoji, :enable_wide_emoji_reaction, :kmyblue_searchability, @@ -126,6 +125,7 @@ def fedibird_capabilities capabilities << :profile_search unless Chewy.enabled? capabilities << :emoji_reaction if Setting.enable_emoji_reaction + capabilities << :kmyblue_visibility_public_unlisted if Setting.enable_public_unlisted_visibility capabilities end diff --git a/app/serializers/rest/v1/instance_serializer.rb b/app/serializers/rest/v1/instance_serializer.rb index 9e801a7898f85a..64951b3db5293d 100644 --- a/app/serializers/rest/v1/instance_serializer.rb +++ b/app/serializers/rest/v1/instance_serializer.rb @@ -117,7 +117,6 @@ def invites_enabled # for third party apps def fedibird_capabilities capabilities = [ - :kmyblue_visibility_public_unlisted, :enable_wide_emoji, :enable_wide_emoji_reaction, :kmyblue_searchability, @@ -135,6 +134,7 @@ def fedibird_capabilities capabilities << :profile_search unless Chewy.enabled? capabilities << :emoji_reaction if Setting.enable_emoji_reaction + capabilities << :kmyblue_visibility_public_unlisted if Setting.enable_public_unlisted_visibility capabilities end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index a549ab1c78a893..b532b775bcb886 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -78,7 +78,7 @@ def preprocess_attributes! @visibility = :direct if @in_reply_to&.limited_visibility? @visibility = :limited if %w(mutual circle).include?(@options[:visibility]) @visibility = :unlisted if (@visibility&.to_sym == :public || @visibility&.to_sym == :public_unlisted || @visibility&.to_sym == :login) && @account.silenced? - @visibility = :public_unlisted if @visibility&.to_sym == :public && !@options[:force_visibility] && !@options[:application]&.superapp && @account.user&.setting_public_post_to_unlisted + @visibility = :public_unlisted if @visibility&.to_sym == :public && !@options[:force_visibility] && !@options[:application]&.superapp && @account.user&.setting_public_post_to_unlisted && Setting.enable_public_unlisted_visibility @limited_scope = @options[:visibility]&.to_sym if @visibility == :limited @searchability = searchability @searchability = :private if @account.silenced? && @searchability&.to_sym == :public @@ -86,6 +86,8 @@ def preprocess_attributes! @scheduled_at = @options[:scheduled_at]&.to_datetime @scheduled_at = nil if scheduled_in_the_past? @reference_ids = (@options[:status_reference_ids] || []).map(&:to_i).filter(&:positive?) + raise ArgumentError if !Setting.enable_public_unlisted_visibility && @visibility == :public_unlisted + load_circle overwrite_dtl_post process_sensitive_words diff --git a/app/views/admin/settings/discovery/show.html.haml b/app/views/admin/settings/discovery/show.html.haml index 6ea9e4fb4b006f..ee7d72ad320e9c 100644 --- a/app/views/admin/settings/discovery/show.html.haml +++ b/app/views/admin/settings/discovery/show.html.haml @@ -40,6 +40,11 @@ .fields-group = f.input :streaming_other_servers_emoji_reaction, as: :boolean, wrapper: :with_label, kmyblue: true + %h4= t('admin.settings.discovery.visibilities') + + .fields-group + = f.input :enable_public_unlisted_visibility, as: :boolean, wrapper: :with_label, kmyblue: true, hint: false + %h4= t('admin.settings.discovery.publish_statistics') .fields-group diff --git a/config/locales/en.yml b/config/locales/en.yml index 18ed3cb8f58606..cf45976a7c8938 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -817,6 +817,7 @@ en: publish_statistics: Publish statistics title: Discovery trends: Trends + visibilities: Visibilities domain_blocks: all: To everyone disabled: To no one diff --git a/config/locales/ja.yml b/config/locales/ja.yml index fd93ff54abf81d..b033c48264c3fc 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -814,6 +814,7 @@ ja: publish_statistics: 統計情報を公開する title: 見つける trends: トレンド + visibilities: 公開範囲 domain_blocks: all: 誰にでも許可 disabled: 誰にも許可しない diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index aa17a42816262d..af5c64ef6209ca 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -96,6 +96,7 @@ en: closed_registrations_message: Displayed when sign-ups are closed content_cache_retention_period: All posts and boosts from other servers will be deleted after the specified number of days. Some posts may not be recoverable. All related bookmarks, favourites and boosts will also be lost and impossible to undo. custom_css: You can apply custom styles on the web version of Mastodon. + enable_public_unlisted_visibility: If true, your community maybe closed-minded. If turn it false, strongly recommend that you disclose that you have disabled this setting! mascot: Overrides the illustration in the advanced web interface. media_cache_retention_period: Downloaded media files will be deleted after the specified number of days when set to a positive value, and re-downloaded on demand. peers_api_enabled: A list of domain names this server has encountered in the fediverse. No data is included here about whether you federate with a given server, just that your server knows about it. This is used by services that collect statistics on federation in a general sense. @@ -321,6 +322,7 @@ en: content_cache_retention_period: Content cache retention period custom_css: Custom CSS enable_emoji_reaction: Enable stamp function + enable_public_unlisted_visibility: Enable public-unlisted visibility mascot: Custom mascot (legacy) media_cache_retention_period: Media cache retention period peers_api_enabled: Publish list of discovered servers in the API diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index e255c43cd49c99..6ea9661d5afbe2 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -109,6 +109,7 @@ ja: closed_registrations_message: アカウント作成を停止している時に表示されます content_cache_retention_period: 指定した日数が経過した他のサーバーの投稿とブーストを削除します。削除された投稿は再取得できない場合があります。削除された投稿についたブックマークやお気に入り、ブーストも失われ、元に戻せません。 custom_css: ウェブ版のMastodonでカスタムスタイルを適用できます。 + enable_public_unlisted_visibility: 有効にするとあなたのコミュニティは閉鎖的になるかもしれません。この設定はkmyblueの主要機能の1つであり、無効にする場合は概要などに記載することを強くおすすめします。 mascot: 上級者向けWebインターフェースのイラストを上書きします。 media_cache_retention_period: 正の値に設定されている場合、ダウンロードされたメディアファイルは指定された日数の後に削除され、リクエストに応じて再ダウンロードされます。 peers_api_enabled: このサーバーが Fediverse で遭遇したドメイン名のリストです。このサーバーが知っているだけで、特定のサーバーと連合しているかのデータは含まれません。これは一般的に Fediverse に関する統計情報を収集するサービスによって使用されます。 @@ -336,6 +337,7 @@ ja: content_cache_retention_period: コンテンツキャッシュの保持期間 custom_css: カスタムCSS enable_emoji_reaction: スタンプ機能を有効にする + enable_public_unlisted_visibility: 公開範囲「ローカル公開」を有効にする mascot: カスタムマスコット(レガシー) media_cache_retention_period: メディアキャッシュの保持期間 peers_api_enabled: 発見したサーバーのリストをAPIで公開する diff --git a/config/settings.yml b/config/settings.yml index 69b3ed1ee34a91..c0b5f4109bd6aa 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -42,6 +42,7 @@ defaults: &defaults streaming_other_servers_emoji_reaction: false enable_emoji_reaction: true check_lts_version_only: true + enable_public_unlisted_visibility: true development: <<: *defaults