commit 074e19d
grunfink
·
2025-08-31 12:07:27 +0000 UTC
parent 5cda2f7
Added a 'replies' object to Notes.
2 files changed,
+77,
-0
M
snac.h
+76,
-0
1@@ -1264,6 +1264,46 @@ xs_dict *msg_collection(snac *snac, const char *id, int items)
2 }
3
4
5+xs_dict *msg_replies(snac *user, const char *id, int fill)
6+/* creates a CollectionPage with replies of id */
7+{
8+ xs *r_id = xs_replace(id, "/p/", "/r/");
9+ xs *r_idp = xs_fmt("%s#page", r_id);
10+ xs *r_idh = xs_fmt("%s#hdr", r_id);
11+
12+ xs_dict *msg = msg_base(user, "CollectionPage", r_idp, NULL, NULL, NULL);
13+
14+ msg = xs_dict_set(msg, "partOf", r_idh);
15+
16+ xs *items = xs_list_new();
17+ if (fill) {
18+ xs *children = object_children(id);
19+ const char *md5;
20+
21+ xs_list_foreach(children, md5) {
22+ xs *obj = NULL;
23+
24+ if (valid_status(object_get_by_md5(md5, &obj)) && is_msg_public(obj)) {
25+ const char *c_id = xs_dict_get(obj, "id");
26+
27+ if (xs_is_string(c_id))
28+ items = xs_list_append(items, c_id);
29+ }
30+ }
31+ }
32+ else {
33+ xs *r_idl = xs_fmt("%s#local", r_id);
34+
35+ msg = xs_dict_del(msg, "@context");
36+ msg = xs_dict_set(msg, "id", r_idl);
37+ }
38+
39+ msg = xs_dict_set(msg, "items", items);
40+
41+ return msg;
42+}
43+
44+
45 xs_dict *msg_accept(snac *snac, const xs_val *object, const char *to)
46 /* creates an Accept message (as a response to a Follow) */
47 {
48@@ -1868,6 +1908,22 @@ xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts,
49 }
50 }
51
52+ if (!priv) {
53+ /* create the replies object */
54+ xs *replies = xs_dict_new();
55+ xs *r_id = xs_replace(id, "/p/", "/r/");
56+ xs *h_id = xs_fmt("%s#hdr", r_id);
57+ xs *n_id = xs_fmt("%s#page", r_id);
58+ xs *rp = msg_replies(snac, id, 0);
59+
60+ replies = xs_dict_set(replies, "id", h_id);
61+ replies = xs_dict_set(replies, "type", "Collection");
62+ replies = xs_dict_set(replies, "next", n_id);
63+ replies = xs_dict_set(replies, "first", rp);
64+
65+ msg = xs_dict_set(msg, "replies", replies);
66+ }
67+
68 return msg;
69 }
70
71@@ -3395,6 +3451,26 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path,
72 if (valid_status(status) && !is_msg_public(msg))
73 status = HTTP_STATUS_NOT_FOUND;
74 }
75+ else
76+ if (xs_startswith(p_path, "r/")) {
77+ /* replies to a post */
78+ xs *s = xs_dup(p_path);
79+ s[0] = 'p';
80+
81+ xs *id = xs_fmt("%s/%s", snac.actor, s);
82+
83+ xs *obj = NULL;
84+ status = object_get(id, &obj);
85+
86+ /* don't return non-public objects */
87+ if (!valid_status(status))
88+ status = HTTP_STATUS_NOT_FOUND;
89+ else
90+ if (!is_msg_public(obj))
91+ status = HTTP_STATUS_NOT_FOUND;
92+ else
93+ msg = msg_replies(&snac, id, 1);
94+ }
95 else
96 status = HTTP_STATUS_NOT_FOUND;
97
M
snac.h
+1,
-0
1@@ -360,6 +360,7 @@ xs_dict *msg_move(snac *user, const char *new_account);
2 xs_dict *msg_accept(snac *snac, const xs_val *object, const char *to);
3 xs_dict *msg_question(snac *user, const char *content, xs_list *attach,
4 const xs_list *opts, int multiple, int end_secs);
5+xs_dict *msg_replies(snac *user, const char *id, int fill);
6
7 int activitypub_request(snac *snac, const char *url, xs_dict **data);
8 int actor_request(snac *user, const char *actor, xs_dict **data);