A community's vote on our reply counts, followed or not
Lemmy sends a vote to the community alone, which relays it to the post's server. A persona's reply in a thread of a community nobody here follows lost its Lemmy upvotes: the relay was dropped as "not followed". Such a relay is now taken when the vote (or its undo) is on one of our posts in a thread rooted in that community; from any other unfollowed group it is still dropped. For that, a post keeps the community its `audience` names (FEP-1b12) however it arrived, fetched for a thread as well as announced. Found by the town's village (p191: 1 like counted of 2). 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
8686275b69
commit
7e37f56db6
4 files changed
+62
-2
No files matched your search
@@ -143,7 +143,8 @@ namespace PrivaPub.Federation.Inbox.Handlers
|
||||
{
|
||||
Arrival.About(Value(inner, "type"));
|
||||
if (group.AvatarType != AvatarType.Group
|
||||
|| !await _dbEntities.Followings.Match(f => f.TargetActorURI == group.ActorURI && f.State == FollowState.Accepted).ExecuteAnyAsync(token))
|
||||
|| !await _dbEntities.Followings.Match(f => f.TargetActorURI == group.ActorURI && f.State == FollowState.Accepted).ExecuteAnyAsync(token)
|
||||
&& !await OurPostInItsThread(inner, group, token))
|
||||
{
|
||||
Arrival.Drop("not-followed");
|
||||
return;
|
||||
@@ -230,6 +231,28 @@ namespace PrivaPub.Federation.Inbox.Handlers
|
||||
}
|
||||
}
|
||||
|
||||
// A vote (or its undoing) on one of our posts in a thread the community holds: the community relays it to the post's
|
||||
// server whether or not anyone here follows the community (Lemmy sends a vote to the community alone)
|
||||
async Task<bool> OurPostInItsThread(JsonNode inner, ForeignAvatar group, CancellationToken token)
|
||||
{
|
||||
var target = Value(inner, "type") switch
|
||||
{
|
||||
"Like" or "Dislike" => Id(inner["object"]),
|
||||
"Undo" when (inner["object"] as JsonObject)?["type"]?.GetValue<string>() is "Like" or "Dislike" => Id(inner["object"]?["object"]),
|
||||
_ => default
|
||||
};
|
||||
var post = target == default
|
||||
? default
|
||||
: await _dbEntities.Posts.Match(p => p.ObjectURI == target && !p.IsFederatedCopy && !p.DeletedAt.HasValue).ExecuteFirstAsync(token);
|
||||
for (var depth = 0; post != default && depth < RemotePosts.MaxDepth; depth++)
|
||||
{
|
||||
if (post.AudienceURI == group.ActorURI)
|
||||
return true;
|
||||
post = string.IsNullOrEmpty(post.AnsweringToPostId) ? default : await _dbEntities.Posts.MatchID(post.AnsweringToPostId).ExecuteFirstAsync(token);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// A community's moderators lock one of its posts, or unlock it: no more replies, ours included. The community vouches
|
||||
// for what is done to its own posts.
|
||||
async Task Lock(string objectUri, ForeignAvatar group, bool locked, CancellationToken token)
|
||||
|
||||
@@ -94,6 +94,11 @@ namespace PrivaPub.Federation.Inbox
|
||||
Cc = cc.ToList(),
|
||||
Url = note.Url,
|
||||
ContextURI = note.Context,
|
||||
// the community it lives in (FEP-1b12), as the post itself names it: a post fetched for a thread knows its
|
||||
// community as well as one its community announced
|
||||
AudienceURI = note.Audience != default && note.Audience != author.ActorURI && !note.Audience.EndsWith("/followers", StringComparison.Ordinal)
|
||||
? note.Audience
|
||||
: default,
|
||||
QuoteURI = note.QuoteUri,
|
||||
ObjectType = note.Type,
|
||||
Title = note.Title,
|
||||
|
||||
Reference in new issue
Block a user