P6: custom emoji, fuller remote profiles, and polls both ways
Build / Build (push) Successful in 39s
Deploy / privapub.thepra.dev (push) Successful in 57s

- 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
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-01 18:35:20 +02:00
1 parent 81de470f64
commit 7be6749a23
33 files changed
+937 -28

No files matched your search

+36 -4
View File
@@ -25,12 +25,24 @@ namespace PrivaPub.Api.Mastodon.Entities
public string LastStatusAt { get; set; }
public bool? HideCollections { get; set; }
public bool Noindex { get; set; } = true;
public List<object> Emojis { get; set; } = new();
public List<CustomEmojiEntity> Emojis { get; set; } = new();
public List<object> Roles { get; set; } = new();
public bool? Memorial { get; set; }
public string AvatarDescription { get; set; } = string.Empty;
public string HeaderDescription { get; set; } = string.Empty;
public List<Field> Fields { get; set; } = new();
public Source Source { get; set; }
}
public class CustomEmojiEntity
{
public string Shortcode { get; set; }
public string Url { get; set; }
public string StaticUrl { get; set; }
public bool VisibleInPicker { get; set; }
public string Category { get; set; }
}
public class Field
{
public string Name { get; set; }
@@ -149,6 +161,26 @@ namespace PrivaPub.Api.Mastodon.Entities
public int Down { get; set; }
}
public class PollEntity
{
public string Id { get; set; }
public string ExpiresAt { get; set; }
public bool Expired { get; set; }
public bool Multiple { get; set; }
public int VotesCount { get; set; }
public int? VotersCount { get; set; }
public bool? Voted { get; set; }
public List<int> OwnVotes { get; set; }
public List<PollOptionEntity> Options { get; set; } = new();
public List<CustomEmojiEntity> Emojis { get; set; } = new();
}
public class PollOptionEntity
{
public string Title { get; set; }
public int? VotesCount { get; set; }
}
public class PreviewCard
{
public string Url { get; set; }
@@ -183,7 +215,7 @@ namespace PrivaPub.Api.Mastodon.Entities
public string Content { get; set; } = string.Empty;
public string CreatedAt { get; set; }
public string EditedAt { get; set; }
public List<object> Emojis { get; set; } = new();
public List<CustomEmojiEntity> Emojis { get; set; } = new();
public int RepliesCount { get; set; }
public int ReblogsCount { get; set; }
public int FavouritesCount { get; set; }
@@ -199,7 +231,7 @@ namespace PrivaPub.Api.Mastodon.Entities
public List<StatusMention> Mentions { get; set; } = new();
public List<StatusTag> Tags { get; set; } = new();
public PreviewCard Card { get; set; }
public object Poll { get; set; }
public PollEntity Poll { get; set; }
public Application Application { get; set; }
public string Language { get; set; }
public string Text { get; set; }
@@ -289,7 +321,7 @@ namespace PrivaPub.Api.Mastodon.Entities
public string CreatedAt { get; set; }
public Account Account { get; set; }
public List<MediaAttachment> MediaAttachments { get; set; } = new();
public List<object> Emojis { get; set; } = new();
public List<CustomEmojiEntity> Emojis { get; set; } = new();
}
public class StatusSource