P6: emoji reactions in and out
Build / Build (push) Successful in 35s
Deploy / privapub.thepra.dev (push) Successful in 57s

- Incoming reactions in all three shapes: Misskey and Sharkey Likes carrying an emoji (`content` or
  `_misskey_reaction`), Pleroma, Akkoma and Iceshrimp.NET EmojiReacts, and their Undo. Unicode reactions are one
  grapheme; custom ones need their Emoji tag and keep its image; `:name@host:` is read as `name`. A Like whose
  content is a heart stays a favourite.
- Reactions are kept per account and emoji on our posts and on remote ones we hold, and the author of a local post
  gets a `pleroma:emoji_reaction` notification with the emoji.
- Personas react through Pleroma's API (PUT/DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji, GET for the list),
  which sends an EmojiReact (or its Undo) to the post's author.
- Statuses carry `emoji_reactions` (read by Phanpy) and `pleroma.emoji_reactions`, with counts and whether the viewer
  reacted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-01 18:39:18 +02:00
1 parent 7be6749a23
commit fdcf5176bc
19 files changed
+507 -12

No files matched your search

+4 -2
View File
@@ -8,7 +8,7 @@ namespace PrivaPub.Domain.Social
public static class Notifications
{
public static async Task Add(string avatarId, NotificationType type, string fromAccountId, string fromActorUri, string postId,
CancellationToken token)
CancellationToken token, string emoji = default, string emojiUrl = default)
{
if (string.IsNullOrEmpty(avatarId) || avatarId == fromAccountId && type != NotificationType.Poll)
return;
@@ -23,7 +23,9 @@ namespace PrivaPub.Domain.Social
FromAccountId = fromAccountId,
FromActorURI = fromActorUri,
PostId = postId,
DedupeKey = $"{type}|{avatarId}|{fromActorUri}|{postId}"
Emoji = emoji,
EmojiURL = emojiUrl,
DedupeKey = emoji == default ? $"{type}|{avatarId}|{fromActorUri}|{postId}" : $"{type}|{avatarId}|{fromActorUri}|{postId}|{emoji}"
}, token);
}
catch (MongoWriteException ex) when (ex.WriteError?.Category == ServerErrorCategory.DuplicateKey)