Skip to content

Commit

Permalink
Add emoji_reaction_policy setting
Browse files Browse the repository at this point in the history
  • Loading branch information
kmycode committed Sep 12, 2023
1 parent defd790 commit 673e607
Show file tree
Hide file tree
Showing 15 changed files with 70 additions and 63 deletions.
3 changes: 2 additions & 1 deletion app/javascript/mastodon/components/status.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,8 @@ class Status extends ImmutablePureComponent {
let emojiReactionsBar = null;
if (!this.props.withoutEmojiReactions && 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} />;
}
}
Expand Down
11 changes: 7 additions & 4 deletions app/javascript/mastodon/components/status_action_bar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -410,13 +410,16 @@ class StatusActionBar extends ImmutablePureComponent {
<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 followed = !account.getIn(['other_settings', 'emoji_reaction_must_following']) || (relationship && relationship.get('followed_by'));
const denyFromAll = !account.getIn(['other_settings', 'emoji_reaction_deny_from_all']);
const emojiReactionPolicy = account.getIn(['other_settings', 'emoji_reaction_policy']) || 'allow';
const following = emojiReactionPolicy !== 'followees_only' || (relationship && relationship.get('following'));
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 = (
<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} />
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,13 +326,16 @@ class ActionBar extends PureComponent {
reblogTitle = intl.formatMessage(messages.cannot_reblog);
}

const following = !account.getIn(['other_settings', 'emoji_reaction_must_follower']) || (relationship && relationship.get('following'));
const followed = !account.getIn(['other_settings', 'emoji_reaction_must_following']) || (relationship && relationship.get('followed_by'));
const denyFromAll = !account.getIn(['other_settings', 'emoji_reaction_deny_from_all']);
const emojiReactionPolicy = account.getIn(['other_settings', 'emoji_reaction_policy']) || 'allow';
const following = emojiReactionPolicy !== 'followees_only' || (relationship && relationship.get('following'));
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 = (
<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>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ class DetailedStatus extends ImmutablePureComponent {
let emojiReactionsBar = null;
if (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} />;
}
}
Expand Down
30 changes: 6 additions & 24 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -363,28 +363,12 @@ def hide_followers_count?
false
end

def emoji_reactions_must_following?
return false unless Setting.enable_block_emoji_reaction_settings || !local?
return user&.settings&.[]('emoji_reactions.must_be_following') || false if user.present?
return settings['emoji_reactions_must_be_following'] || false if settings.present?
def emoji_reaction_policy
return :allow unless Setting.enable_block_emoji_reaction_settings || !local?
return settings['emoji_reaction_policy']&.to_sym || :allow if settings.present?
return :allow if user.nil?

false
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
user.settings&.[]('emoji_reaction_policy')&.to_sym
end

def public_settings
Expand All @@ -400,9 +384,7 @@ def public_settings
}
if Setting.enable_block_emoji_reaction_settings
config = config.merge({
'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?,
'emoji_reaction_policy' => user&.setting_emoji_reaction_policy,
})
end
config = config.merge(settings) if settings.present?
Expand Down
4 changes: 4 additions & 0 deletions app/models/concerns/account_interactions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ def followed_by?(other_account)
other_account.following?(self)
end

def mutual?(other_account)
following?(other_account) && followed_by?(other_account)
end

def blocking?(other_account)
block_relationships.where(target_account: other_account).exists?
end
Expand Down
4 changes: 4 additions & 0 deletions app/models/concerns/has_user_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ def setting_emoji_reaction_streaming_notify_impl2
false
end

def setting_emoji_reaction_policy
settings['emoji_reaction_policy']
end

def setting_unfollow_modal
settings['web.unfollow_modal']
end
Expand Down
2 changes: 2 additions & 0 deletions app/models/status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ def add_status_referred_by_count!(diff)
end

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|
if account.present?
remove_emoji_reactions = []
Expand Down
7 changes: 1 addition & 6 deletions app/models/user_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class KeyError < Error; end
setting :reaction_deck, default: nil
setting :stop_emoji_reaction_streaming, 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 :dtl_force_with_tag, default: :none, in: %w(full searchability none)
setting :dtl_force_subscribable, default: false
Expand Down Expand Up @@ -84,12 +85,6 @@ class KeyError < Error; end
setting :must_be_following_dm, default: false
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)
@original_hash = original_hash || {}
end
Expand Down
14 changes: 0 additions & 14 deletions app/services/notify_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,6 @@ def optional_non_following?
@recipient.user.settings['interactions.must_be_following'] && !following_sender?
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?
@notification.type == :mention
end
Expand Down Expand Up @@ -132,8 +120,6 @@ def blocked?
blocked ||= optional_non_follower?
blocked ||= optional_non_following?
blocked ||= optional_non_following_and_direct?
blocked ||= optional_non_follower_emoji_reaction?
blocked ||= optional_non_following_emoji_reaction?
blocked ||= conversation_muted?
blocked ||= blocked_mention? if @notification.type == :mention
blocked
Expand Down
19 changes: 14 additions & 5 deletions app/validators/emoji_reaction_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,29 @@ def disabled_custom_emoji?(custom_emoji)
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_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

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

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

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
4 changes: 0 additions & 4 deletions app/views/settings/preferences/notifications/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -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_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')
- 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|
.fields-group
Expand Down
3 changes: 3 additions & 0 deletions app/views/settings/preferences/other/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
.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')

- 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

%h4= t 'preferences.dtl'
Expand Down
9 changes: 9 additions & 0 deletions config/locales/simple_form.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,15 @@ en:
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_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_hide_followers_count: Hide followers count
setting_hide_following_count: Hide following count
Expand Down
9 changes: 9 additions & 0 deletions config/locales/simple_form.ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,15 @@ ja:
setting_dtl_force_with_tag: DTL参加時の投稿設定
setting_dtl_menu: Webクライアントのメニューにディープタイムラインを追加する
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_enable_emoji_reaction: 自分の画面に絵文字リアクションを表示する
setting_expand_spoilers: 閲覧注意としてマークされた投稿を常に展開する
Expand Down

0 comments on commit 673e607

Please sign in to comment.