cherry-pick emoji reaction changes

This commit is contained in:
fef 2022-11-29 04:31:22 +01:00 committed by Jeremy Kescher
parent c633dd7d0f
commit 4750a8005d
No known key found for this signature in database
GPG key ID: 80A419A7A613DFA4
17 changed files with 91 additions and 3 deletions

View file

@ -146,6 +146,7 @@ const excludeTypesFromFilter = filter => {
'follow', 'follow',
'follow_request', 'follow_request',
'favourite', 'favourite',
'reaction',
'reblog', 'reblog',
'mention', 'mention',
'poll', 'poll',

View file

@ -755,6 +755,7 @@ class Status extends ImmutablePureComponent {
if (this.props.prepend && account) { if (this.props.prepend && account) {
const notifKind = { const notifKind = {
favourite: 'favourited', favourite: 'favourited',
reaction: 'reacted',
reblog: 'boosted', reblog: 'boosted',
reblogged_by: 'boosted', reblogged_by: 'boosted',
status: 'posted', status: 'posted',

View file

@ -59,6 +59,14 @@ export default class StatusPrepend extends PureComponent {
values={{ name : link }} values={{ name : link }}
/> />
); );
case 'reaction':
return (
<FormattedMessage
id='notification.reaction'
defaultMessage='{name} reacted to your post'
values={{ name: link }}
/>
);
case 'reblog': case 'reblog':
return ( return (
<FormattedMessage <FormattedMessage
@ -113,6 +121,9 @@ export default class StatusPrepend extends PureComponent {
case 'favourite': case 'favourite':
iconId = 'star'; iconId = 'star';
break; break;
case 'reaction':
iconId = 'plus';
break;
case 'featured': case 'featured':
iconId = 'thumb-tack'; iconId = 'thumb-tack';
break; break;

View file

@ -18,7 +18,6 @@ export default class StatusReactionsBar extends ImmutablePureComponent {
static propTypes = { static propTypes = {
statusId: PropTypes.string.isRequired, statusId: PropTypes.string.isRequired,
reactions: ImmutablePropTypes.list.isRequired, reactions: ImmutablePropTypes.list.isRequired,
reactionLimit: PropTypes.number.isRequired,
addReaction: PropTypes.func.isRequired, addReaction: PropTypes.func.isRequired,
removeReaction: PropTypes.func.isRequired, removeReaction: PropTypes.func.isRequired,
emojiMap: ImmutablePropTypes.map.isRequired, emojiMap: ImmutablePropTypes.map.isRequired,

View file

@ -120,6 +120,17 @@ export default class ColumnSettings extends PureComponent {
</div> </div>
</div> </div>
<div role='group' aria-labelledby='notifications-reaction'>
<span id='notifications-reaction' className='column-settings__section'><FormattedMessage id='notifications.column_settings.reaction' defaultMessage='Reactions:' /></span>
<div className='column-settings__pillbar'>
<PillBarButton disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'reaction']} onChange={onChange} label={alertStr} />
{showPushSettings && <PillBarButton prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'reaction']} onChange={this.onPushChange} label={pushStr} />}
<PillBarButton prefix='notifications' settings={settings} settingPath={['shows', 'reaction']} onChange={onChange} label={showStr} />
<PillBarButton prefix='notifications' settings={settings} settingPath={['sounds', 'reaction']} onChange={onChange} label={soundStr} />
</div>
</div>
<div role='group' aria-labelledby='notifications-mention'> <div role='group' aria-labelledby='notifications-mention'>
<span id='notifications-mention' className='column-settings__section'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span> <span id='notifications-mention' className='column-settings__section'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span>

View file

@ -8,6 +8,7 @@ import { Icon } from 'flavours/glitch/components/icon';
const tooltips = defineMessages({ const tooltips = defineMessages({
mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' }, mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' },
favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favourites' }, favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favourites' },
reactions: { id: 'notifications.filter.reactions', defaultMessage: 'Reactions' },
boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' }, boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' },
polls: { id: 'notifications.filter.polls', defaultMessage: 'Poll results' }, polls: { id: 'notifications.filter.polls', defaultMessage: 'Poll results' },
follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' }, follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' },
@ -75,6 +76,13 @@ class FilterBar extends PureComponent {
> >
<Icon id='star' fixedWidth /> <Icon id='star' fixedWidth />
</button> </button>
<button
className={selectedFilter === 'reaction' ? 'active' : ''}
onClick={this.onClick('reaction')}
title={intl.formatMessage(tooltips.reactions)}
>
<Icon id='plus' fixedWidth />
</button>
<button <button
className={selectedFilter === 'reblog' ? 'active' : ''} className={selectedFilter === 'reblog' ? 'active' : ''}
onClick={this.onClick('reblog')} onClick={this.onClick('reblog')}

View file

@ -159,6 +159,28 @@ export default class Notification extends ImmutablePureComponent {
unread={this.props.unread} unread={this.props.unread}
/> />
); );
case 'reaction':
return (
<StatusContainer
containerId={notification.get('id')}
hidden={hidden}
id={notification.get('status')}
account={notification.get('account')}
prepend='reaction'
muted
notification={notification}
onMoveDown={onMoveDown}
onMoveUp={onMoveUp}
onMention={onMention}
getScrollPosition={getScrollPosition}
updateScrollBottom={updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
onUnmount={this.props.onUnmount}
withDismiss
unread={this.props.unread}
/>
);
case 'reblog': case 'reblog':
return ( return (
<StatusContainer <StatusContainer

View file

@ -61,6 +61,7 @@
"keyboard_shortcuts.bookmark": "zu Lesezeichen hinzufügen", "keyboard_shortcuts.bookmark": "zu Lesezeichen hinzufügen",
"keyboard_shortcuts.secondary_toot": "Toot mit sekundärer Privatsphäreeinstellung absenden", "keyboard_shortcuts.secondary_toot": "Toot mit sekundärer Privatsphäreeinstellung absenden",
"keyboard_shortcuts.toggle_collapse": "Toots ein-/ausklappen", "keyboard_shortcuts.toggle_collapse": "Toots ein-/ausklappen",
"tooltips.reactions": "Reaktionen",
"layout.auto": "Automatisch", "layout.auto": "Automatisch",
"layout.desktop": "Desktop", "layout.desktop": "Desktop",
"layout.hint.auto": "Automatisch das Layout anhand der Einstellung \"Erweitertes Webinterface verwenden\" und Bildschirmgröße auswählen.", "layout.hint.auto": "Automatisch das Layout anhand der Einstellung \"Erweitertes Webinterface verwenden\" und Bildschirmgröße auswählen.",
@ -74,6 +75,8 @@
"navigation_bar.keyboard_shortcuts": "Tastaturkürzel", "navigation_bar.keyboard_shortcuts": "Tastaturkürzel",
"navigation_bar.misc": "Sonstiges", "navigation_bar.misc": "Sonstiges",
"notification.markForDeletion": "Zum Entfernen auswählen", "notification.markForDeletion": "Zum Entfernen auswählen",
"notification.reaction": "{name} hat auf deinen Beitrag reagiert",
"notifications.column_settings.reaction": "Reaktionen:",
"notification_purge.btn_all": "Alle\nauswählen", "notification_purge.btn_all": "Alle\nauswählen",
"notification_purge.btn_apply": "Ausgewählte\nentfernen", "notification_purge.btn_apply": "Ausgewählte\nentfernen",
"notification_purge.btn_invert": "Auswahl\numkehren", "notification_purge.btn_invert": "Auswahl\numkehren",

View file

@ -64,6 +64,7 @@
"keyboard_shortcuts.bookmark": "to bookmark", "keyboard_shortcuts.bookmark": "to bookmark",
"keyboard_shortcuts.secondary_toot": "to send toot using secondary privacy setting", "keyboard_shortcuts.secondary_toot": "to send toot using secondary privacy setting",
"keyboard_shortcuts.toggle_collapse": "to collapse/uncollapse toots", "keyboard_shortcuts.toggle_collapse": "to collapse/uncollapse toots",
"tooltips.reactions": "Reactions",
"layout.auto": "Auto", "layout.auto": "Auto",
"layout.desktop": "Desktop", "layout.desktop": "Desktop",
"layout.hint.auto": "Automatically chose layout based on “Enable advanced web interface” setting and screen size.", "layout.hint.auto": "Automatically chose layout based on “Enable advanced web interface” setting and screen size.",
@ -77,6 +78,8 @@
"navigation_bar.keyboard_shortcuts": "Keyboard shortcuts", "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
"navigation_bar.misc": "Misc", "navigation_bar.misc": "Misc",
"notification.markForDeletion": "Mark for deletion", "notification.markForDeletion": "Mark for deletion",
"notification.reaction": "{name} reacted to your post",
"notifications.column_settings.reaction": "Reactions:",
"notification_purge.btn_all": "Select\nall", "notification_purge.btn_all": "Select\nall",
"notification_purge.btn_apply": "Clear\nselected", "notification_purge.btn_apply": "Clear\nselected",
"notification_purge.btn_invert": "Invert\nselection", "notification_purge.btn_invert": "Invert\nselection",

View file

@ -61,6 +61,7 @@
"keyboard_shortcuts.bookmark": "ajouter aux marque-pages", "keyboard_shortcuts.bookmark": "ajouter aux marque-pages",
"keyboard_shortcuts.secondary_toot": "Envoyer le post en utilisant les paramètres secondaires de confidentialité", "keyboard_shortcuts.secondary_toot": "Envoyer le post en utilisant les paramètres secondaires de confidentialité",
"keyboard_shortcuts.toggle_collapse": "Plier/déplier les posts", "keyboard_shortcuts.toggle_collapse": "Plier/déplier les posts",
"tooltips.reactions": "Réactions",
"layout.auto": "Auto", "layout.auto": "Auto",
"layout.desktop": "Ordinateur", "layout.desktop": "Ordinateur",
"layout.hint.auto": "Choisir automatiquement la mise en page selon l'option \"Activer l'interface Web avancée\" et la taille d'écran.", "layout.hint.auto": "Choisir automatiquement la mise en page selon l'option \"Activer l'interface Web avancée\" et la taille d'écran.",
@ -74,6 +75,8 @@
"navigation_bar.keyboard_shortcuts": "Raccourcis clavier", "navigation_bar.keyboard_shortcuts": "Raccourcis clavier",
"navigation_bar.misc": "Autres", "navigation_bar.misc": "Autres",
"notification.markForDeletion": "Ajouter aux éléments à supprimer", "notification.markForDeletion": "Ajouter aux éléments à supprimer",
"notification.reaction": "{name} a réagi·e à votre message",
"notifications.column_settings.reaction": "Réactions:",
"notification_purge.btn_all": "Sélectionner\ntout", "notification_purge.btn_all": "Sélectionner\ntout",
"notification_purge.btn_apply": "Effacer\nla sélection", "notification_purge.btn_apply": "Effacer\nla sélection",
"notification_purge.btn_invert": "Inverser\nla sélection", "notification_purge.btn_invert": "Inverser\nla sélection",

View file

@ -39,6 +39,7 @@ const initialState = ImmutableMap({
follow: false, follow: false,
follow_request: false, follow_request: false,
favourite: false, favourite: false,
reaction: false,
reblog: false, reblog: false,
mention: false, mention: false,
poll: false, poll: false,
@ -62,6 +63,7 @@ const initialState = ImmutableMap({
follow_request: false, follow_request: false,
favourite: true, favourite: true,
reblog: true, reblog: true,
reaction: true,
mention: true, mention: true,
poll: true, poll: true,
status: true, status: true,
@ -75,6 +77,7 @@ const initialState = ImmutableMap({
follow_request: false, follow_request: false,
favourite: true, favourite: true,
reblog: true, reblog: true,
reaction: true,
mention: true, mention: true,
poll: true, poll: true,
status: true, status: true,

View file

@ -25,6 +25,7 @@ class Notification < ApplicationRecord
'Follow' => :follow, 'Follow' => :follow,
'FollowRequest' => :follow_request, 'FollowRequest' => :follow_request,
'Favourite' => :favourite, 'Favourite' => :favourite,
'StatusReaction' => :reaction,
'Poll' => :poll, 'Poll' => :poll,
}.freeze }.freeze
@ -35,6 +36,7 @@ class Notification < ApplicationRecord
follow follow
follow_request follow_request
favourite favourite
reaction
poll poll
update update
admin.sign_up admin.sign_up
@ -46,6 +48,7 @@ class Notification < ApplicationRecord
reblog: [status: :reblog], reblog: [status: :reblog],
mention: [mention: :status], mention: [mention: :status],
favourite: [favourite: :status], favourite: [favourite: :status],
reaction: [status_reaction: :status],
poll: [poll: :status], poll: [poll: :status],
update: :status, update: :status,
'admin.report': [report: :target_account], 'admin.report': [report: :target_account],
@ -61,6 +64,7 @@ class Notification < ApplicationRecord
belongs_to :follow, inverse_of: :notification belongs_to :follow, inverse_of: :notification
belongs_to :follow_request, inverse_of: :notification belongs_to :follow_request, inverse_of: :notification
belongs_to :favourite, inverse_of: :notification belongs_to :favourite, inverse_of: :notification
belongs_to :status_reaction, 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
end end
@ -81,6 +85,8 @@ class Notification < ApplicationRecord
status&.reblog status&.reblog
when :favourite when :favourite
favourite&.status favourite&.status
when :reaction
status_reaction&.status
when :mention when :mention
mention&.status mention&.status
when :poll when :poll
@ -130,6 +136,8 @@ class Notification < ApplicationRecord
notification.status.reblog = cached_status notification.status.reblog = cached_status
when :favourite when :favourite
notification.favourite.status = cached_status notification.favourite.status = cached_status
when :reaction
notification.reaction.status = cached_status
when :mention when :mention
notification.mention.status = cached_status notification.mention.status = cached_status
when :poll when :poll
@ -141,6 +149,8 @@ class Notification < ApplicationRecord
end end
end end
alias reaction status_reaction
after_initialize :set_from_account after_initialize :set_from_account
before_validation :set_from_account before_validation :set_from_account
@ -150,7 +160,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', 'StatusReaction', 'FollowRequest', 'Poll', 'Report'
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

View file

@ -12,7 +12,7 @@ class REST::NotificationSerializer < ActiveModel::Serializer
end end
def status_type? def status_type?
[:favourite, :reblog, :status, :mention, :poll, :update].include?(object.type) [:favourite, :reaction, :reblog, :status, :mention, :poll, :update].include?(object.type)
end end
def report_type? def report_type?

View file

@ -14,6 +14,7 @@ class StatusReactionService < BaseService
json = Oj.dump(serialize_payload(reaction, ActivityPub::EmojiReactionSerializer)) json = Oj.dump(serialize_payload(reaction, ActivityPub::EmojiReactionSerializer))
if status.account.local? if status.account.local?
NotifyService.new.call(status.account, :reaction, reaction)
ActivityPub::RawDistributionWorker.perform_async(json, status.account.id) ActivityPub::RawDistributionWorker.perform_async(json, status.account.id)
else else
ActivityPub::DeliveryWorker.perform_async(json, reaction.account_id, status.account.inbox_url) ActivityPub::DeliveryWorker.perform_async(json, reaction.account_id, status.account.inbox_url)

View file

@ -1339,6 +1339,10 @@ de:
body: 'Dein Beitrag wurde von %{name} favorisiert:' body: 'Dein Beitrag wurde von %{name} favorisiert:'
subject: "%{name} favorisierte deinen Beitrag" subject: "%{name} favorisierte deinen Beitrag"
title: Neue Favorisierung title: Neue Favorisierung
reaction:
body: '%{name} hat auf deinen Beitrag reagiert:'
subject: '%{name} hat auf deinen Beitrag reagiert'
title: Neue Reaktion
follow: follow:
body: "%{name} folgt dir jetzt!" body: "%{name} folgt dir jetzt!"
subject: "%{name} folgt dir jetzt" subject: "%{name} folgt dir jetzt"

View file

@ -1433,6 +1433,10 @@ en:
title: New mention title: New mention
poll: poll:
subject: A poll by %{name} has ended subject: A poll by %{name} has ended
reaction:
body: '%{name} reacted to your post:'
subject: '%{name} reacted to your post'
title: New reaction
reblog: reblog:
body: 'Your post was boosted by %{name}:' body: 'Your post was boosted by %{name}:'
subject: "%{name} boosted your post" subject: "%{name} boosted your post"

View file

@ -1323,6 +1323,10 @@ fr:
body: "%{name} a ajouté votre message à ses favoris :" body: "%{name} a ajouté votre message à ses favoris :"
subject: "%{name} a ajouté votre message à ses favoris" subject: "%{name} a ajouté votre message à ses favoris"
title: Nouveau favori title: Nouveau favori
reaction:
body: '%{name} a réagi·e à votre message:'
subject: '%{name} a réagi·e à votre message'
title: Nouvelle réaction
follow: follow:
body: "%{name} vous suit!" body: "%{name} vous suit!"
subject: "%{name} vous suit" subject: "%{name} vous suit"