diff --git a/app/controllers/api/web/push_subscriptions_controller.rb b/app/controllers/api/web/push_subscriptions_controller.rb
index db2512e5f5f..5167928e932 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 9370811e0c1..00e8d74d7c5 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 ada8b6e4a83..84db044304a 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 cd471852b55..9198e9c9d88 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 5146abe98a3..39639f3dce8 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 807a1bcb942..7d713cd3786 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 c14eb8a7eb7..9bf296386af 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 e1a1b98c323..70e7cc57016 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 ab80a7e4ba9..b1f9fd755a8 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 2dc6f880bfc..7f879b1aa35 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 cf4c2cc37ea..c206c893b7d 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}