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);