Add emoji_reaction_policy setting
This commit is contained in:
parent
defd790889
commit
673e607e94
15 changed files with 70 additions and 63 deletions
|
@ -577,7 +577,8 @@ class Status extends ImmutablePureComponent {
|
||||||
let emojiReactionsBar = null;
|
let emojiReactionsBar = null;
|
||||||
if (!this.props.withoutEmojiReactions && status.get('emoji_reactions')) {
|
if (!this.props.withoutEmojiReactions && status.get('emoji_reactions')) {
|
||||||
const emojiReactions = status.get('emoji_reactions');
|
const emojiReactions = status.get('emoji_reactions');
|
||||||
if (emojiReactions.size > 0 && enableEmojiReaction) {
|
const emojiReactionPolicy = status.getIn(['account', 'other_settings', 'emoji_reaction_policy']) || 'allow';
|
||||||
|
if (emojiReactions.size > 0 && enableEmojiReaction && emojiReactionPolicy !== 'block_and_hide') {
|
||||||
emojiReactionsBar = <StatusEmojiReactionsBar emojiReactions={emojiReactions} status={status} onEmojiReact={this.props.onEmojiReact} onUnEmojiReact={this.props.onUnEmojiReact} />;
|
emojiReactionsBar = <StatusEmojiReactionsBar emojiReactions={emojiReactions} status={status} onEmojiReact={this.props.onEmojiReact} onUnEmojiReact={this.props.onUnEmojiReact} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -410,13 +410,16 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
<IconButton className='status__action-bar__button' title={intl.formatMessage(messages.hide)} icon='eye' onClick={this.handleHideClick} />
|
<IconButton className='status__action-bar__button' title={intl.formatMessage(messages.hide)} icon='eye' onClick={this.handleHideClick} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const following = !account.getIn(['other_settings', 'emoji_reaction_must_follower']) || (relationship && relationship.get('following'));
|
const emojiReactionPolicy = account.getIn(['other_settings', 'emoji_reaction_policy']) || 'allow';
|
||||||
const followed = !account.getIn(['other_settings', 'emoji_reaction_must_following']) || (relationship && relationship.get('followed_by'));
|
const following = emojiReactionPolicy !== 'followees_only' || (relationship && relationship.get('following'));
|
||||||
const denyFromAll = !account.getIn(['other_settings', 'emoji_reaction_deny_from_all']);
|
const followed = emojiReactionPolicy !== 'followers_only' || (relationship && relationship.get('followed_by'));
|
||||||
|
const mutual = emojiReactionPolicy !== 'mutuals_only' || (relationship && relationship.get('following') && relationship.get('followed_by'));
|
||||||
|
const outside = emojiReactionPolicy !== 'outside_only' || (relationship && (relationship.get('following') || relationship.get('followed_by')));
|
||||||
|
const denyFromAll = emojiReactionPolicy !== 'block' && emojiReactionPolicy !== 'block_and_hide';
|
||||||
const emojiPickerButton = (
|
const emojiPickerButton = (
|
||||||
<IconButton className='status__action-bar__button' title={intl.formatMessage(messages.emojiReaction)} icon='smile-o' onClick={this.handleEmojiPickInnerButton} />
|
<IconButton className='status__action-bar__button' title={intl.formatMessage(messages.emojiReaction)} icon='smile-o' onClick={this.handleEmojiPickInnerButton} />
|
||||||
);
|
);
|
||||||
const emojiPickerDropdown = enableEmojiReaction && (writtenByMe || ((denyFromAll) && (following) && (followed))) && (
|
const emojiPickerDropdown = enableEmojiReaction && (writtenByMe || (denyFromAll && following && followed && mutual && outside)) && (
|
||||||
<EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={emojiPickerButton} />
|
<EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={emojiPickerButton} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -326,13 +326,16 @@ class ActionBar extends PureComponent {
|
||||||
reblogTitle = intl.formatMessage(messages.cannot_reblog);
|
reblogTitle = intl.formatMessage(messages.cannot_reblog);
|
||||||
}
|
}
|
||||||
|
|
||||||
const following = !account.getIn(['other_settings', 'emoji_reaction_must_follower']) || (relationship && relationship.get('following'));
|
const emojiReactionPolicy = account.getIn(['other_settings', 'emoji_reaction_policy']) || 'allow';
|
||||||
const followed = !account.getIn(['other_settings', 'emoji_reaction_must_following']) || (relationship && relationship.get('followed_by'));
|
const following = emojiReactionPolicy !== 'followees_only' || (relationship && relationship.get('following'));
|
||||||
const denyFromAll = !account.getIn(['other_settings', 'emoji_reaction_deny_from_all']);
|
const followed = emojiReactionPolicy !== 'followers_only' || (relationship && relationship.get('followed_by'));
|
||||||
|
const mutual = emojiReactionPolicy !== 'mutuals_only' || (relationship && relationship.get('following') && relationship.get('followed_by'));
|
||||||
|
const outside = emojiReactionPolicy !== 'outside_only' || (relationship && (relationship.get('following') || relationship.get('followed_by')));
|
||||||
|
const denyFromAll = emojiReactionPolicy !== 'block' && emojiReactionPolicy !== 'block_and_hide';
|
||||||
const emojiPickerButton = (
|
const emojiPickerButton = (
|
||||||
<IconButton icon='smile-o' onClick={this.handleEmojiPickInnerButton} title={intl.formatMessage(messages.pickEmoji)} />
|
<IconButton icon='smile-o' onClick={this.handleEmojiPickInnerButton} title={intl.formatMessage(messages.pickEmoji)} />
|
||||||
);
|
);
|
||||||
const emojiPickerDropdown = enableEmojiReaction && (writtenByMe || ((denyFromAll) && (following) && (followed))) && (
|
const emojiPickerDropdown = enableEmojiReaction && (writtenByMe || (denyFromAll && following && followed && mutual && outside)) && (
|
||||||
<div className='detailed-status__button'><EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={emojiPickerButton} /></div>
|
<div className='detailed-status__button'><EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={emojiPickerButton} /></div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,8 @@ class DetailedStatus extends ImmutablePureComponent {
|
||||||
let emojiReactionsBar = null;
|
let emojiReactionsBar = null;
|
||||||
if (status.get('emoji_reactions')) {
|
if (status.get('emoji_reactions')) {
|
||||||
const emojiReactions = status.get('emoji_reactions');
|
const emojiReactions = status.get('emoji_reactions');
|
||||||
if (emojiReactions.size > 0 && enableEmojiReaction) {
|
const emojiReactionPolicy = status.getIn(['account', 'other_settings', 'emoji_reaction_policy']) || 'allow';
|
||||||
|
if (emojiReactions.size > 0 && enableEmojiReaction && emojiReactionPolicy !== 'block_and_hide') {
|
||||||
emojiReactionsBar = <StatusEmojiReactionsBar emojiReactions={emojiReactions} status={status} onEmojiReact={this.props.onEmojiReact} onUnEmojiReact={this.props.onUnEmojiReact} />;
|
emojiReactionsBar = <StatusEmojiReactionsBar emojiReactions={emojiReactions} status={status} onEmojiReact={this.props.onEmojiReact} onUnEmojiReact={this.props.onUnEmojiReact} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,28 +363,12 @@ class Account < ApplicationRecord
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_reactions_must_following?
|
def emoji_reaction_policy
|
||||||
return false unless Setting.enable_block_emoji_reaction_settings || !local?
|
return :allow unless Setting.enable_block_emoji_reaction_settings || !local?
|
||||||
return user&.settings&.[]('emoji_reactions.must_be_following') || false if user.present?
|
return settings['emoji_reaction_policy']&.to_sym || :allow if settings.present?
|
||||||
return settings['emoji_reactions_must_be_following'] || false if settings.present?
|
return :allow if user.nil?
|
||||||
|
|
||||||
false
|
user.settings&.[]('emoji_reaction_policy')&.to_sym
|
||||||
end
|
|
||||||
|
|
||||||
def emoji_reactions_must_follower?
|
|
||||||
return false unless Setting.enable_block_emoji_reaction_settings || !local?
|
|
||||||
return user&.settings&.[]('emoji_reactions.must_be_follower') || false if user.present?
|
|
||||||
return settings['emoji_reaction_must_be_follower'] || false if settings.present?
|
|
||||||
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def emoji_reactions_deny_from_all?
|
|
||||||
return false unless Setting.enable_block_emoji_reaction_settings || !local?
|
|
||||||
return user&.settings&.[]('emoji_reactions.deny_from_all') || false if user.present?
|
|
||||||
return settings['emoji_reaction_deny_from_all'] || false if settings.present?
|
|
||||||
|
|
||||||
false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_settings
|
def public_settings
|
||||||
|
@ -400,9 +384,7 @@ class Account < ApplicationRecord
|
||||||
}
|
}
|
||||||
if Setting.enable_block_emoji_reaction_settings
|
if Setting.enable_block_emoji_reaction_settings
|
||||||
config = config.merge({
|
config = config.merge({
|
||||||
'emoji_reaction_must_following' => emoji_reactions_must_following?,
|
'emoji_reaction_policy' => user&.setting_emoji_reaction_policy,
|
||||||
'emoji_reaction_must_follower' => emoji_reactions_must_follower?,
|
|
||||||
'emoji_reaction_deny_from_all' => emoji_reactions_deny_from_all?,
|
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
config = config.merge(settings) if settings.present?
|
config = config.merge(settings) if settings.present?
|
||||||
|
|
|
@ -211,6 +211,10 @@ module AccountInteractions
|
||||||
other_account.following?(self)
|
other_account.following?(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mutual?(other_account)
|
||||||
|
following?(other_account) && followed_by?(other_account)
|
||||||
|
end
|
||||||
|
|
||||||
def blocking?(other_account)
|
def blocking?(other_account)
|
||||||
block_relationships.where(target_account: other_account).exists?
|
block_relationships.where(target_account: other_account).exists?
|
||||||
end
|
end
|
||||||
|
|
|
@ -79,6 +79,10 @@ module HasUserSettings
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def setting_emoji_reaction_policy
|
||||||
|
settings['emoji_reaction_policy']
|
||||||
|
end
|
||||||
|
|
||||||
def setting_unfollow_modal
|
def setting_unfollow_modal
|
||||||
settings['web.unfollow_modal']
|
settings['web.unfollow_modal']
|
||||||
end
|
end
|
||||||
|
|
|
@ -350,6 +350,8 @@ class Status < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_reactions_grouped_by_name(account = nil)
|
def emoji_reactions_grouped_by_name(account = nil)
|
||||||
|
return [] if self.account.emoji_reaction_policy == :block_and_hide
|
||||||
|
|
||||||
(Oj.load(status_stat&.emoji_reactions || '', mode: :strict) || []).tap do |emoji_reactions|
|
(Oj.load(status_stat&.emoji_reactions || '', mode: :strict) || []).tap do |emoji_reactions|
|
||||||
if account.present?
|
if account.present?
|
||||||
remove_emoji_reactions = []
|
remove_emoji_reactions = []
|
||||||
|
|
|
@ -36,6 +36,7 @@ class UserSettings
|
||||||
setting :reaction_deck, default: nil
|
setting :reaction_deck, default: nil
|
||||||
setting :stop_emoji_reaction_streaming, default: false
|
setting :stop_emoji_reaction_streaming, default: false
|
||||||
setting :emoji_reaction_streaming_notify_impl2, default: false
|
setting :emoji_reaction_streaming_notify_impl2, default: false
|
||||||
|
setting :emoji_reaction_policy, default: :allow, in: %w(allow outside_only followers_only followees_only mutuals_only block block_and_hide)
|
||||||
setting :unsafe_limited_distribution, default: false
|
setting :unsafe_limited_distribution, default: false
|
||||||
setting :dtl_force_with_tag, default: :none, in: %w(full searchability none)
|
setting :dtl_force_with_tag, default: :none, in: %w(full searchability none)
|
||||||
setting :dtl_force_subscribable, default: false
|
setting :dtl_force_subscribable, default: false
|
||||||
|
@ -84,12 +85,6 @@ class UserSettings
|
||||||
setting :must_be_following_dm, default: false
|
setting :must_be_following_dm, default: false
|
||||||
end
|
end
|
||||||
|
|
||||||
namespace :emoji_reactions do
|
|
||||||
setting :must_be_follower, default: false
|
|
||||||
setting :must_be_following, default: false
|
|
||||||
setting :deny_from_all, default: false
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(original_hash)
|
def initialize(original_hash)
|
||||||
@original_hash = original_hash || {}
|
@original_hash = original_hash || {}
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,18 +51,6 @@ class NotifyService < BaseService
|
||||||
@recipient.user.settings['interactions.must_be_following'] && !following_sender?
|
@recipient.user.settings['interactions.must_be_following'] && !following_sender?
|
||||||
end
|
end
|
||||||
|
|
||||||
def optional_non_follower_emoji_reaction?
|
|
||||||
emoji_reaction? && @recipient.user.settings['emoji_reactions.must_be_follower'] && !@notification.from_account.following?(@recipient)
|
|
||||||
end
|
|
||||||
|
|
||||||
def optional_non_following_emoji_reaction?
|
|
||||||
emoji_reaction? && @recipient.user.settings['emoji_reactions.must_be_following'] && !following_sender?
|
|
||||||
end
|
|
||||||
|
|
||||||
def emoji_reaction?
|
|
||||||
@notification.type == :emoji_reaction
|
|
||||||
end
|
|
||||||
|
|
||||||
def message?
|
def message?
|
||||||
@notification.type == :mention
|
@notification.type == :mention
|
||||||
end
|
end
|
||||||
|
@ -132,8 +120,6 @@ class NotifyService < BaseService
|
||||||
blocked ||= optional_non_follower?
|
blocked ||= optional_non_follower?
|
||||||
blocked ||= optional_non_following?
|
blocked ||= optional_non_following?
|
||||||
blocked ||= optional_non_following_and_direct?
|
blocked ||= optional_non_following_and_direct?
|
||||||
blocked ||= optional_non_follower_emoji_reaction?
|
|
||||||
blocked ||= optional_non_following_emoji_reaction?
|
|
||||||
blocked ||= conversation_muted?
|
blocked ||= conversation_muted?
|
||||||
blocked ||= blocked_mention? if @notification.type == :mention
|
blocked ||= blocked_mention? if @notification.type == :mention
|
||||||
blocked
|
blocked
|
||||||
|
|
|
@ -24,20 +24,29 @@ class EmojiReactionValidator < ActiveModel::Validator
|
||||||
def deny_emoji_reactions?(emoji_reaction)
|
def deny_emoji_reactions?(emoji_reaction)
|
||||||
return false unless Setting.enable_block_emoji_reaction_settings
|
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 deny_from_all?(emoji_reaction) if emoji_reaction.status.account_id == emoji_reaction.account_id
|
||||||
|
return false if emoji_reaction.status.account.emoji_reaction_policy == :allow
|
||||||
|
|
||||||
deny_from_all?(emoji_reaction) || non_follower?(emoji_reaction) || non_following?(emoji_reaction)
|
deny_from_all?(emoji_reaction) || non_outside?(emoji_reaction) || non_follower?(emoji_reaction) || non_following?(emoji_reaction) || non_mutual?(emoji_reaction)
|
||||||
end
|
end
|
||||||
|
|
||||||
def deny_from_all?(emoji_reaction)
|
def deny_from_all?(emoji_reaction)
|
||||||
emoji_reaction.status.account.emoji_reactions_deny_from_all?
|
%i(block block_and_hide).include?(emoji_reaction.status.account.emoji_reaction_policy)
|
||||||
end
|
end
|
||||||
|
|
||||||
def non_following?(emoji_reaction)
|
def non_following?(emoji_reaction)
|
||||||
emoji_reaction.status.account.emoji_reactions_must_following? && !emoji_reaction.status.account.following?(emoji_reaction.account)
|
emoji_reaction.status.account.emoji_reaction_policy == :followees_only && !emoji_reaction.status.account.following?(emoji_reaction.account)
|
||||||
end
|
end
|
||||||
|
|
||||||
def non_follower?(emoji_reaction)
|
def non_follower?(emoji_reaction)
|
||||||
emoji_reaction.status.account.emoji_reactions_must_follower? && !emoji_reaction.account.following?(emoji_reaction.status.account)
|
emoji_reaction.status.account.emoji_reaction_policy == :followers_only && !emoji_reaction.account.following?(emoji_reaction.status.account)
|
||||||
|
end
|
||||||
|
|
||||||
|
def non_outside?(emoji_reaction)
|
||||||
|
emoji_reaction.status.account.emoji_reaction_policy == :outside_only && !emoji_reaction.account.following?(emoji_reaction.status.account) && !emoji_reaction.status.account.following?(emoji_reaction.account)
|
||||||
|
end
|
||||||
|
|
||||||
|
def non_mutual?(emoji_reaction)
|
||||||
|
emoji_reaction.status.account.emoji_reaction_policy == :mutuals_only && !emoji_reaction.status.account.mutual?(emoji_reaction.account)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,10 +42,6 @@
|
||||||
= 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')
|
||||||
- if Setting.enable_block_emoji_reaction_settings
|
|
||||||
= 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.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
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
.fields-group
|
.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')
|
= 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')
|
||||||
|
|
||||||
|
- if Setting.enable_block_emoji_reaction_settings
|
||||||
|
= ff.input :emoji_reaction_policy, kmyblue: true, collection: ['allow', 'outside_only', 'followers_only', 'followees_only', 'mutuals_only', 'block', 'block_and_hide'], label_method: lambda { |item| safe_join([t("simple_form.labels.defaults.setting_emoji_reaction_policy_items.#{item}")]) }, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', wrapper: :with_floating_label, label: I18n.t('simple_form.labels.defaults.setting_emoji_reaction_policy')
|
||||||
|
|
||||||
- if @dtl_enabled
|
- if @dtl_enabled
|
||||||
|
|
||||||
%h4= t 'preferences.dtl'
|
%h4= t 'preferences.dtl'
|
||||||
|
|
|
@ -244,6 +244,15 @@ en:
|
||||||
setting_emoji_reaction_streaming_notify_impl2: Enable stamp notification compat with Nyastodon, Catstodon, glitch-soc
|
setting_emoji_reaction_streaming_notify_impl2: Enable stamp notification compat with Nyastodon, Catstodon, glitch-soc
|
||||||
setting_enable_emoji_reaction: Show emoji reaction on your display
|
setting_enable_emoji_reaction: Show emoji reaction on your display
|
||||||
setting_enable_login_privacy: Enable login visibility
|
setting_enable_login_privacy: Enable login visibility
|
||||||
|
setting_emoji_reaction_policy: Stamp policy
|
||||||
|
setting_emoji_reaction_policy_items:
|
||||||
|
allow: Allow all
|
||||||
|
block: Block all
|
||||||
|
block_and_hide: Block and hide
|
||||||
|
followees_only: Followings only
|
||||||
|
followers_only: Followers only
|
||||||
|
mutuals_only: Mutuals only
|
||||||
|
outside_only: Followings or followers only
|
||||||
setting_expand_spoilers: Always expand posts marked with content warnings
|
setting_expand_spoilers: Always expand posts marked with content warnings
|
||||||
setting_hide_followers_count: Hide followers count
|
setting_hide_followers_count: Hide followers count
|
||||||
setting_hide_following_count: Hide following count
|
setting_hide_following_count: Hide following count
|
||||||
|
|
|
@ -252,6 +252,15 @@ ja:
|
||||||
setting_dtl_force_with_tag: DTL参加時の投稿設定
|
setting_dtl_force_with_tag: DTL参加時の投稿設定
|
||||||
setting_dtl_menu: Webクライアントのメニューにディープタイムラインを追加する
|
setting_dtl_menu: Webクライアントのメニューにディープタイムラインを追加する
|
||||||
setting_enable_login_privacy: 公開範囲「ログインユーザーのみ」をWeb UIで選択可能にする
|
setting_enable_login_privacy: 公開範囲「ログインユーザーのみ」をWeb UIで選択可能にする
|
||||||
|
setting_emoji_reaction_policy: スタンプ受け入れ設定
|
||||||
|
setting_emoji_reaction_policy_items:
|
||||||
|
allow: 全員に許可
|
||||||
|
block: 全員禁止
|
||||||
|
block_and_hide: 全員禁止し、既存のスタンプも非表示にする
|
||||||
|
followees_only: フォロー中の相手のみ許可
|
||||||
|
followers_only: フォロワーのみ許可
|
||||||
|
mutuals_only: 相互のみ許可
|
||||||
|
outside_only: フォロー中、またはフォロワーのみに許可
|
||||||
setting_emoji_reaction_streaming_notify_impl2: Nyastodon, Catstodon, glitch-soc互換のスタンプ機能を有効にする
|
setting_emoji_reaction_streaming_notify_impl2: Nyastodon, Catstodon, glitch-soc互換のスタンプ機能を有効にする
|
||||||
setting_enable_emoji_reaction: 自分の画面に絵文字リアクションを表示する
|
setting_enable_emoji_reaction: 自分の画面に絵文字リアクションを表示する
|
||||||
setting_expand_spoilers: 閲覧注意としてマークされた投稿を常に展開する
|
setting_expand_spoilers: 閲覧注意としてマークされた投稿を常に展開する
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue