mirror of
https://github.com/mastodon/mastodon.git
synced 2024-11-22 06:06:45 +00:00
WIP: Notifications for Report Notes
This commit is contained in:
parent
2526b32ad3
commit
0b1710f6ba
|
@ -19,6 +19,14 @@ module Admin
|
||||||
log_action :reopen, @report
|
log_action :reopen, @report
|
||||||
end
|
end
|
||||||
|
|
||||||
|
User.those_who_can(:manage_reports).includes(:account).find_each do |u|
|
||||||
|
# Prevent notifications to the author of the report note:
|
||||||
|
next if @report_note.account.id == u.account.id
|
||||||
|
|
||||||
|
LocalNotificationWorker.perform_async(u.account_id, @report_note.id, 'ReportNote', 'admin.report_note')
|
||||||
|
AdminMailer.with(recipient: u.account).new_report_note(@report_note).deliver_later if u.allows_report_emails?
|
||||||
|
end
|
||||||
|
|
||||||
redirect_to after_create_redirect_path, notice: I18n.t('admin.report_notes.created_msg')
|
redirect_to after_create_redirect_path, notice: I18n.t('admin.report_notes.created_msg')
|
||||||
else
|
else
|
||||||
@report_notes = @report.notes.chronological.includes(:account)
|
@report_notes = @report.notes.chronological.includes(:account)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import type { AccountWarningAction } from 'mastodon/models/notification_group';
|
import type { AccountWarningAction } from 'mastodon/models/notification_group';
|
||||||
|
|
||||||
import type { ApiAccountJSON } from './accounts';
|
import type { ApiAccountJSON } from './accounts';
|
||||||
import type { ApiReportJSON } from './reports';
|
import type { ApiReportJSON, ApiReportNoteJSON } from './reports';
|
||||||
import type { ApiStatusJSON } from './statuses';
|
import type { ApiStatusJSON } from './statuses';
|
||||||
|
|
||||||
// See app/model/notification.rb
|
// See app/model/notification.rb
|
||||||
|
@ -18,6 +18,7 @@ export const allNotificationTypes = [
|
||||||
'update',
|
'update',
|
||||||
'admin.sign_up',
|
'admin.sign_up',
|
||||||
'admin.report',
|
'admin.report',
|
||||||
|
'admin.report_note',
|
||||||
'moderation_warning',
|
'moderation_warning',
|
||||||
'severed_relationships',
|
'severed_relationships',
|
||||||
'annual_report',
|
'annual_report',
|
||||||
|
@ -39,6 +40,7 @@ export type NotificationType =
|
||||||
| 'severed_relationships'
|
| 'severed_relationships'
|
||||||
| 'admin.sign_up'
|
| 'admin.sign_up'
|
||||||
| 'admin.report'
|
| 'admin.report'
|
||||||
|
| 'admin.report_note'
|
||||||
| 'annual_report';
|
| 'annual_report';
|
||||||
|
|
||||||
export interface BaseNotificationJSON {
|
export interface BaseNotificationJSON {
|
||||||
|
@ -80,6 +82,16 @@ interface ReportNotificationJSON extends BaseNotificationJSON {
|
||||||
report: ApiReportJSON;
|
report: ApiReportJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ReportNoteNotificationGroupJSON extends BaseNotificationGroupJSON {
|
||||||
|
type: 'admin.report_note';
|
||||||
|
report_note: ApiReportNoteJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ReportNoteNotificationJSON extends BaseNotificationJSON {
|
||||||
|
type: 'admin.report_note';
|
||||||
|
report_note: ApiReportNoteJSON;
|
||||||
|
}
|
||||||
|
|
||||||
type SimpleNotificationTypes = 'follow' | 'follow_request' | 'admin.sign_up';
|
type SimpleNotificationTypes = 'follow' | 'follow_request' | 'admin.sign_up';
|
||||||
interface SimpleNotificationGroupJSON extends BaseNotificationGroupJSON {
|
interface SimpleNotificationGroupJSON extends BaseNotificationGroupJSON {
|
||||||
type: SimpleNotificationTypes;
|
type: SimpleNotificationTypes;
|
||||||
|
@ -144,6 +156,7 @@ interface AnnualReportNotificationGroupJSON extends BaseNotificationGroupJSON {
|
||||||
export type ApiNotificationJSON =
|
export type ApiNotificationJSON =
|
||||||
| SimpleNotificationJSON
|
| SimpleNotificationJSON
|
||||||
| ReportNotificationJSON
|
| ReportNotificationJSON
|
||||||
|
| ReportNoteNotificationJSON
|
||||||
| AccountRelationshipSeveranceNotificationJSON
|
| AccountRelationshipSeveranceNotificationJSON
|
||||||
| NotificationWithStatusJSON
|
| NotificationWithStatusJSON
|
||||||
| ModerationWarningNotificationJSON;
|
| ModerationWarningNotificationJSON;
|
||||||
|
@ -151,6 +164,7 @@ export type ApiNotificationJSON =
|
||||||
export type ApiNotificationGroupJSON =
|
export type ApiNotificationGroupJSON =
|
||||||
| SimpleNotificationGroupJSON
|
| SimpleNotificationGroupJSON
|
||||||
| ReportNotificationGroupJSON
|
| ReportNotificationGroupJSON
|
||||||
|
| ReportNoteNotificationGroupJSON
|
||||||
| AccountRelationshipSeveranceNotificationGroupJSON
|
| AccountRelationshipSeveranceNotificationGroupJSON
|
||||||
| NotificationGroupWithStatusJSON
|
| NotificationGroupWithStatusJSON
|
||||||
| ModerationWarningNotificationGroupJSON
|
| ModerationWarningNotificationGroupJSON
|
||||||
|
|
|
@ -14,3 +14,10 @@ export interface ApiReportJSON {
|
||||||
rule_ids: string[];
|
rule_ids: string[];
|
||||||
target_account: ApiAccountJSON;
|
target_account: ApiAccountJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiReportNoteJSON {
|
||||||
|
id: string;
|
||||||
|
content: string;
|
||||||
|
created_at: string;
|
||||||
|
report: ApiReportJSON;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react';
|
||||||
|
import { Icon } from 'mastodon/components/icon';
|
||||||
|
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
|
||||||
|
import type { NotificationGroupAdminReportNote } from 'mastodon/models/notification_group';
|
||||||
|
import { useAppSelector } from 'mastodon/store';
|
||||||
|
|
||||||
|
export const NotificationAdminReportNote: React.FC<{
|
||||||
|
notification: NotificationGroupAdminReportNote;
|
||||||
|
unread?: boolean;
|
||||||
|
}> = ({ notification, notification: { reportNote }, unread }) => {
|
||||||
|
const account = useAppSelector((state) =>
|
||||||
|
state.accounts.get(notification.sampleAccountIds[0] ?? '0'),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!account) return null;
|
||||||
|
|
||||||
|
const domain = account.acct.split('@')[1];
|
||||||
|
|
||||||
|
const values = {
|
||||||
|
name: <bdi>{domain ?? `@${account.acct}`}</bdi>,
|
||||||
|
reportId: reportNote.report.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='notification.admin.report_note'
|
||||||
|
defaultMessage='{name} added a report note to Report #{reportId}'
|
||||||
|
values={values}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href={`/admin/reports/${reportNote.report.id}#report_note_${reportNote.id}`}
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
className={classNames(
|
||||||
|
'notification-group notification-group--link notification-group--admin-report focusable',
|
||||||
|
{ 'notification-group--unread': unread },
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className='notification-group__icon'>
|
||||||
|
<Icon id='flag' icon={FlagIcon} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='notification-group__main'>
|
||||||
|
<div className='notification-group__main__header'>
|
||||||
|
<div className='notification-group__main__header__label'>
|
||||||
|
{message}
|
||||||
|
<RelativeTimestamp timestamp={reportNote.created_at} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{reportNote.content.length > 0 && (
|
||||||
|
<div className='notification-group__embedded-status__content'>
|
||||||
|
“{reportNote.content}”
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
};
|
|
@ -8,6 +8,7 @@ import type { NotificationGroup as NotificationGroupModel } from 'mastodon/model
|
||||||
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
import { NotificationAdminReport } from './notification_admin_report';
|
import { NotificationAdminReport } from './notification_admin_report';
|
||||||
|
import { NotificationAdminReportNote } from './notification_admin_report_note';
|
||||||
import { NotificationAdminSignUp } from './notification_admin_sign_up';
|
import { NotificationAdminSignUp } from './notification_admin_sign_up';
|
||||||
import { NotificationAnnualReport } from './notification_annual_report';
|
import { NotificationAnnualReport } from './notification_annual_report';
|
||||||
import { NotificationFavourite } from './notification_favourite';
|
import { NotificationFavourite } from './notification_favourite';
|
||||||
|
@ -136,6 +137,14 @@ export const NotificationGroup: React.FC<{
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case 'admin.report_note':
|
||||||
|
content = (
|
||||||
|
<NotificationAdminReportNote
|
||||||
|
unread={unread}
|
||||||
|
notification={notificationGroup}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
break;
|
||||||
case 'moderation_warning':
|
case 'moderation_warning':
|
||||||
content = (
|
content = (
|
||||||
<NotificationModerationWarning
|
<NotificationModerationWarning
|
||||||
|
|
|
@ -8,7 +8,10 @@ import type {
|
||||||
NotificationType,
|
NotificationType,
|
||||||
NotificationWithStatusType,
|
NotificationWithStatusType,
|
||||||
} from 'mastodon/api_types/notifications';
|
} from 'mastodon/api_types/notifications';
|
||||||
import type { ApiReportJSON } from 'mastodon/api_types/reports';
|
import type {
|
||||||
|
ApiReportJSON,
|
||||||
|
ApiReportNoteJSON,
|
||||||
|
} from 'mastodon/api_types/reports';
|
||||||
|
|
||||||
// Maximum number of avatars displayed in a notification group
|
// Maximum number of avatars displayed in a notification group
|
||||||
// This corresponds to the max lenght of `group.sampleAccountIds`
|
// This corresponds to the max lenght of `group.sampleAccountIds`
|
||||||
|
@ -81,6 +84,14 @@ export interface NotificationGroupAdminReport
|
||||||
report: Report;
|
report: Report;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ReportNote extends Omit<ApiReportNoteJSON, 'report'> {
|
||||||
|
report: Report;
|
||||||
|
}
|
||||||
|
export interface NotificationGroupAdminReportNote
|
||||||
|
extends BaseNotification<'admin.report_note'> {
|
||||||
|
reportNote: ReportNote;
|
||||||
|
}
|
||||||
|
|
||||||
export type NotificationGroup =
|
export type NotificationGroup =
|
||||||
| NotificationGroupFavourite
|
| NotificationGroupFavourite
|
||||||
| NotificationGroupReblog
|
| NotificationGroupReblog
|
||||||
|
@ -94,6 +105,7 @@ export type NotificationGroup =
|
||||||
| NotificationGroupSeveredRelationships
|
| NotificationGroupSeveredRelationships
|
||||||
| NotificationGroupAdminSignUp
|
| NotificationGroupAdminSignUp
|
||||||
| NotificationGroupAdminReport
|
| NotificationGroupAdminReport
|
||||||
|
| NotificationGroupAdminReportNote
|
||||||
| NotificationGroupAnnualReport;
|
| NotificationGroupAnnualReport;
|
||||||
|
|
||||||
function createReportFromJSON(reportJSON: ApiReportJSON): Report {
|
function createReportFromJSON(reportJSON: ApiReportJSON): Report {
|
||||||
|
@ -104,6 +116,16 @@ function createReportFromJSON(reportJSON: ApiReportJSON): Report {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createReportNoteFromJSON(
|
||||||
|
reportNoteJSON: ApiReportNoteJSON,
|
||||||
|
): ReportNote {
|
||||||
|
const { report, ...reportNote } = reportNoteJSON;
|
||||||
|
return {
|
||||||
|
report: createReportFromJSON(report),
|
||||||
|
...reportNote,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function createAccountWarningFromJSON(
|
function createAccountWarningFromJSON(
|
||||||
warningJSON: ApiAccountWarningJSON,
|
warningJSON: ApiAccountWarningJSON,
|
||||||
): AccountWarning {
|
): AccountWarning {
|
||||||
|
@ -153,6 +175,14 @@ export function createNotificationGroupFromJSON(
|
||||||
...groupWithoutTargetAccount,
|
...groupWithoutTargetAccount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case 'admin.report_note': {
|
||||||
|
const { report_note, ...groupWithoutReportNote } = group;
|
||||||
|
return {
|
||||||
|
reportNote: createReportNoteFromJSON(report_note),
|
||||||
|
sampleAccountIds,
|
||||||
|
...groupWithoutReportNote,
|
||||||
|
};
|
||||||
|
}
|
||||||
case 'severed_relationships':
|
case 'severed_relationships':
|
||||||
return {
|
return {
|
||||||
...group,
|
...group,
|
||||||
|
@ -207,6 +237,11 @@ export function createNotificationGroupFromNotificationJSON(
|
||||||
return { ...group, statusId: notification.status?.id };
|
return { ...group, statusId: notification.status?.id };
|
||||||
case 'admin.report':
|
case 'admin.report':
|
||||||
return { ...group, report: createReportFromJSON(notification.report) };
|
return { ...group, report: createReportFromJSON(notification.report) };
|
||||||
|
case 'admin.report_note':
|
||||||
|
return {
|
||||||
|
...group,
|
||||||
|
reportNote: createReportNoteFromJSON(notification.report_note),
|
||||||
|
};
|
||||||
case 'severed_relationships':
|
case 'severed_relationships':
|
||||||
return {
|
return {
|
||||||
...group,
|
...group,
|
||||||
|
|
|
@ -56,6 +56,7 @@ export const notificationToMap = notification => ImmutableMap({
|
||||||
created_at: notification.created_at,
|
created_at: notification.created_at,
|
||||||
status: notification.status ? notification.status.id : null,
|
status: notification.status ? notification.status.id : null,
|
||||||
report: notification.report ? fromJS(notification.report) : null,
|
report: notification.report ? fromJS(notification.report) : null,
|
||||||
|
report_note: notification.report_note ? fromJS(notification.report_note) : null,
|
||||||
event: notification.event ? fromJS(notification.event) : null,
|
event: notification.event ? fromJS(notification.event) : null,
|
||||||
moderation_warning: notification.moderation_warning ? fromJS(notification.moderation_warning) : null,
|
moderation_warning: notification.moderation_warning ? fromJS(notification.moderation_warning) : null,
|
||||||
});
|
});
|
||||||
|
|
|
@ -41,6 +41,7 @@ const initialState = ImmutableMap({
|
||||||
update: false,
|
update: false,
|
||||||
'admin.sign_up': false,
|
'admin.sign_up': false,
|
||||||
'admin.report': false,
|
'admin.report': false,
|
||||||
|
'admin.report_note': false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
quickFilter: ImmutableMap({
|
quickFilter: ImmutableMap({
|
||||||
|
@ -64,6 +65,7 @@ const initialState = ImmutableMap({
|
||||||
update: true,
|
update: true,
|
||||||
'admin.sign_up': true,
|
'admin.sign_up': true,
|
||||||
'admin.report': true,
|
'admin.report': true,
|
||||||
|
'admin.report_note': true,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
sounds: ImmutableMap({
|
sounds: ImmutableMap({
|
||||||
|
@ -77,6 +79,7 @@ const initialState = ImmutableMap({
|
||||||
update: true,
|
update: true,
|
||||||
'admin.sign_up': true,
|
'admin.sign_up': true,
|
||||||
'admin.report': true,
|
'admin.report': true,
|
||||||
|
'admin.report_note': true,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
group: ImmutableMap({
|
group: ImmutableMap({
|
||||||
|
|
|
@ -21,6 +21,14 @@ class AdminMailer < ApplicationMailer
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def new_report_note(report_note)
|
||||||
|
@report_note = report_note
|
||||||
|
|
||||||
|
locale_for_account(@me) do
|
||||||
|
mail subject: default_i18n_subject(instance: @instance, id: @report_note.report.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def new_appeal(appeal)
|
def new_appeal(appeal)
|
||||||
@appeal = appeal
|
@appeal = appeal
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,9 @@ class Notification < ApplicationRecord
|
||||||
'admin.report': {
|
'admin.report': {
|
||||||
filterable: false,
|
filterable: false,
|
||||||
}.freeze,
|
}.freeze,
|
||||||
|
'admin.report_note': {
|
||||||
|
filterable: false,
|
||||||
|
}.freeze,
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
TYPES = PROPERTIES.keys.freeze
|
TYPES = PROPERTIES.keys.freeze
|
||||||
|
@ -85,6 +88,7 @@ class Notification < ApplicationRecord
|
||||||
poll: [poll: :status],
|
poll: [poll: :status],
|
||||||
update: :status,
|
update: :status,
|
||||||
'admin.report': [report: :target_account],
|
'admin.report': [report: :target_account],
|
||||||
|
'admin.report_note': [report_note: :report],
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
belongs_to :account, optional: true
|
belongs_to :account, optional: true
|
||||||
|
@ -99,6 +103,7 @@ class Notification < ApplicationRecord
|
||||||
belongs_to :favourite, inverse_of: :notification
|
belongs_to :favourite, inverse_of: :notification
|
||||||
belongs_to :poll, inverse_of: false
|
belongs_to :poll, inverse_of: false
|
||||||
belongs_to :report, inverse_of: false
|
belongs_to :report, inverse_of: false
|
||||||
|
belongs_to :report_note, inverse_of: false
|
||||||
belongs_to :account_relationship_severance_event, inverse_of: false
|
belongs_to :account_relationship_severance_event, inverse_of: false
|
||||||
belongs_to :account_warning, inverse_of: false
|
belongs_to :account_warning, inverse_of: false
|
||||||
belongs_to :generated_annual_report, inverse_of: false
|
belongs_to :generated_annual_report, inverse_of: false
|
||||||
|
@ -192,7 +197,7 @@ class Notification < ApplicationRecord
|
||||||
return unless new_record?
|
return unless new_record?
|
||||||
|
|
||||||
case activity_type
|
case activity_type
|
||||||
when 'Status', 'Follow', 'Favourite', 'FollowRequest', 'Poll', 'Report'
|
when 'Status', 'Follow', 'Favourite', 'FollowRequest', 'Poll', 'Report', 'ReportNote'
|
||||||
self.from_account_id = activity&.account_id
|
self.from_account_id = activity&.account_id
|
||||||
when 'Mention'
|
when 'Mention'
|
||||||
self.from_account_id = activity&.status&.account_id
|
self.from_account_id = activity&.status&.account_id
|
||||||
|
|
|
@ -49,6 +49,7 @@ class NotificationGroup < ActiveModelSerializers::Model
|
||||||
delegate :type,
|
delegate :type,
|
||||||
:target_status,
|
:target_status,
|
||||||
:report,
|
:report,
|
||||||
|
:report_note,
|
||||||
:account_relationship_severance_event,
|
:account_relationship_severance_event,
|
||||||
:account_warning,
|
:account_warning,
|
||||||
:generated_annual_report,
|
:generated_annual_report,
|
||||||
|
|
|
@ -11,6 +11,7 @@ class REST::NotificationGroupSerializer < ActiveModel::Serializer
|
||||||
attribute :sample_account_ids
|
attribute :sample_account_ids
|
||||||
attribute :status_id, if: :status_type?
|
attribute :status_id, if: :status_type?
|
||||||
belongs_to :report, if: :report_type?, serializer: REST::ReportSerializer
|
belongs_to :report, if: :report_type?, serializer: REST::ReportSerializer
|
||||||
|
belongs_to :report_note, if: :report_note_type?, serializer: REST::ReportNoteSerializer
|
||||||
belongs_to :account_relationship_severance_event, key: :event, if: :relationship_severance_event?, serializer: REST::AccountRelationshipSeveranceEventSerializer
|
belongs_to :account_relationship_severance_event, key: :event, if: :relationship_severance_event?, serializer: REST::AccountRelationshipSeveranceEventSerializer
|
||||||
belongs_to :account_warning, key: :moderation_warning, if: :moderation_warning_event?, serializer: REST::AccountWarningSerializer
|
belongs_to :account_warning, key: :moderation_warning, if: :moderation_warning_event?, serializer: REST::AccountWarningSerializer
|
||||||
belongs_to :generated_annual_report, key: :annual_report, if: :annual_report_event?, serializer: REST::AnnualReportEventSerializer
|
belongs_to :generated_annual_report, key: :annual_report, if: :annual_report_event?, serializer: REST::AnnualReportEventSerializer
|
||||||
|
@ -31,6 +32,10 @@ class REST::NotificationGroupSerializer < ActiveModel::Serializer
|
||||||
object.type == :'admin.report'
|
object.type == :'admin.report'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def report_note_type?
|
||||||
|
object.type == :'admin.report_note'
|
||||||
|
end
|
||||||
|
|
||||||
def relationship_severance_event?
|
def relationship_severance_event?
|
||||||
object.type == :severed_relationships
|
object.type == :severed_relationships
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,7 @@ class REST::NotificationSerializer < ActiveModel::Serializer
|
||||||
belongs_to :from_account, key: :account, serializer: REST::AccountSerializer
|
belongs_to :from_account, key: :account, serializer: REST::AccountSerializer
|
||||||
belongs_to :target_status, key: :status, if: :status_type?, serializer: REST::StatusSerializer
|
belongs_to :target_status, key: :status, if: :status_type?, serializer: REST::StatusSerializer
|
||||||
belongs_to :report, if: :report_type?, serializer: REST::ReportSerializer
|
belongs_to :report, if: :report_type?, serializer: REST::ReportSerializer
|
||||||
|
belongs_to :report_note, if: :report_note_type?, serializer: REST::ReportNoteSerializer
|
||||||
belongs_to :account_relationship_severance_event, key: :event, if: :relationship_severance_event?, serializer: REST::AccountRelationshipSeveranceEventSerializer
|
belongs_to :account_relationship_severance_event, key: :event, if: :relationship_severance_event?, serializer: REST::AccountRelationshipSeveranceEventSerializer
|
||||||
belongs_to :account_warning, key: :moderation_warning, if: :moderation_warning_event?, serializer: REST::AccountWarningSerializer
|
belongs_to :account_warning, key: :moderation_warning, if: :moderation_warning_event?, serializer: REST::AccountWarningSerializer
|
||||||
|
|
||||||
|
@ -28,6 +29,10 @@ class REST::NotificationSerializer < ActiveModel::Serializer
|
||||||
object.type == :'admin.report'
|
object.type == :'admin.report'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def report_note_type?
|
||||||
|
object.type == :'admin.report_note'
|
||||||
|
end
|
||||||
|
|
||||||
def relationship_severance_event?
|
def relationship_severance_event?
|
||||||
object.type == :severed_relationships
|
object.type == :severed_relationships
|
||||||
end
|
end
|
||||||
|
|
11
app/serializers/rest/report_note_serializer.rb
Normal file
11
app/serializers/rest/report_note_serializer.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class REST::ReportNoteSerializer < ActiveModel::Serializer
|
||||||
|
attributes :id, :content, :created_at
|
||||||
|
|
||||||
|
has_one :report, serializer: REST::ReportSerializer
|
||||||
|
|
||||||
|
def id
|
||||||
|
object.id.to_s
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,6 +6,7 @@ class NotifyService < BaseService
|
||||||
# TODO: the severed_relationships and annual_report types probably warrants email notifications
|
# TODO: the severed_relationships and annual_report types probably warrants email notifications
|
||||||
NON_EMAIL_TYPES = %i(
|
NON_EMAIL_TYPES = %i(
|
||||||
admin.report
|
admin.report
|
||||||
|
admin.report_note
|
||||||
admin.sign_up
|
admin.sign_up
|
||||||
update
|
update
|
||||||
poll
|
poll
|
||||||
|
@ -23,6 +24,7 @@ class NotifyService < BaseService
|
||||||
NON_FILTERABLE_TYPES = %i(
|
NON_FILTERABLE_TYPES = %i(
|
||||||
admin.sign_up
|
admin.sign_up
|
||||||
admin.report
|
admin.report
|
||||||
|
admin.report_note
|
||||||
poll
|
poll
|
||||||
update
|
update
|
||||||
account_warning
|
account_warning
|
||||||
|
|
5
app/views/admin_mailer/new_report_note.text.erb
Normal file
5
app/views/admin_mailer/new_report_note.text.erb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<%= raw t('admin_mailer.new_report_note.body', report_id: @report_note.report.id, account: @report_note.account.pretty_acct) %>
|
||||||
|
|
||||||
|
> <%= raw word_wrap(@report_note.content, break_sequence: "\n> ") %>
|
||||||
|
|
||||||
|
<%= raw t('application_mailer.view')%> <%= admin_report_url(@report_note.report, anchor: dom_id(@report_note)) %>
|
|
@ -1052,6 +1052,9 @@ en:
|
||||||
body: "%{reporter} has reported %{target}"
|
body: "%{reporter} has reported %{target}"
|
||||||
body_remote: Someone from %{domain} has reported %{target}
|
body_remote: Someone from %{domain} has reported %{target}
|
||||||
subject: New report for %{instance} (#%{id})
|
subject: New report for %{instance} (#%{id})
|
||||||
|
new_report_note:
|
||||||
|
body: "%{account} has added a report note to Report #%{report_id}:"
|
||||||
|
subject: "New report note for %{instance} (Report #%{id})"
|
||||||
new_software_updates:
|
new_software_updates:
|
||||||
body: New Mastodon versions have been released, you may want to update!
|
body: New Mastodon versions have been released, you may want to update!
|
||||||
subject: New Mastodon versions are available for %{instance}!
|
subject: New Mastodon versions are available for %{instance}!
|
||||||
|
|
Loading…
Reference in a new issue