fix: my-profile replies tab queries posts collection instead of ap_activities

The replies tab was empty because it queried ap_activities for outbound
Create activities with a non-null targetUrl, but targetUrl was always null
(remote actor resolution often fails). Now queries posts collection for
post-type "reply" which reliably has in-reply-to URLs.

Also fixes activity log to store in-reply-to URL as targetUrl instead of
the resolved actor URL.
This commit is contained in:
Ricardo
2026-02-23 16:29:32 +01:00
parent 743cb6b85b
commit 9805cb9eff
3 changed files with 16 additions and 27 deletions
+1 -1
View File
@@ -480,7 +480,7 @@ export default class ActivityPubEndpoint {
type: typeName, type: typeName,
actorUrl: self._publicationUrl, actorUrl: self._publicationUrl,
objectUrl: properties.url, objectUrl: properties.url,
targetUrl: replyToActor?.url || undefined, targetUrl: properties["in-reply-to"] || undefined,
summary: `Sent ${typeName} for ${properties.url} to ${followerCount} followers${replyNote}`, summary: `Sent ${typeName} for ${properties.url} to ${followerCount} followers${replyNote}`,
}); });
+14 -25
View File
@@ -137,41 +137,30 @@ export function myProfileController(plugin) {
} }
case "replies": { case "replies": {
const apActivities = collections.get("ap_activities"); // Query posts collection for reply-type posts (have in-reply-to)
if (apActivities) { if (postsCollection) {
const query = { const query = {
direction: "outbound", "properties.post-type": "reply",
type: "Create",
targetUrl: { $exists: true, $ne: null },
}; };
if (before) { if (before) {
query.receivedAt = { $lt: before }; query["properties.published"] = { $lt: before };
} }
const activities = await apActivities const replies = await postsCollection
.find(query) .find(query)
.sort({ receivedAt: -1 }) .sort({ "properties.published": -1 })
.limit(PAGE_LIMIT) .limit(PAGE_LIMIT)
.toArray(); .toArray();
items = activities.map((a) => ({ items = replies.map((p) => {
uid: a.objectUrl, const card = postToCardItem(p, profile);
url: a.objectUrl, card.inReplyTo = p.properties?.["in-reply-to"] || null;
content: a.content card.type = "reply";
? { text: a.content } return card;
: { text: a.summary || "" }, });
published: a.receivedAt,
inReplyTo: a.targetUrl,
type: "reply",
author: {
name: profile?.name || a.actorName || "",
url: profile?.url || a.actorUrl || "",
photo: profile?.icon || "",
},
}));
if (activities.length === PAGE_LIMIT) { if (replies.length === PAGE_LIMIT) {
nextBefore = activities[activities.length - 1].receivedAt; nextBefore = items[items.length - 1].published;
} }
} }
break; break;
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@rmdes/indiekit-endpoint-activitypub", "name": "@rmdes/indiekit-endpoint-activitypub",
"version": "2.0.11", "version": "2.0.12",
"description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.", "description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
"keywords": [ "keywords": [
"indiekit", "indiekit",