diff --git a/app/javascript/mastodon/components/status_content.jsx b/app/javascript/mastodon/components/status_content.jsx index f4ae93f80d..55447a6197 100644 --- a/app/javascript/mastodon/components/status_content.jsx +++ b/app/javascript/mastodon/components/status_content.jsx @@ -241,7 +241,12 @@ class StatusContent extends PureComponent { const renderReadMore = this.props.onClick && status.get('collapsed'); const contentLocale = intl.locale.replace(/[_-].*/, ''); const targetLanguages = this.props.languages?.get(status.get('language') || 'und'); - const renderTranslate = this.props.onTranslate && this.context.identity.signedIn && ['public', 'unlisted'].includes(status.get('visibility')) && status.get('search_index').trim().length > 0 && status.get('language') && targetLanguages?.includes(contentLocale); + const renderTranslate = this.props.onTranslate && + this.context.identity.signedIn && + (['public', 'unlisted'].includes(status.get('visibility')) || status.getIn(['account', 'other_settings', 'translatable_private'])) && + status.get('search_index').trim().length > 0 && + status.get('language') && + targetLanguages?.includes(contentLocale); const content = { __html: statusContent ?? getStatusContent(status) }; const spoilerContent = { __html: status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml') }; diff --git a/app/models/account.rb b/app/models/account.rb index d2538bb065..f3655c70d1 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -319,6 +319,10 @@ class Account < ApplicationRecord user&.setting_noai || (settings.present? && settings['noai']) || false end + def translatable_private? + user&.setting_translatable_private || (settings.present? && settings['translatable_private']) || false + end + def public_statuses_count hide_statuses_count? ? 0 : statuses_count end @@ -387,6 +391,7 @@ class Account < ApplicationRecord 'emoji_reaction_must_following' => emoji_reactions_must_following?, 'emoji_reaction_must_follower' => emoji_reactions_must_follower?, 'emoji_reaction_deny_from_all' => emoji_reactions_deny_from_all?, + 'translatable_private' => translatable_private?, } config = config.merge(settings) if settings.present? config diff --git a/app/models/concerns/has_user_settings.rb b/app/models/concerns/has_user_settings.rb index dfb37c3517..17ab1c2c1b 100644 --- a/app/models/concerns/has_user_settings.rb +++ b/app/models/concerns/has_user_settings.rb @@ -99,6 +99,10 @@ module HasUserSettings settings['noai'] end + def setting_translatable_private + settings['translatable_private'] + end + def setting_hide_statuses_count settings['hide_statuses_count'] end diff --git a/app/models/user_settings.rb b/app/models/user_settings.rb index 32bfa563cd..1db8c53f7f 100644 --- a/app/models/user_settings.rb +++ b/app/models/user_settings.rb @@ -12,6 +12,7 @@ class UserSettings setting :theme, default: -> { ::Setting.theme } setting :noindex, default: -> { ::Setting.noindex } setting :noai, default: true + setting :translatable_private, default: false setting :bio_markdown, default: false setting :discoverable_local, default: false setting :hide_statuses_count, default: false diff --git a/app/services/translate_status_service.rb b/app/services/translate_status_service.rb index c2b40433ed..4bc99c8b3c 100644 --- a/app/services/translate_status_service.rb +++ b/app/services/translate_status_service.rb @@ -30,7 +30,7 @@ class TranslateStatusService < BaseService end def permitted? - return false unless @status.distributable? && TranslationService.configured? + return false unless (@status.distributable? || @status.account.translatable_private?) && TranslationService.configured? languages[@status.language]&.include?(@target_language) end diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 99c3e0b2bc..a01bce556c 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -11,6 +11,12 @@ .fields-group = ff.input :aggregate_reblogs, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_aggregate_reblogs'), hint: I18n.t('simple_form.hints.defaults.setting_aggregate_reblogs') + .fields-group + = ff.input :noai, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_noai'), hint: I18n.t('simple_form.hints.defaults.setting_noai') + + .fields-group + = ff.input :translatable_private, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_translatable_private') + %h4= t 'preferences.posting_defaults' .fields-row diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 88d9ded9d5..b6a70352b2 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -253,6 +253,7 @@ en: setting_stop_emoji_reaction_streaming: Disable stamp streamings setting_system_font_ui: Use system's default font setting_theme: Site theme + setting_translatable_private: Allow other users translation of your private posts setting_trends: Show today's trends setting_unfollow_modal: Show confirmation dialog before unfollowing someone setting_unsafe_limited_distribution: Send limit posts with unsafe way to other servers diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 05e27f62a3..28ac8994c4 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -263,6 +263,7 @@ ja: setting_stop_emoji_reaction_streaming: スタンプのストリーミングを停止する setting_system_font_ui: システムのデフォルトフォントを使う setting_theme: サイトテーマ + setting_translatable_private: 非公開投稿の翻訳を許可する setting_trends: 本日のトレンドタグを表示する setting_unfollow_modal: フォローを解除する前に確認ダイアログを表示する setting_unsafe_limited_distribution: 安全でない方法で限定投稿を他サーバーに配信する (非推奨)