- Custom emoji (Emoji tags) on posts, display names, bios and profile fields, at most 64 per object, proxied, in Status.emojis and Account.emojis. - Remote profiles keep their header, profile fields, locked flag, published date, movedTo, indexable, memorial and image descriptions (a locked GoToSocial account no longer shows as open). - Polls: incoming Questions (Mastodon, Misskey, Pleroma, GoToSocial shapes) with counts, voters, end and closed; our own polls from the Mastodon API go out as Questions; votes in are counted once per voter and never become replies; personas vote on other servers' polls with one Note per choice; counts refresh with an Update at most every three minutes; a poll closes on time and tells its voters and its author. GET /api/v1/polls/:id and POST /api/v1/polls/:id/votes. - An Update without a newer `updated` only refreshes poll, video, audio and event details and leaves no revision. Checked live against GoToSocial: each side's poll reaches the other as a poll and each side's vote is counted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
35 lines
971 B
C#
35 lines
971 B
C#
using MongoDB.Driver;
|
|
using MongoDB.Entities;
|
|
|
|
using PrivaPub.Models.Social;
|
|
|
|
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)
|
|
{
|
|
if (string.IsNullOrEmpty(avatarId) || avatarId == fromAccountId && type != NotificationType.Poll)
|
|
return;
|
|
if ((await Relationships.Hidden.AuthorsHiddenFrom(avatarId, new[] { fromActorUri }, forNotifications: true, token)).Count > 0)
|
|
return;
|
|
try
|
|
{
|
|
await DB.Default.SaveAsync(new Notification
|
|
{
|
|
AvatarId = avatarId,
|
|
Type = type,
|
|
FromAccountId = fromAccountId,
|
|
FromActorURI = fromActorUri,
|
|
PostId = postId,
|
|
DedupeKey = $"{type}|{avatarId}|{fromActorUri}|{postId}"
|
|
}, token);
|
|
}
|
|
catch (MongoWriteException ex) when (ex.WriteError?.Category == ServerErrorCategory.DuplicateKey)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|