A status asked for by id is shown, and remote warnings are their own
GET /api/v1/statuses/:id applied the viewer's own blocks and mutes and answered 200 with null for a post of an author the viewer had blocked; decePub's thread page then showed nothing. As in Mastodon, a status asked for by id (or acted on) is shown whatever the viewer blocked or muted, and only lists leave such posts out; when nothing can be shown the answer is 404, never null, and search leaves it out. A remote post marked sensitive with an empty summary (Akkoma's sensitive media, Lemmy's NSFW) got an invented "Content warning" that hid its words. A remote post now keeps its own summary: sensitive without one hides the media only. A local post warned without words still gets the default warning. Both found by decePub's end-to-end tests on the town. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
d405269526
commit
6b55b5c35c
4 files changed
+48
-7
No files matched your search
@@ -146,12 +146,15 @@ namespace PrivaPub.Api.Mastodon.Mappers
|
||||
}
|
||||
|
||||
public async Task<Status> Status(PostEntity post, string viewerId, CancellationToken token) =>
|
||||
(await Statuses(new[] { post }, viewerId, token)).FirstOrDefault();
|
||||
(await Statuses(new[] { post }, viewerId, nested: false, token, hideFromViewer: false)).FirstOrDefault();
|
||||
|
||||
public Task<List<Status>> Statuses(IReadOnlyCollection<PostEntity> posts, string viewerId, CancellationToken token) =>
|
||||
Statuses(posts, viewerId, nested: false, token);
|
||||
|
||||
async Task<List<Status>> Statuses(IReadOnlyCollection<PostEntity> posts, string viewerId, bool nested, CancellationToken token)
|
||||
// Lists leave out what the viewer blocked or muted; a status asked for by its id is still shown, as Mastodon shows it
|
||||
// (only its author's block of the viewer hides it, and that is decided before mapping)
|
||||
async Task<List<Status>> Statuses(IReadOnlyCollection<PostEntity> posts, string viewerId, bool nested, CancellationToken token,
|
||||
bool hideFromViewer = true)
|
||||
{
|
||||
var originalIds = posts.Where(p => p.ReblogOfPostId != default).Select(p => p.ReblogOfPostId).Distinct().ToList();
|
||||
var originals = originalIds.Count == 0
|
||||
@@ -191,7 +194,7 @@ namespace PrivaPub.Api.Mastodon.Mappers
|
||||
? new Dictionary<string, List<int>>()
|
||||
: (await DB.Default.Find<PollVote>().Match(v => pollIds.Contains(v.PostId) && v.VoterAccountId == viewerId && v.IsLocalVoter).ExecuteAsync(token))
|
||||
.GroupBy(v => v.PostId).ToDictionary(g => g.Key, g => g.Select(v => v.Choice).ToList());
|
||||
var hidden = viewerId == default
|
||||
var hidden = viewerId == default || !hideFromViewer
|
||||
? new HashSet<string>()
|
||||
: await Domain.Relationships.Hidden.AuthorsHiddenFrom(viewerId, all.Select(p => p.ActorURI), forNotifications: false, token);
|
||||
var reblogged = viewerId == default
|
||||
@@ -222,7 +225,9 @@ namespace PrivaPub.Api.Mastodon.Mappers
|
||||
Bookmarked = bookmarked.Contains(post.ID),
|
||||
Pinned = pinned.Contains(post.ID),
|
||||
Sensitive = post.HasContentWarning,
|
||||
SpoilerText = post.SpoilerText ?? (post.HasContentWarning ? post.Title ?? ActivityPubRenderer.ContentWarning : string.Empty),
|
||||
//a remote post keeps its own summary: sensitive with none (Akkoma's sensitive media, Lemmy's NSFW) hides the
|
||||
//media, never the words behind an invented warning; a local post warned without words gets the default one
|
||||
SpoilerText = post.SpoilerText ?? (post.HasContentWarning && !post.IsFederatedCopy ? post.Title ?? ActivityPubRenderer.ContentWarning : string.Empty),
|
||||
Visibility = Visibility(post.Visibility),
|
||||
Language = post.Language,
|
||||
MediaAttachments = post.Media.Count > 0 ? post.Media.Select(Media).ToList() : Playable(post),
|
||||
|
||||
Reference in new issue
Block a user