Merge commit '563fc88821
' into kb_migration
This commit is contained in:
commit
5233e68f13
20 changed files with 183 additions and 22 deletions
34
app/controllers/admin/ng_words_controller.rb
Normal file
34
app/controllers/admin/ng_words_controller.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class NgWordsController < BaseController
|
||||||
|
def show
|
||||||
|
authorize :ng_words, :show?
|
||||||
|
|
||||||
|
@admin_settings = Form::AdminSettings.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
authorize :ng_words, :create?
|
||||||
|
|
||||||
|
@admin_settings = Form::AdminSettings.new(settings_params)
|
||||||
|
|
||||||
|
if @admin_settings.save
|
||||||
|
flash[:notice] = I18n.t('generic.changes_saved_msg')
|
||||||
|
redirect_to after_update_redirect_path
|
||||||
|
else
|
||||||
|
render :index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def after_update_redirect_path
|
||||||
|
admin_ng_words_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def settings_params
|
||||||
|
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -88,6 +88,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||||
process_tags
|
process_tags
|
||||||
process_audience
|
process_audience
|
||||||
|
|
||||||
|
return unless valid_status?
|
||||||
|
|
||||||
ApplicationRecord.transaction do
|
ApplicationRecord.transaction do
|
||||||
@status = Status.create!(@params)
|
@status = Status.create!(@params)
|
||||||
attach_tags(@status)
|
attach_tags(@status)
|
||||||
|
@ -139,6 +141,10 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def valid_status?
|
||||||
|
!Admin::NgWord.reject?("#{@params[:spoiler_text]}\n#{@params[:text]}") && !Admin::NgWord.hashtag_reject?(@tags.size)
|
||||||
|
end
|
||||||
|
|
||||||
def reply_to_local_account?
|
def reply_to_local_account?
|
||||||
accounts_in_audience.any?(&:local?)
|
accounts_in_audience.any?(&:local?)
|
||||||
end
|
end
|
||||||
|
|
|
@ -343,6 +343,7 @@ class Account < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_reactions_must_following?
|
def emoji_reactions_must_following?
|
||||||
|
return false unless Setting.enable_block_emoji_reaction_settings
|
||||||
return user&.settings&.[]('emoji_reactions.must_be_following') || false if user.present?
|
return user&.settings&.[]('emoji_reactions.must_be_following') || false if user.present?
|
||||||
return settings['emoji_reactions_must_be_following'] || false if settings.present?
|
return settings['emoji_reactions_must_be_following'] || false if settings.present?
|
||||||
|
|
||||||
|
@ -350,6 +351,7 @@ class Account < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_reactions_must_follower?
|
def emoji_reactions_must_follower?
|
||||||
|
return false unless Setting.enable_block_emoji_reaction_settings
|
||||||
return user&.settings&.[]('emoji_reactions.must_be_follower') || false if user.present?
|
return user&.settings&.[]('emoji_reactions.must_be_follower') || false if user.present?
|
||||||
return settings['emoji_reaction_must_be_follower'] || false if settings.present?
|
return settings['emoji_reaction_must_be_follower'] || false if settings.present?
|
||||||
|
|
||||||
|
@ -357,6 +359,7 @@ class Account < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_reactions_deny_from_all?
|
def emoji_reactions_deny_from_all?
|
||||||
|
return false unless Setting.enable_block_emoji_reaction_settings
|
||||||
return user&.settings&.[]('emoji_reactions.deny_from_all') || false if user.present?
|
return user&.settings&.[]('emoji_reactions.deny_from_all') || false if user.present?
|
||||||
return settings['emoji_reaction_deny_from_all'] || false if settings.present?
|
return settings['emoji_reaction_deny_from_all'] || false if settings.present?
|
||||||
|
|
||||||
|
|
28
app/models/admin/ng_word.rb
Normal file
28
app/models/admin/ng_word.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Admin::NgWord
|
||||||
|
class << self
|
||||||
|
def reject?(text)
|
||||||
|
ng_words.any? { |word| text.include?(word) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def hashtag_reject?(hashtag_count)
|
||||||
|
post_hash_tags_max.positive? && post_hash_tags_max < hashtag_count
|
||||||
|
end
|
||||||
|
|
||||||
|
def hashtag_reject_with_extractor?(text)
|
||||||
|
hashtag_reject?(Extractor.extract_hashtags(text)&.size || 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def ng_words
|
||||||
|
Setting.ng_words
|
||||||
|
end
|
||||||
|
|
||||||
|
def post_hash_tags_max
|
||||||
|
value = Setting.post_hash_tags_max
|
||||||
|
value.is_a?(Integer) && value.positive? ? value : 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -34,12 +34,17 @@ class Form::AdminSettings
|
||||||
backups_retention_period
|
backups_retention_period
|
||||||
status_page_url
|
status_page_url
|
||||||
captcha_enabled
|
captcha_enabled
|
||||||
|
ng_words
|
||||||
|
enable_block_emoji_reaction_settings
|
||||||
|
hide_local_users_for_anonymous
|
||||||
|
post_hash_tags_max
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
INTEGER_KEYS = %i(
|
INTEGER_KEYS = %i(
|
||||||
media_cache_retention_period
|
media_cache_retention_period
|
||||||
content_cache_retention_period
|
content_cache_retention_period
|
||||||
backups_retention_period
|
backups_retention_period
|
||||||
|
post_hash_tags_max
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
BOOLEAN_KEYS = %i(
|
BOOLEAN_KEYS = %i(
|
||||||
|
@ -54,6 +59,8 @@ class Form::AdminSettings
|
||||||
noindex
|
noindex
|
||||||
require_invite_text
|
require_invite_text
|
||||||
captcha_enabled
|
captcha_enabled
|
||||||
|
enable_block_emoji_reaction_settings
|
||||||
|
hide_local_users_for_anonymous
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
UPLOAD_KEYS = %i(
|
UPLOAD_KEYS = %i(
|
||||||
|
@ -61,6 +68,10 @@ class Form::AdminSettings
|
||||||
mascot
|
mascot
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
|
STRING_ARRAY_KEYS = %i(
|
||||||
|
ng_words
|
||||||
|
).freeze
|
||||||
|
|
||||||
attr_accessor(*KEYS)
|
attr_accessor(*KEYS)
|
||||||
|
|
||||||
validates :registrations_mode, inclusion: { in: %w(open approved none) }, if: -> { defined?(@registrations_mode) }
|
validates :registrations_mode, inclusion: { in: %w(open approved none) }, if: -> { defined?(@registrations_mode) }
|
||||||
|
@ -80,6 +91,8 @@ class Form::AdminSettings
|
||||||
|
|
||||||
stored_value = if UPLOAD_KEYS.include?(key)
|
stored_value = if UPLOAD_KEYS.include?(key)
|
||||||
SiteUpload.where(var: key).first_or_initialize(var: key)
|
SiteUpload.where(var: key).first_or_initialize(var: key)
|
||||||
|
elsif STRING_ARRAY_KEYS.include?(key)
|
||||||
|
Setting.public_send(key)&.join("\n") || ''
|
||||||
else
|
else
|
||||||
Setting.public_send(key)
|
Setting.public_send(key)
|
||||||
end
|
end
|
||||||
|
@ -122,6 +135,8 @@ class Form::AdminSettings
|
||||||
value == '1'
|
value == '1'
|
||||||
elsif INTEGER_KEYS.include?(key)
|
elsif INTEGER_KEYS.include?(key)
|
||||||
value.blank? ? value : Integer(value)
|
value.blank? ? value : Integer(value)
|
||||||
|
elsif STRING_ARRAY_KEYS.include?(key)
|
||||||
|
value&.split(/\r\n|\r|\n/)&.filter(&:present?)&.uniq || []
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,7 +24,7 @@ class PublicFeed
|
||||||
scope.merge!(without_replies_scope) unless with_replies?
|
scope.merge!(without_replies_scope) unless with_replies?
|
||||||
scope.merge!(without_reblogs_scope) unless with_reblogs?
|
scope.merge!(without_reblogs_scope) unless with_reblogs?
|
||||||
scope.merge!(local_only_scope) if local_only?
|
scope.merge!(local_only_scope) if local_only?
|
||||||
scope.merge!(remote_only_scope) if remote_only?
|
scope.merge!(remote_only_scope) if remote_only? || hide_local_users?
|
||||||
scope.merge!(global_timeline_only_scope) if global_timeline?
|
scope.merge!(global_timeline_only_scope) if global_timeline?
|
||||||
scope.merge!(account_filters_scope) if account?
|
scope.merge!(account_filters_scope) if account?
|
||||||
scope.merge!(media_only_scope) if media_only?
|
scope.merge!(media_only_scope) if media_only?
|
||||||
|
@ -54,6 +54,10 @@ class PublicFeed
|
||||||
options[:remote]
|
options[:remote]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def hide_local_users?
|
||||||
|
@account.nil? && Setting.hide_local_users_for_anonymous
|
||||||
|
end
|
||||||
|
|
||||||
def global_timeline?
|
def global_timeline?
|
||||||
!options[:remote] && !options[:local]
|
!options[:remote] && !options[:local]
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,7 +29,7 @@ class TagFeed < PublicFeed
|
||||||
scope.merge!(tagged_with_all_scope)
|
scope.merge!(tagged_with_all_scope)
|
||||||
scope.merge!(tagged_with_none_scope)
|
scope.merge!(tagged_with_none_scope)
|
||||||
scope.merge!(local_only_scope) if local_only?
|
scope.merge!(local_only_scope) if local_only?
|
||||||
scope.merge!(remote_only_scope) if remote_only?
|
scope.merge!(remote_only_scope) if remote_only? || hide_local_users?
|
||||||
scope.merge!(account_filters_scope) if account?
|
scope.merge!(account_filters_scope) if account?
|
||||||
scope.merge!(media_only_scope) if media_only?
|
scope.merge!(media_only_scope) if media_only?
|
||||||
scope.merge!(anonymous_scope) unless account?
|
scope.merge!(anonymous_scope) unless account?
|
||||||
|
|
|
@ -36,6 +36,7 @@ class UserRole < ApplicationRecord
|
||||||
manage_roles: (1 << 17),
|
manage_roles: (1 << 17),
|
||||||
manage_user_access: (1 << 18),
|
manage_user_access: (1 << 18),
|
||||||
delete_user_data: (1 << 19),
|
delete_user_data: (1 << 19),
|
||||||
|
manage_ng_words: (1 << 30),
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
module Flags
|
module Flags
|
||||||
|
@ -61,6 +62,7 @@ class UserRole < ApplicationRecord
|
||||||
manage_blocks
|
manage_blocks
|
||||||
manage_taxonomies
|
manage_taxonomies
|
||||||
manage_invites
|
manage_invites
|
||||||
|
manage_ng_words
|
||||||
).freeze,
|
).freeze,
|
||||||
|
|
||||||
administration: %w(
|
administration: %w(
|
||||||
|
|
11
app/policies/ng_words_policy.rb
Normal file
11
app/policies/ng_words_policy.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class NgWordsPolicy < ApplicationPolicy
|
||||||
|
def show?
|
||||||
|
role.can?(:manage_ng_words)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create?
|
||||||
|
role.can?(:manage_ng_words)
|
||||||
|
end
|
||||||
|
end
|
|
@ -18,7 +18,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
||||||
@request_id = request_id
|
@request_id = request_id
|
||||||
|
|
||||||
# Only native types can be updated at the moment
|
# Only native types can be updated at the moment
|
||||||
return @status if !expected_type? || already_updated_more_recently?
|
return @status if !expected_type? || already_updated_more_recently? || !valid_status?
|
||||||
|
|
||||||
if @status_parser.edited_at.present? && (@status.edited_at.nil? || @status_parser.edited_at > @status.edited_at)
|
if @status_parser.edited_at.present? && (@status.edited_at.nil? || @status_parser.edited_at > @status.edited_at)
|
||||||
handle_explicit_update!
|
handle_explicit_update!
|
||||||
|
@ -152,6 +152,10 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def valid_status?
|
||||||
|
!Admin::NgWord.reject?("#{@status_parser.spoiler_text}\n#{@status_parser.text}") && !Admin::NgWord.hashtag_reject?(@tags.size)
|
||||||
|
end
|
||||||
|
|
||||||
def update_immediate_attributes!
|
def update_immediate_attributes!
|
||||||
@status.text = @status_parser.text || ''
|
@status.text = @status_parser.text || ''
|
||||||
@status.spoiler_text = @status_parser.spoiler_text || ''
|
@status.spoiler_text = @status_parser.spoiler_text || ''
|
||||||
|
|
|
@ -44,6 +44,7 @@ class PostStatusService < BaseService
|
||||||
|
|
||||||
return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
|
return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
|
||||||
|
|
||||||
|
validate_status!
|
||||||
validate_media!
|
validate_media!
|
||||||
preprocess_attributes!
|
preprocess_attributes!
|
||||||
|
|
||||||
|
@ -158,6 +159,11 @@ class PostStatusService < BaseService
|
||||||
GroupReblogService.new.call(@status)
|
GroupReblogService.new.call(@status)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_status!
|
||||||
|
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if Admin::NgWord.reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
|
||||||
|
raise Mastodon::ValidationError, I18n.t('statuses.too_many_hashtags') if Admin::NgWord.hashtag_reject_with_extractor?(@options[:text])
|
||||||
|
end
|
||||||
|
|
||||||
def validate_media!
|
def validate_media!
|
||||||
if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
|
if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
|
||||||
@media = []
|
@media = []
|
||||||
|
|
|
@ -27,6 +27,8 @@ class UpdateStatusService < BaseService
|
||||||
|
|
||||||
clear_histories! if @options[:no_history]
|
clear_histories! if @options[:no_history]
|
||||||
|
|
||||||
|
validate_status!
|
||||||
|
|
||||||
Status.transaction do
|
Status.transaction do
|
||||||
create_previous_edit! unless @options[:no_history]
|
create_previous_edit! unless @options[:no_history]
|
||||||
update_media_attachments! if @options.key?(:media_ids)
|
update_media_attachments! if @options.key?(:media_ids)
|
||||||
|
@ -71,6 +73,11 @@ class UpdateStatusService < BaseService
|
||||||
@status.media_attachments.reload
|
@status.media_attachments.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_status!
|
||||||
|
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if Admin::NgWord.reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
|
||||||
|
raise Mastodon::ValidationError, I18n.t('statuses.too_many_hashtags') if Admin::NgWord.hashtag_reject_with_extractor?(@options[:text])
|
||||||
|
end
|
||||||
|
|
||||||
def validate_media!
|
def validate_media!
|
||||||
return [] if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
|
return [] if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ class EmojiReactionValidator < ActiveModel::Validator
|
||||||
|
|
||||||
emoji_reaction.errors.add(:name, I18n.t('reactions.errors.unrecognized_emoji')) if emoji_reaction.custom_emoji_id.blank? && !unicode_emoji?(emoji_reaction.name)
|
emoji_reaction.errors.add(:name, I18n.t('reactions.errors.unrecognized_emoji')) if emoji_reaction.custom_emoji_id.blank? && !unicode_emoji?(emoji_reaction.name)
|
||||||
emoji_reaction.errors.add(:name, I18n.t('reactions.errors.unrecognized_emoji')) if emoji_reaction.custom_emoji_id.present? && disabled_custom_emoji?(emoji_reaction.custom_emoji)
|
emoji_reaction.errors.add(:name, I18n.t('reactions.errors.unrecognized_emoji')) if emoji_reaction.custom_emoji_id.present? && disabled_custom_emoji?(emoji_reaction.custom_emoji)
|
||||||
emoji_reaction.errors.add(:name, I18n.t('reactions.errors.banned')) if deny_from_all?(emoji_reaction) || non_follower?(emoji_reaction) || non_following?(emoji_reaction)
|
emoji_reaction.errors.add(:name, I18n.t('reactions.errors.banned')) if deny_emoji_reactions?(emoji_reaction)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -21,24 +21,23 @@ class EmojiReactionValidator < ActiveModel::Validator
|
||||||
custom_emoji.nil? ? false : custom_emoji.disabled
|
custom_emoji.nil? ? false : custom_emoji.disabled
|
||||||
end
|
end
|
||||||
|
|
||||||
def deny_from_all?(emoji_reaction)
|
def deny_emoji_reactions?(emoji_reaction)
|
||||||
|
return false unless Setting.enable_block_emoji_reaction_settings
|
||||||
return false if emoji_reaction.status.account.user.nil?
|
return false if emoji_reaction.status.account.user.nil?
|
||||||
return false if emoji_reaction.status.account_id == emoji_reaction.account_id
|
return false if emoji_reaction.status.account_id == emoji_reaction.account_id
|
||||||
|
|
||||||
|
deny_from_all?(emoji_reaction) || non_follower?(emoji_reaction) || non_following?(emoji_reaction)
|
||||||
|
end
|
||||||
|
|
||||||
|
def deny_from_all?(emoji_reaction)
|
||||||
emoji_reaction.status.account.user.settings['emoji_reactions.deny_from_all']
|
emoji_reaction.status.account.user.settings['emoji_reactions.deny_from_all']
|
||||||
end
|
end
|
||||||
|
|
||||||
def non_following?(emoji_reaction)
|
def non_following?(emoji_reaction)
|
||||||
return false if emoji_reaction.status.account.user.nil?
|
|
||||||
return false if emoji_reaction.status.account_id == emoji_reaction.account_id
|
|
||||||
|
|
||||||
emoji_reaction.status.account.user.settings['emoji_reactions.must_be_following'] && !emoji_reaction.status.account.following?(emoji_reaction.account)
|
emoji_reaction.status.account.user.settings['emoji_reactions.must_be_following'] && !emoji_reaction.status.account.following?(emoji_reaction.account)
|
||||||
end
|
end
|
||||||
|
|
||||||
def non_follower?(emoji_reaction)
|
def non_follower?(emoji_reaction)
|
||||||
return false if emoji_reaction.status.account.user.nil?
|
|
||||||
return false if emoji_reaction.status.account_id == emoji_reaction.account_id
|
|
||||||
|
|
||||||
emoji_reaction.status.account.user.settings['emoji_reactions.must_be_follower'] && !emoji_reaction.account.following?(emoji_reaction.status.account)
|
emoji_reaction.status.account.user.settings['emoji_reactions.must_be_follower'] && !emoji_reaction.account.following?(emoji_reaction.status.account)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
23
app/views/admin/ng_words/show.html.haml
Normal file
23
app/views/admin/ng_words/show.html.haml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('admin.ng_words.title')
|
||||||
|
|
||||||
|
- content_for :header_tags do
|
||||||
|
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
||||||
|
|
||||||
|
= simple_form_for @admin_settings, url: admin_ng_words_path, html: { method: :post } do |f|
|
||||||
|
= render 'shared/error_messages', object: @admin_settings
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :ng_words, wrapper: :with_label, as: :text, input_html: { rows: 12 }, label: t('admin.ng_words.keywords')
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :post_hash_tags_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_hash_tags_max')
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :enable_block_emoji_reaction_settings, wrapper: :with_label, as: :boolean, label: t('admin.ng_words.enable_block_emoji_reaction_settings')
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :hide_local_users_for_anonymous, wrapper: :with_label, as: :boolean, label: t('admin.ng_words.hide_local_users_for_anonymous')
|
||||||
|
|
||||||
|
.actions
|
||||||
|
= f.button :button, t('generic.save_changes'), type: :submit
|
|
@ -33,9 +33,10 @@
|
||||||
= ff.input :'interactions.must_be_follower', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_follower')
|
= ff.input :'interactions.must_be_follower', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_follower')
|
||||||
= ff.input :'interactions.must_be_following', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following')
|
= ff.input :'interactions.must_be_following', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following')
|
||||||
= ff.input :'interactions.must_be_following_dm', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following_dm')
|
= ff.input :'interactions.must_be_following_dm', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following_dm')
|
||||||
= ff.input :'emoji_reactions.must_be_follower', kmyblue: true, wrapper: :with_label, label: I18n.t('simple_form.labels.emoji_reactions.must_be_follower')
|
- if Setting.enable_block_emoji_reaction_settings
|
||||||
= ff.input :'emoji_reactions.must_be_following', kmyblue: true, wrapper: :with_label, label: I18n.t('simple_form.labels.emoji_reactions.must_be_following')
|
= ff.input :'emoji_reactions.must_be_follower', kmyblue: true, wrapper: :with_label, label: I18n.t('simple_form.labels.emoji_reactions.must_be_follower')
|
||||||
= ff.input :'emoji_reactions.deny_from_all', kmyblue: true, wrapper: :with_label, label: I18n.t('simple_form.labels.emoji_reactions.deny_from_all')
|
= ff.input :'emoji_reactions.must_be_following', kmyblue: true, wrapper: :with_label, label: I18n.t('simple_form.labels.emoji_reactions.must_be_following')
|
||||||
|
= ff.input :'emoji_reactions.deny_from_all', kmyblue: true, wrapper: :with_label, label: I18n.t('simple_form.labels.emoji_reactions.deny_from_all')
|
||||||
|
|
||||||
= f.simple_fields_for :settings, current_user.settings do |ff|
|
= f.simple_fields_for :settings, current_user.settings do |ff|
|
||||||
.fields-group
|
.fields-group
|
||||||
|
|
|
@ -48,16 +48,16 @@
|
||||||
.fields-group
|
.fields-group
|
||||||
= ff.input :show_application, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_show_application'), hint: I18n.t('simple_form.hints.defaults.setting_show_application')
|
= ff.input :show_application, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_show_application'), hint: I18n.t('simple_form.hints.defaults.setting_show_application')
|
||||||
|
|
||||||
%h4= t 'preferences.stop_deliver'
|
%h4= t 'preferences.stop_deliver'
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :setting_send_without_domain_blocks, kmyblue: true, recommended: :not_recommended, as: :boolean, wrapper: :with_label
|
= ff.input :send_without_domain_blocks, kmyblue: true, recommended: :not_recommended, as: :boolean, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_send_without_domain_blocks'), hint: I18n.t('simple_form.hints.defaults.setting_send_without_domain_blocks')
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :setting_reject_public_unlisted_subscription, kmyblue: true, as: :boolean, wrapper: :with_label
|
= ff.input :reject_public_unlisted_subscription, kmyblue: true, as: :boolean, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_reject_public_unlisted_subscription')
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :setting_reject_unlisted_subscription, kmyblue: true, as: :boolean, wrapper: :with_label
|
= ff.input :reject_unlisted_subscription, kmyblue: true, as: :boolean, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_reject_unlisted_subscription'), hint: I18n.t('simple_form.hints.defaults.setting_reject_unlisted_subscription')
|
||||||
|
|
||||||
%h4= t 'preferences.hide'
|
%h4= t 'preferences.hide'
|
||||||
|
|
||||||
|
|
|
@ -595,6 +595,12 @@ en:
|
||||||
title: IP rules
|
title: IP rules
|
||||||
media_attachments:
|
media_attachments:
|
||||||
title: Media attachments
|
title: Media attachments
|
||||||
|
ng_words:
|
||||||
|
enable_block_emoji_reaction_settings: Enable block emoji reactions settings for users
|
||||||
|
hide_local_users_for_anonymous: Hide timeline local user posts from anonymous
|
||||||
|
keywords: Reject keywords
|
||||||
|
post_hash_tags_max: Hash tags max for posts
|
||||||
|
title: NG words and against spams
|
||||||
relationships:
|
relationships:
|
||||||
title: "%{acct}'s relationships"
|
title: "%{acct}'s relationships"
|
||||||
relays:
|
relays:
|
||||||
|
@ -1710,6 +1716,7 @@ en:
|
||||||
one: "%{count} video"
|
one: "%{count} video"
|
||||||
other: "%{count} videos"
|
other: "%{count} videos"
|
||||||
boosted_from_html: Boosted from %{acct_link}
|
boosted_from_html: Boosted from %{acct_link}
|
||||||
|
contains_ng_words: The post contains NG words
|
||||||
content_warning: 'Content warning: %{warning}'
|
content_warning: 'Content warning: %{warning}'
|
||||||
default_language: Same as interface language
|
default_language: Same as interface language
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
|
@ -1747,6 +1754,7 @@ en:
|
||||||
show_older: Show older
|
show_older: Show older
|
||||||
show_thread: Show thread
|
show_thread: Show thread
|
||||||
title: '%{name}: "%{quote}"'
|
title: '%{name}: "%{quote}"'
|
||||||
|
too_many_hashtags: Too many hashtags
|
||||||
visibilities:
|
visibilities:
|
||||||
direct: Direct
|
direct: Direct
|
||||||
private: Followers-only
|
private: Followers-only
|
||||||
|
|
|
@ -594,6 +594,12 @@ ja:
|
||||||
title: IPルール
|
title: IPルール
|
||||||
media_attachments:
|
media_attachments:
|
||||||
title: 投稿された画像
|
title: 投稿された画像
|
||||||
|
ng_words:
|
||||||
|
enable_block_emoji_reaction_settings: 各ユーザーにスタンプ機能のブロック設定項目を解放する
|
||||||
|
hide_local_users_for_anonymous: ログインしていない状態でローカルユーザーの投稿をタイムラインから取得できないようにする
|
||||||
|
keywords: 投稿できないキーワード
|
||||||
|
post_hash_tags_max: 投稿に設定可能なハッシュタグの最大数
|
||||||
|
title: NGワードとスパム
|
||||||
relationships:
|
relationships:
|
||||||
title: "%{acct} さんのフォロー・フォロワー"
|
title: "%{acct} さんのフォロー・フォロワー"
|
||||||
relays:
|
relays:
|
||||||
|
@ -1697,6 +1703,7 @@ ja:
|
||||||
video:
|
video:
|
||||||
other: "%{count}本の動画"
|
other: "%{count}本の動画"
|
||||||
boosted_from_html: '%{acct_link}からブースト'
|
boosted_from_html: '%{acct_link}からブースト'
|
||||||
|
contains_ng_words: 投稿できない単語が含まれています
|
||||||
content_warning: '閲覧注意: %{warning}'
|
content_warning: '閲覧注意: %{warning}'
|
||||||
default_language: UIの表示言語
|
default_language: UIの表示言語
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
|
@ -1731,6 +1738,7 @@ ja:
|
||||||
show_older: 古いものを表示
|
show_older: 古いものを表示
|
||||||
show_thread: スレッドを表示
|
show_thread: スレッドを表示
|
||||||
title: '%{name}: "%{quote}"'
|
title: '%{name}: "%{quote}"'
|
||||||
|
too_many_hashtags: ハッシュタグが多すぎます
|
||||||
visibilities:
|
visibilities:
|
||||||
direct: ダイレクト
|
direct: ダイレクト
|
||||||
private: フォロワー限定
|
private: フォロワー限定
|
||||||
|
|
|
@ -36,10 +36,11 @@ SimpleNavigation::Configuration.run do |navigation|
|
||||||
s.item :links, safe_join([fa_icon('newspaper-o fw'), t('admin.trends.links.title')]), admin_trends_links_path, highlights_on: %r{/admin/trends/links}
|
s.item :links, safe_join([fa_icon('newspaper-o fw'), t('admin.trends.links.title')]), admin_trends_links_path, highlights_on: %r{/admin/trends/links}
|
||||||
end
|
end
|
||||||
|
|
||||||
n.item :moderation, safe_join([fa_icon('gavel fw'), t('moderation.title')]), nil, if: -> { current_user.can?(:manage_reports, :view_audit_log, :manage_users, :manage_invites, :manage_taxonomies, :manage_federation, :manage_blocks) } do |s|
|
n.item :moderation, safe_join([fa_icon('gavel fw'), t('moderation.title')]), nil, if: -> { current_user.can?(:manage_reports, :view_audit_log, :manage_users, :manage_invites, :manage_taxonomies, :manage_federation, :manage_blocks, :manage_ng_words) } do |s|
|
||||||
s.item :reports, safe_join([fa_icon('flag fw'), t('admin.reports.title')]), admin_reports_path, highlights_on: %r{/admin/reports}, if: -> { current_user.can?(:manage_reports) }
|
s.item :reports, safe_join([fa_icon('flag fw'), t('admin.reports.title')]), admin_reports_path, highlights_on: %r{/admin/reports}, if: -> { current_user.can?(:manage_reports) }
|
||||||
s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_path(origin: 'local'), highlights_on: %r{/admin/accounts|/admin/pending_accounts|/admin/disputes|/admin/users}, if: -> { current_user.can?(:manage_users) }
|
s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_path(origin: 'local'), highlights_on: %r{/admin/accounts|/admin/pending_accounts|/admin/disputes|/admin/users}, if: -> { current_user.can?(:manage_users) }
|
||||||
s.item :media_attachments, safe_join([fa_icon('picture-o fw'), t('admin.media_attachments.title')]), admin_media_attachments_path, highlights_on: %r{/admin/media_attachments}, if: -> { current_user.can?(:manage_users) }
|
s.item :media_attachments, safe_join([fa_icon('picture-o fw'), t('admin.media_attachments.title')]), admin_media_attachments_path, highlights_on: %r{/admin/media_attachments}, if: -> { current_user.can?(:manage_users) }
|
||||||
|
s.item :ng_words, safe_join([fa_icon('picture-o fw'), t('admin.ng_words.title')]), admin_ng_words_path, highlights_on: %r{/admin/ng_words}, if: -> { current_user.can?(:manage_ng_words) }
|
||||||
s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path, if: -> { current_user.can?(:manage_invites) }
|
s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path, if: -> { current_user.can?(:manage_invites) }
|
||||||
s.item :follow_recommendations, safe_join([fa_icon('user-plus fw'), t('admin.follow_recommendations.title')]), admin_follow_recommendations_path, highlights_on: %r{/admin/follow_recommendations}, if: -> { current_user.can?(:manage_taxonomies) }
|
s.item :follow_recommendations, safe_join([fa_icon('user-plus fw'), t('admin.follow_recommendations.title')]), admin_follow_recommendations_path, highlights_on: %r{/admin/follow_recommendations}, if: -> { current_user.can?(:manage_taxonomies) }
|
||||||
s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_path(limited: whitelist_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.can?(:manage_federation) }
|
s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_path(limited: whitelist_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.can?(:manage_federation) }
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace :admin do
|
||||||
resources :action_logs, only: [:index]
|
resources :action_logs, only: [:index]
|
||||||
resources :warning_presets, except: [:new, :show]
|
resources :warning_presets, except: [:new, :show]
|
||||||
resources :media_attachments, only: [:index]
|
resources :media_attachments, only: [:index]
|
||||||
|
resource :ng_words, only: [:show, :create]
|
||||||
|
|
||||||
resources :announcements, except: [:show] do
|
resources :announcements, except: [:show] do
|
||||||
member do
|
member do
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue