mirror of
https://github.com/mastodon/mastodon.git
synced 2025-09-05 09:21:11 +00:00
Add quoted_update
notification type (#35820)
This commit is contained in:
parent
7aba79ade9
commit
f3a932d8a1
|
@ -31,7 +31,8 @@ export type NotificationWithStatusType =
|
|||
| 'mention'
|
||||
| 'quote'
|
||||
| 'poll'
|
||||
| 'update';
|
||||
| 'update'
|
||||
| 'quoted_update';
|
||||
|
||||
export type NotificationType =
|
||||
| NotificationWithStatusType
|
||||
|
|
|
@ -38,6 +38,7 @@ const messages = defineMessages({
|
|||
reblog: { id: 'notification.reblog', defaultMessage: '{name} boosted your post' },
|
||||
status: { id: 'notification.status', defaultMessage: '{name} just posted' },
|
||||
update: { id: 'notification.update', defaultMessage: '{name} edited a post' },
|
||||
quoted_update: { id: 'notification.quoted_update', defaultMessage: '{name} edited a post you have quoted' },
|
||||
adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' },
|
||||
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
|
||||
relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' },
|
||||
|
@ -336,6 +337,41 @@ class Notification extends ImmutablePureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
renderQuotedUpdate (notification, link) {
|
||||
const { intl, unread, status } = this.props;
|
||||
|
||||
if (!status) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Hotkeys handlers={this.getHandlers()}>
|
||||
<div className={classNames('notification notification-update focusable', { unread })} tabIndex={0} aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.update, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
|
||||
<div className='notification__message'>
|
||||
<Icon id='pencil' icon={EditIcon} />
|
||||
|
||||
<span title={notification.get('created_at')}>
|
||||
<FormattedMessage id='notification.quoted_update' defaultMessage='{name} edited a post you have quoted' values={{ name: link }} />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<StatusQuoteManager
|
||||
id={notification.get('status')}
|
||||
account={notification.get('account')}
|
||||
contextType='notifications'
|
||||
muted
|
||||
withDismiss
|
||||
hidden={this.props.hidden}
|
||||
getScrollPosition={this.props.getScrollPosition}
|
||||
updateScrollBottom={this.props.updateScrollBottom}
|
||||
cachedMediaWidth={this.props.cachedMediaWidth}
|
||||
cacheMediaWidth={this.props.cacheMediaWidth}
|
||||
/>
|
||||
</div>
|
||||
</Hotkeys>
|
||||
);
|
||||
}
|
||||
|
||||
renderPoll (notification, account) {
|
||||
const { intl, unread, status } = this.props;
|
||||
const ownPoll = me === account.get('id');
|
||||
|
@ -492,6 +528,8 @@ class Notification extends ImmutablePureComponent {
|
|||
return this.renderStatus(notification, link);
|
||||
case 'update':
|
||||
return this.renderUpdate(notification, link);
|
||||
case 'quoted_update':
|
||||
return this.renderQuotedUpdate(notification, link);
|
||||
case 'poll':
|
||||
return this.renderPoll(notification, account);
|
||||
case 'severed_relationships':
|
||||
|
|
|
@ -16,6 +16,7 @@ import { NotificationMention } from './notification_mention';
|
|||
import { NotificationModerationWarning } from './notification_moderation_warning';
|
||||
import { NotificationPoll } from './notification_poll';
|
||||
import { NotificationQuote } from './notification_quote';
|
||||
import { NotificationQuotedUpdate } from './notification_quoted_update';
|
||||
import { NotificationReblog } from './notification_reblog';
|
||||
import { NotificationSeveredRelationships } from './notification_severed_relationships';
|
||||
import { NotificationStatus } from './notification_status';
|
||||
|
@ -115,6 +116,14 @@ export const NotificationGroup: React.FC<{
|
|||
<NotificationUpdate unread={unread} notification={notificationGroup} />
|
||||
);
|
||||
break;
|
||||
case 'quoted_update':
|
||||
content = (
|
||||
<NotificationQuotedUpdate
|
||||
unread={unread}
|
||||
notification={notificationGroup}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case 'admin.sign_up':
|
||||
content = (
|
||||
<NotificationAdminSignUp
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
||||
import type { NotificationGroupQuotedUpdate } from 'mastodon/models/notification_group';
|
||||
|
||||
import type { LabelRenderer } from './notification_group_with_status';
|
||||
import { NotificationWithStatus } from './notification_with_status';
|
||||
|
||||
const labelRenderer: LabelRenderer = (displayedName) => (
|
||||
<FormattedMessage
|
||||
id='notification.quoted_update'
|
||||
defaultMessage='{name} edited a post you have quoted'
|
||||
values={{ name: displayedName }}
|
||||
/>
|
||||
);
|
||||
|
||||
export const NotificationQuotedUpdate: React.FC<{
|
||||
notification: NotificationGroupQuotedUpdate;
|
||||
unread: boolean;
|
||||
}> = ({ notification, unread }) => (
|
||||
<NotificationWithStatus
|
||||
type='update'
|
||||
icon={EditIcon}
|
||||
iconId='edit'
|
||||
accountIds={notification.sampleAccountIds}
|
||||
count={notification.notifications_count}
|
||||
statusId={notification.statusId}
|
||||
labelRenderer={labelRenderer}
|
||||
unread={unread}
|
||||
/>
|
||||
);
|
|
@ -620,6 +620,7 @@
|
|||
"notification.moderation_warning.action_suspend": "Your account has been suspended.",
|
||||
"notification.own_poll": "Your poll has ended",
|
||||
"notification.poll": "A poll you voted in has ended",
|
||||
"notification.quoted_update": "{name} edited a post you have quoted",
|
||||
"notification.reblog": "{name} boosted your post",
|
||||
"notification.reblog.name_and_others_with_link": "{name} and <a>{count, plural, one {# other} other {# others}}</a> boosted your post",
|
||||
"notification.relationships_severance_event": "Lost connections with {name}",
|
||||
|
|
|
@ -39,6 +39,8 @@ export type NotificationGroupMention = BaseNotificationWithStatus<'mention'>;
|
|||
export type NotificationGroupQuote = BaseNotificationWithStatus<'quote'>;
|
||||
export type NotificationGroupPoll = BaseNotificationWithStatus<'poll'>;
|
||||
export type NotificationGroupUpdate = BaseNotificationWithStatus<'update'>;
|
||||
export type NotificationGroupQuotedUpdate =
|
||||
BaseNotificationWithStatus<'quoted_update'>;
|
||||
export type NotificationGroupFollow = BaseNotification<'follow'>;
|
||||
export type NotificationGroupFollowRequest = BaseNotification<'follow_request'>;
|
||||
export type NotificationGroupAdminSignUp = BaseNotification<'admin.sign_up'>;
|
||||
|
@ -91,6 +93,7 @@ export type NotificationGroup =
|
|||
| NotificationGroupQuote
|
||||
| NotificationGroupPoll
|
||||
| NotificationGroupUpdate
|
||||
| NotificationGroupQuotedUpdate
|
||||
| NotificationGroupFollow
|
||||
| NotificationGroupFollowRequest
|
||||
| NotificationGroupModerationWarning
|
||||
|
@ -141,7 +144,8 @@ export function createNotificationGroupFromJSON(
|
|||
case 'mention':
|
||||
case 'quote':
|
||||
case 'poll':
|
||||
case 'update': {
|
||||
case 'update':
|
||||
case 'quoted_update': {
|
||||
const { status_id: statusId, ...groupWithoutStatus } = group;
|
||||
return {
|
||||
statusId: statusId ?? undefined,
|
||||
|
@ -215,6 +219,7 @@ export function createNotificationGroupFromNotificationJSON(
|
|||
case 'quote':
|
||||
case 'poll':
|
||||
case 'update':
|
||||
case 'quoted_update':
|
||||
return {
|
||||
...group,
|
||||
type: notification.type,
|
||||
|
|
|
@ -77,6 +77,9 @@ class Notification < ApplicationRecord
|
|||
quote: {
|
||||
filterable: true,
|
||||
}.freeze,
|
||||
quoted_update: {
|
||||
filterable: false,
|
||||
}.freeze,
|
||||
}.freeze
|
||||
|
||||
TYPES = PROPERTIES.keys.freeze
|
||||
|
@ -89,6 +92,7 @@ class Notification < ApplicationRecord
|
|||
favourite: [favourite: :status],
|
||||
poll: [poll: :status],
|
||||
update: :status,
|
||||
quoted_update: :status,
|
||||
'admin.report': [report: :target_account],
|
||||
}.freeze
|
||||
|
||||
|
@ -120,7 +124,7 @@ class Notification < ApplicationRecord
|
|||
|
||||
def target_status
|
||||
case type
|
||||
when :status, :update
|
||||
when :status, :update, :quoted_update
|
||||
status
|
||||
when :reblog
|
||||
status&.reblog
|
||||
|
@ -172,7 +176,7 @@ class Notification < ApplicationRecord
|
|||
cached_status = cached_statuses_by_id[notification.target_status.id]
|
||||
|
||||
case notification.type
|
||||
when :status, :update
|
||||
when :status, :update, :quoted_update
|
||||
notification.status = cached_status
|
||||
when :reblog
|
||||
notification.status.reblog = cached_status
|
||||
|
@ -202,7 +206,9 @@ class Notification < ApplicationRecord
|
|||
return unless new_record?
|
||||
|
||||
case activity_type
|
||||
when 'Status', 'Follow', 'Favourite', 'FollowRequest', 'Poll', 'Report', 'Quote'
|
||||
when 'Status'
|
||||
self.from_account_id = type == :quoted_update ? activity&.quote&.quoted_account_id : activity&.account_id
|
||||
when 'Follow', 'Favourite', 'FollowRequest', 'Poll', 'Report', 'Quote'
|
||||
self.from_account_id = activity&.account_id
|
||||
when 'Mention'
|
||||
self.from_account_id = activity&.status&.account_id
|
||||
|
|
|
@ -24,7 +24,7 @@ class REST::NotificationGroupSerializer < ActiveModel::Serializer
|
|||
end
|
||||
|
||||
def status_type?
|
||||
[:favourite, :reblog, :status, :mention, :poll, :update, :quote].include?(object.type)
|
||||
[:favourite, :reblog, :status, :mention, :poll, :update, :quote, :quoted_update].include?(object.type)
|
||||
end
|
||||
|
||||
def report_type?
|
||||
|
|
|
@ -99,6 +99,12 @@ class FanOutOnWriteService < BaseService
|
|||
[account.id, @status.id, 'Status', 'update']
|
||||
end
|
||||
end
|
||||
|
||||
@status.quotes.accepted.find_in_batches do |quotes|
|
||||
LocalNotificationWorker.push_bulk(quotes) do |quote|
|
||||
[quote.account_id, quote.status_id, 'Status', 'quoted_update']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def deliver_to_all_followers!
|
||||
|
|
|
@ -8,6 +8,7 @@ class NotifyService < BaseService
|
|||
admin.report
|
||||
admin.sign_up
|
||||
update
|
||||
quoted_update
|
||||
poll
|
||||
status
|
||||
moderation_warning
|
||||
|
|
|
@ -17,6 +17,8 @@ class LocalNotificationWorker
|
|||
# should replace the previous ones.
|
||||
if type == 'update'
|
||||
Notification.where(account: receiver, activity: activity, type: 'update').in_batches.delete_all
|
||||
elsif type == 'quoted_update'
|
||||
Notification.where(account: receiver, activity: activity, type: 'quoted_update').in_batches.delete_all
|
||||
elsif Notification.where(account: receiver, activity: activity, type: type).any?
|
||||
return
|
||||
end
|
||||
|
|
|
@ -69,6 +69,17 @@ RSpec.describe Notification do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when the notification is a quoted post update notification' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
status = Fabricate(:status)
|
||||
quote = Fabricate(:quote, quoted_status: status)
|
||||
|
||||
notification = Fabricate.build(:notification, activity_type: 'Status', type: 'quoted_update', activity: quote.status)
|
||||
|
||||
expect(notification.from_account).to eq(status.account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when activity_type is a Follow' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
follow = Fabricate(:follow)
|
||||
|
|
Loading…
Reference in New Issue
Block a user