@rmdes/indiekit-endpoint-activitypub 2.4.2 → 2.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -92,7 +92,7 @@ export function mapMastodonStatusToItem(status, instance) {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
const item = {
|
|
96
96
|
uid: status.url || status.uri || "",
|
|
97
97
|
url: status.url || status.uri || "",
|
|
98
98
|
type: "note",
|
|
@@ -116,7 +116,43 @@ export function mapMastodonStatusToItem(status, instance) {
|
|
|
116
116
|
video,
|
|
117
117
|
audio,
|
|
118
118
|
inReplyTo: status.in_reply_to_id ? `https://${instance}/web/statuses/${status.in_reply_to_id}` : "",
|
|
119
|
+
quoteUrl: status.quote?.url || status.quote?.uri || "",
|
|
119
120
|
createdAt: new Date().toISOString(),
|
|
120
121
|
_explore: true,
|
|
121
122
|
};
|
|
123
|
+
|
|
124
|
+
// Map quoted post data if present (Mastodon 4.3+ quote support)
|
|
125
|
+
if (status.quote) {
|
|
126
|
+
const q = status.quote;
|
|
127
|
+
const qAccount = q.account || {};
|
|
128
|
+
const qAcct = qAccount.acct || "";
|
|
129
|
+
const qHandle = qAcct.includes("@") ? `@${qAcct}` : `@${qAcct}@${instance}`;
|
|
130
|
+
const qPhoto = [];
|
|
131
|
+
for (const att of q.media_attachments || []) {
|
|
132
|
+
const attUrl = att.url || att.remote_url || "";
|
|
133
|
+
if (attUrl && (att.type === "image" || att.type === "gifv")) {
|
|
134
|
+
qPhoto.push(attUrl);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
item.quote = {
|
|
139
|
+
url: q.url || q.uri || "",
|
|
140
|
+
uid: q.uri || q.url || "",
|
|
141
|
+
author: {
|
|
142
|
+
name: sanitizeHtml(qAccount.display_name || qAccount.username || "Unknown", { allowedTags: [], allowedAttributes: {} }),
|
|
143
|
+
url: qAccount.url || "",
|
|
144
|
+
photo: qAccount.avatar || qAccount.avatar_static || "",
|
|
145
|
+
handle: qHandle,
|
|
146
|
+
},
|
|
147
|
+
content: {
|
|
148
|
+
text: (q.content || "").replace(/<[^>]*>/g, ""),
|
|
149
|
+
html: sanitizeContent(q.content || ""),
|
|
150
|
+
},
|
|
151
|
+
published: q.created_at || "",
|
|
152
|
+
name: "",
|
|
153
|
+
photo: qPhoto.slice(0, 1),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return item;
|
|
122
158
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { searchInstances, checkInstanceTimeline, getPopularAccounts } from "../fedidb.js";
|
|
9
9
|
import { getToken } from "../csrf.js";
|
|
10
10
|
import { validateInstance, validateHashtag, mapMastodonStatusToItem } from "./explore-utils.js";
|
|
11
|
+
import { stripQuoteReferenceHtml } from "../og-unfurl.js";
|
|
11
12
|
|
|
12
13
|
const FETCH_TIMEOUT_MS = 10_000;
|
|
13
14
|
const MAX_RESULTS = 20;
|
|
@@ -98,6 +99,14 @@ export function exploreController(mountPath) {
|
|
|
98
99
|
|
|
99
100
|
items = statuses.map((s) => mapMastodonStatusToItem(s, instance));
|
|
100
101
|
|
|
102
|
+
// Strip "RE:" paragraphs from items that have quote embeds
|
|
103
|
+
for (const item of items) {
|
|
104
|
+
const quoteRef = item.quoteUrl || item.quote?.url || item.quote?.uid;
|
|
105
|
+
if (item.quote && quoteRef && item.content?.html) {
|
|
106
|
+
item.content.html = stripQuoteReferenceHtml(item.content.html, quoteRef);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
101
110
|
// Get next max_id from last item for pagination
|
|
102
111
|
if (statuses.length === MAX_RESULTS && statuses.length > 0) {
|
|
103
112
|
const last = statuses[statuses.length - 1];
|
|
@@ -181,6 +190,14 @@ export function exploreApiController(mountPath) {
|
|
|
181
190
|
|
|
182
191
|
const items = statuses.map((s) => mapMastodonStatusToItem(s, instance));
|
|
183
192
|
|
|
193
|
+
// Strip "RE:" paragraphs from items that have quote embeds
|
|
194
|
+
for (const item of items) {
|
|
195
|
+
const quoteRef = item.quoteUrl || item.quote?.url || item.quote?.uid;
|
|
196
|
+
if (item.quote && quoteRef && item.content?.html) {
|
|
197
|
+
item.content.html = stripQuoteReferenceHtml(item.content.html, quoteRef);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
184
201
|
let nextMaxId = null;
|
|
185
202
|
if (statuses.length === MAX_RESULTS && statuses.length > 0) {
|
|
186
203
|
const last = statuses[statuses.length - 1];
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import { validateHashtag, mapMastodonStatusToItem } from "./explore-utils.js";
|
|
20
20
|
import { getToken } from "../csrf.js";
|
|
21
|
+
import { stripQuoteReferenceHtml } from "../og-unfurl.js";
|
|
21
22
|
|
|
22
23
|
const FETCH_TIMEOUT_MS = 10_000;
|
|
23
24
|
const PAGE_SIZE = 20;
|
|
@@ -183,6 +184,14 @@ export function hashtagExploreApiController(mountPath) {
|
|
|
183
184
|
mapMastodonStatusToItem(status, domain)
|
|
184
185
|
);
|
|
185
186
|
|
|
187
|
+
// Strip "RE:" paragraphs from items that have quote embeds
|
|
188
|
+
for (const item of items) {
|
|
189
|
+
const quoteRef = item.quoteUrl || item.quote?.url || item.quote?.uid;
|
|
190
|
+
if (item.quote && quoteRef && item.content?.html) {
|
|
191
|
+
item.content.html = stripQuoteReferenceHtml(item.content.html, quoteRef);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
186
195
|
// Render HTML AFTER merge/dedup/paginate (don't waste CPU on discarded items)
|
|
187
196
|
const csrfToken = getToken(request.session);
|
|
188
197
|
const templateData = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rmdes/indiekit-endpoint-activitypub",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.3",
|
|
4
4
|
"description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"indiekit",
|