From 7b816eb5aeeed61fa1e3a7c95cbb5bb7978f7fa5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 23 Feb 2022 16:45:22 +0100 Subject: [PATCH] Add notifications for new sign-ups (#16953) --- .../api/web/push_subscriptions_controller.rb | 23 +--------- .../mastodon/actions/notifications.js | 3 +- .../components/column_settings.js | 16 ++++++- .../notifications/components/notification.js | 25 +++++++++++ app/javascript/mastodon/reducers/settings.js | 3 ++ .../service_worker/web_push_locales.js | 1 + app/models/notification.rb | 14 +++---- app/services/bootstrap_timeline_service.rb | 7 ++++ app/services/notify_service.rb | 42 ++++--------------- config/i18n-tasks.yml | 1 + config/locales/en.yml | 3 ++ 11 files changed, 73 insertions(+), 65 deletions(-) diff --git a/app/controllers/api/web/push_subscriptions_controller.rb b/app/controllers/api/web/push_subscriptions_controller.rb index db2512e5f5..5167928e93 100644 --- a/app/controllers/api/web/push_subscriptions_controller.rb +++ b/app/controllers/api/web/push_subscriptions_controller.rb @@ -17,17 +17,7 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController data = { policy: 'all', - - alerts: { - follow: alerts_enabled, - follow_request: alerts_enabled, - favourite: alerts_enabled, - reblog: alerts_enabled, - mention: alerts_enabled, - poll: alerts_enabled, - status: alerts_enabled, - update: alerts_enabled, - }, + alerts: Notification::TYPES.index_with { alerts_enabled }, } data.deep_merge!(data_params) if params[:data] @@ -62,15 +52,6 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController end def data_params - @data_params ||= params.require(:data).permit(:policy, alerts: [ - :follow, - :follow_request, - :favourite, - :reblog, - :mention, - :poll, - :status, - :update, - ]) + @data_params ||= params.require(:data).permit(:policy, alerts: Notification::TYPES) end end diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js index 9370811e0c..00e8d74d7c 100644 --- a/app/javascript/mastodon/actions/notifications.js +++ b/app/javascript/mastodon/actions/notifications.js @@ -45,7 +45,7 @@ defineMessages({ }); const fetchRelatedRelationships = (dispatch, notifications) => { - const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id); + const accountIds = notifications.filter(item => ['follow', 'follow_request', 'admin.sign_up'].indexOf(item.type) !== -1).map(item => item.account.id); if (accountIds.length > 0) { dispatch(fetchRelationships(accountIds)); @@ -132,6 +132,7 @@ const excludeTypesFromFilter = filter => { 'poll', 'status', 'update', + 'admin.sign_up', ]); return allTypes.filterNot(item => item === filter).toJS(); diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js index ada8b6e4a8..84db044304 100644 --- a/app/javascript/mastodon/features/notifications/components/column_settings.js +++ b/app/javascript/mastodon/features/notifications/components/column_settings.js @@ -5,6 +5,7 @@ import { FormattedMessage } from 'react-intl'; import ClearColumnButton from './clear_column_button'; import GrantPermissionButton from './grant_permission_button'; import SettingToggle from './setting_toggle'; +import { isStaff } from 'mastodon/initial_state'; export default class ColumnSettings extends React.PureComponent { @@ -155,7 +156,7 @@ export default class ColumnSettings extends React.PureComponent {
- +
@@ -164,6 +165,19 @@ export default class ColumnSettings extends React.PureComponent {
+ + {isStaff && ( +
+ + +
+ + {showPushSettings && } + + +
+
+ )} ); } diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js index cd471852b5..9198e9c9d8 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.js +++ b/app/javascript/mastodon/features/notifications/components/notification.js @@ -20,6 +20,7 @@ const messages = defineMessages({ reblog: { id: 'notification.reblog', defaultMessage: '{name} boosted your status' }, status: { id: 'notification.status', defaultMessage: '{name} just posted' }, update: { id: 'notification.update', defaultMessage: '{name} edited a post' }, + adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' }, }); const notificationForScreenReader = (intl, message, timestamp) => { @@ -344,6 +345,28 @@ class Notification extends ImmutablePureComponent { ); } + renderAdminSignUp (notification, account, link) { + const { intl, unread } = this.props; + + return ( + +
+
+
+ +
+ + + + +
+ +
+
+ ); + } + render () { const { notification } = this.props; const account = notification.get('account'); @@ -367,6 +390,8 @@ class Notification extends ImmutablePureComponent { return this.renderUpdate(notification, link); case 'poll': return this.renderPoll(notification, account); + case 'admin.sign_up': + return this.renderAdminSignUp(notification, account, link); } return null; diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js index 5146abe98a..39639f3dce 100644 --- a/app/javascript/mastodon/reducers/settings.js +++ b/app/javascript/mastodon/reducers/settings.js @@ -37,6 +37,7 @@ const initialState = ImmutableMap({ poll: false, status: false, update: false, + 'admin.sign_up': false, }), quickFilter: ImmutableMap({ @@ -57,6 +58,7 @@ const initialState = ImmutableMap({ poll: true, status: true, update: true, + 'admin.sign_up': true, }), sounds: ImmutableMap({ @@ -68,6 +70,7 @@ const initialState = ImmutableMap({ poll: true, status: true, update: true, + 'admin.sign_up': true, }), }), diff --git a/app/javascript/mastodon/service_worker/web_push_locales.js b/app/javascript/mastodon/service_worker/web_push_locales.js index 807a1bcb94..7d713cd378 100644 --- a/app/javascript/mastodon/service_worker/web_push_locales.js +++ b/app/javascript/mastodon/service_worker/web_push_locales.js @@ -22,6 +22,7 @@ filenames.forEach(filename => { 'notification.poll': full['notification.poll'] || '', 'notification.status': full['notification.status'] || '', 'notification.update': full['notification.update'] || '', + 'notification.admin.sign_up': full['notification.admin.sign_up'] || '', 'status.show_more': full['status.show_more'] || '', 'status.reblog': full['status.reblog'] || '', diff --git a/app/models/notification.rb b/app/models/notification.rb index c14eb8a7eb..9bf296386a 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -36,6 +36,7 @@ class Notification < ApplicationRecord favourite poll update + admin.sign_up ).freeze TARGET_STATUS_INCLUDES_BY_TYPE = { @@ -63,13 +64,10 @@ class Notification < ApplicationRecord scope :without_suspended, -> { joins(:from_account).merge(Account.without_suspended) } scope :browserable, ->(exclude_types = [], account_id = nil) { - types = TYPES - exclude_types.map(&:to_sym) - - if account_id.nil? - where(type: types) - else - where(type: types, from_account_id: account_id) - end + scope = all + scope = where(from_account_id: account_id) if account_id.present? + scope = scope.where(type: TYPES - exclude_types.map(&:to_sym)) unless exclude_types.empty? + scope } def type @@ -142,6 +140,8 @@ class Notification < ApplicationRecord self.from_account_id = activity&.account_id when 'Mention' self.from_account_id = activity&.status&.account_id + when 'Account' + self.from_account_id = activity&.id end end end diff --git a/app/services/bootstrap_timeline_service.rb b/app/services/bootstrap_timeline_service.rb index e1a1b98c32..70e7cc5701 100644 --- a/app/services/bootstrap_timeline_service.rb +++ b/app/services/bootstrap_timeline_service.rb @@ -5,6 +5,7 @@ class BootstrapTimelineService < BaseService @source_account = source_account autofollow_inviter! + notify_staff! end private @@ -14,4 +15,10 @@ class BootstrapTimelineService < BaseService FollowService.new.call(@source_account, @source_account.user.invite.user.account) end + + def notify_staff! + User.staff.includes(:account).find_each do |user| + NotifyService.new.call(user.account, :'admin.new_user', @source_account) + end + end end diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index ab80a7e4ba..b1f9fd755a 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -22,34 +22,6 @@ class NotifyService < BaseService FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient) end - def blocked_status? - false - end - - def blocked_favourite? - false - end - - def blocked_follow? - false - end - - def blocked_reblog? - false - end - - def blocked_follow_request? - false - end - - def blocked_poll? - false - end - - def blocked_update? - false - end - def following_sender? return @following_sender if defined?(@following_sender) @following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account) @@ -149,15 +121,15 @@ class NotifyService < BaseService return blocked if message? && from_staff? - blocked ||= domain_blocking? # Skip for domain blocked accounts - blocked ||= @recipient.blocking?(@notification.from_account) # Skip for blocked accounts + blocked ||= domain_blocking? + blocked ||= @recipient.blocking?(@notification.from_account) blocked ||= @recipient.muting_notifications?(@notification.from_account) - blocked ||= hellbanned? # Hellban - blocked ||= optional_non_follower? # Options - blocked ||= optional_non_following? # Options - blocked ||= optional_non_following_and_direct? # Options + blocked ||= hellbanned? + blocked ||= optional_non_follower? + blocked ||= optional_non_following? + blocked ||= optional_non_following_and_direct? blocked ||= conversation_muted? - blocked ||= send("blocked_#{@notification.type}?") # Type-dependent filters + blocked ||= blocked_mention? if @notification.type == :mention blocked end diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 2dc6f880bf..7f879b1aa3 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -61,6 +61,7 @@ ignore_unused: - 'admin.action_logs.actions.*' - 'statuses.attached.*' - 'move_handler.carry_{mutes,blocks}_over_text' + - 'notification_mailer.*' ignore_inconsistent_interpolations: - '*.one' diff --git a/config/locales/en.yml b/config/locales/en.yml index cf4c2cc37e..c206c893b7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1176,6 +1176,9 @@ en: carry_mutes_over_text: This user moved from %{acct}, which you had muted. copy_account_note_text: 'This user moved from %{acct}, here were your previous notes about them:' notification_mailer: + admin: + sign_up: + subject: "%{name} signed up" digest: action: View all notifications body: Here is a brief summary of the messages you missed since your last visit on %{since}