From a4a1990dbb16e3e4599500299c32c980c9cbd5bf Mon Sep 17 00:00:00 2001
From: byte
Date: Sat, 25 Oct 2025 16:21:42 +0200
Subject: rendering visibility conditionally, with lesser reach if needed
---
html.c | 72 +++++++++++++++++++++++++++++-------------------------------------
1 file changed, 32 insertions(+), 40 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 584059b..7c39237 100644
--- a/html.c
+++ b/html.c
@@ -398,6 +398,37 @@ xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg,
return actor_icon;
}
+void html_note_render_visibility(snac* user, xs_html *form, const int scope)
+{
+ // scopes aren't sorted by value unfortunately, so simple math won't work to limit them. using map-like thing here
+ static const int public_scopes[5] = {SCOPE_PUBLIC, SCOPE_UNLISTED, SCOPE_FOLLOWERS, SCOPE_MENTIONED, -1};
+ static const int unlisted_scopes[4] = {SCOPE_UNLISTED, SCOPE_FOLLOWERS, SCOPE_MENTIONED, -1};
+ static const int followers_scopes[3] = {SCOPE_FOLLOWERS, SCOPE_MENTIONED, -1};
+ static const int mentioned_scopes[2] = {SCOPE_MENTIONED, -1};
+ static const int * const scopes[4] = { public_scopes, mentioned_scopes, unlisted_scopes, followers_scopes};
+ static const char * const scopes_tags[4] = { "public", "mentioned", "unlisted", "followers"};
+ static const char * const scopes_names[4] = { "Public", "Direct Message", "Unlisted", "Followers-only"};
+
+ xs_html *paragraph = xs_html_tag("p", xs_html_text(L("Visibility: ")));
+ const int* to_render = scopes[scope];
+ for( int i = 0; to_render[i] != -1; i++ ){
+ const int scope_i = to_render[i];
+ const char* value = scopes_tags[scope_i];
+ const char* name = scopes_names[scope_i];
+ xs_html_add(paragraph,
+ xs_html_tag("label",
+ xs_html_sctag("input",
+ xs_html_attr("type", "radio"),
+ xs_html_attr("name", "visibility"),
+ xs_html_attr("value", value),
+ xs_html_attr(scope == scope_i ? "checked" : "", NULL)),
+ xs_html_text(" "),
+ xs_html_text(L(name)),
+ xs_html_text(" "))
+ );
+ }
+ xs_html_add(form, paragraph);
+}
xs_html *html_note(snac *user, const char *summary,
const char *div_id, const char *form_id,
@@ -455,46 +486,7 @@ xs_html *html_note(snac *user, const char *summary,
xs_html_attr("type", "hidden"),
xs_html_attr("name", "to"),
xs_html_attr("value", actor_id)));
- else {
- xs_html_add(form,
- xs_html_tag("p",
- xs_html_text(L("Visibility: ")),
- xs_html_tag("label",
- xs_html_sctag("input",
- xs_html_attr("type", "radio"),
- xs_html_attr("name", "visibility"),
- xs_html_attr("value", "public"),
- xs_html_attr(scope == SCOPE_PUBLIC ? "checked" : "", NULL)),
- xs_html_text(" "),
- xs_html_text(L("Public"))),
- xs_html_text(" "),
- xs_html_tag("label",
- xs_html_sctag("input",
- xs_html_attr("type", "radio"),
- xs_html_attr("name", "visibility"),
- xs_html_attr("value", "unlisted"),
- xs_html_attr(scope == SCOPE_UNLISTED ? "checked" : "", NULL)),
- xs_html_text(" "),
- xs_html_text(L("Unlisted"))),
- xs_html_text(" "),
- xs_html_tag("label",
- xs_html_sctag("input",
- xs_html_attr("type", "radio"),
- xs_html_attr("name", "visibility"),
- xs_html_attr("value", "followers"),
- xs_html_attr(scope == SCOPE_FOLLOWERS ? "checked" : "", NULL)),
- xs_html_text(" "),
- xs_html_text(L("Followers-only"))),
- xs_html_text(" "),
- xs_html_tag("label",
- xs_html_sctag("input",
- xs_html_attr("type", "radio"),
- xs_html_attr("name", "visibility"),
- xs_html_attr("value", "mentioned"),
- xs_html_attr(scope == SCOPE_MENTIONED ? "checked" : "", NULL)),
- xs_html_text(" "),
- xs_html_text(L("Direct Message")))));
- }
+ html_note_render_visibility(user, form, scope);
if (redir)
xs_html_add(form,
--
cgit v1.2.3
From daee7581dbf5b458f28e486fd89804b91209a9bb Mon Sep 17 00:00:00 2001
From: byte
Date: Sat, 1 Nov 2025 01:18:28 +0100
Subject: no visibility for editing
---
html.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index a2dfb79..84636e9 100644
--- a/html.c
+++ b/html.c
@@ -486,7 +486,8 @@ xs_html *html_note(snac *user, const char *summary,
xs_html_attr("type", "hidden"),
xs_html_attr("name", "to"),
xs_html_attr("value", actor_id)));
- html_note_render_visibility(user, form, scope);
+ if (edit_id == NULL)
+ html_note_render_visibility(user, form, scope);
if (redir)
xs_html_add(form,
--
cgit v1.2.3
From fcae55fcb1542f6fa0a330c45e3b806f902a84de Mon Sep 17 00:00:00 2001
From: grunfink
Date: Wed, 26 Nov 2025 17:21:16 +0100
Subject: Some attachments are of type 'Video' instead of a MIME type (bsky).
---
html.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index df5b508..12d269a 100644
--- a/html.c
+++ b/html.c
@@ -2634,7 +2634,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
xs_html_attr("title", name))));
}
else
- if (xs_startswith(type, "video/")) {
+ if (xs_startswith(type, "video/") || strcmp(type, "Video") == 0) {
xs_html_add(content_attachments,
xs_html_tag("video",
xs_html_attr("preload", "none"),
--
cgit v1.2.3
From a45c1ce152011e8fe25eb1d25594ac5705f65404 Mon Sep 17 00:00:00 2001
From: rako
Date: Fri, 28 Nov 2025 10:37:49 +0100
Subject: Fix user matching
In order to be a proper prefix, the actor url must end with a '/'
otherwise it can match another user that starts with the same prefix:
for example 'testuser' will match anything made by 'testuser2'
---
html.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 12d269a..d6223b9 100644
--- a/html.c
+++ b/html.c
@@ -1898,7 +1898,7 @@ xs_html *html_entry_controls(snac *user, const char *actor,
xs_html_attr("name", "redir"),
xs_html_attr("value", redir))));
- if (!xs_startswith(id, user->actor)) {
+ if (!is_msg_mine(user, id)) {
if (xs_list_in(likes, user->md5) == -1) {
/* not already liked; add button */
xs_html_add(form,
@@ -2426,7 +2426,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
if (read_only)
closed = 1; /* non-identified page; show as closed */
else
- if (user && xs_startswith(id, user->actor))
+ if (user && is_msg_mine(user, id))
closed = 1; /* we questioned; closed for us */
else
if (user && was_question_voted(user, id))
@@ -5022,7 +5022,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
}
else {
/* delete an entry */
- if (xs_startswith(id, snac.actor) && !is_draft(&snac, id)) {
+ if (is_msg_mine(&snac, id) && !is_draft(&snac, id)) {
/* it's a post by us: generate a delete */
xs *msg = msg_delete(&snac, id);
--
cgit v1.2.3
From ee7483cf0dd007d104a815fce47a0d5f050ca870 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Tue, 9 Dec 2025 13:31:37 +0100
Subject: New query variable terse=anything.
If set to any value, a public post page doesn't show any headline.
---
html.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 9ac57f8..32ed057 100644
--- a/html.c
+++ b/html.c
@@ -2996,7 +2996,7 @@ xs_html *html_footer(const snac *user)
xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
int skip, int show, int show_more,
const char *title, const char *page,
- int utl, const char *error)
+ int utl, const char *error, int terse)
/* returns the HTML for the timeline */
{
xs_list *p = (xs_list *)list;
@@ -3024,7 +3024,11 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
if (user) {
head = html_user_head(user, desc, alternate);
- body = html_user_body(user, read_only);
+
+ if (terse)
+ body = xs_html_tag("body", NULL);
+ else
+ body = html_user_body(user, read_only);
}
else {
head = html_instance_head();
@@ -3902,6 +3906,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
int cache = 1;
int save = 1;
int proxy = 0;
+ int terse = 0;
const char *v;
const xs_dict *q_vars = xs_dict_get(req, "q_vars");
@@ -3914,6 +3919,9 @@ int html_get_handler(const xs_dict *req, const char *q_path,
return HTTP_STATUS_NOT_FOUND;
}
+ if (!xs_is_null(xs_dict_get(q_vars, "terse")))
+ terse = 1;
+
if (strcmp(v, "share-bridge") == 0) {
/* temporary redirect for a post */
const char *login = xs_dict_get(q_vars, "login");
@@ -4014,7 +4022,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE) {
/** empty public timeline for private users **/
- *body = html_timeline(&snac, NULL, 1, 0, 0, 0, NULL, "", 1, error);
+ *body = html_timeline(&snac, NULL, 1, 0, 0, 0, NULL, "", 1, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4037,7 +4045,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *pins = pinned_list(&snac);
pins = xs_list_cat(pins, list);
- *body = html_timeline(&snac, pins, 1, skip, show, more, NULL, "", 1, error);
+ *body = html_timeline(&snac, pins, 1, skip, show, more, NULL, "", 1, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
@@ -4161,7 +4169,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *title = xs_fmt(xs_list_len(tl) ?
L("Search results for tag %s") : L("Nothing found for tag %s"), q);
- *body = html_timeline(&snac, tl, 0, skip, show, more, title, page, 0, error);
+ *body = html_timeline(&snac, tl, 0, skip, show, more, title, page, 0, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4186,7 +4194,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
title = xs_fmt(L("Nothing found for '%s'"), q);
*body = html_timeline(&snac, tl, 0, skip, tl_len, to || tl_len == show,
- title, page, 0, error);
+ title, page, 0, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4213,7 +4221,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *list = timeline_list(&snac, "private", skip, show, &more);
*body = html_timeline(&snac, list, 0, skip, show,
- more, NULL, "/admin", 1, error);
+ more, NULL, "/admin", 1, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
@@ -4240,7 +4248,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *list0 = xs_list_append(xs_list_new(), md5);
xs *list = timeline_top_level(&snac, list0);
- *body = html_timeline(&snac, list, 0, 0, 0, 0, NULL, "/admin", 1, error);
+ *body = html_timeline(&snac, list, 0, 0, 0, 0, NULL, "/admin", 1, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4281,7 +4289,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *next = timeline_instance_list(skip + show, 1);
*body = html_timeline(&snac, list, 0, skip, show,
- xs_list_len(next), L("Showing instance timeline"), "/instance", 0, error);
+ xs_list_len(next), L("Showing instance timeline"), "/instance", 0, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4296,7 +4304,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *list = pinned_list(&snac);
*body = html_timeline(&snac, list, 0, skip, show,
- 0, L("Pinned posts"), "", 0, error);
+ 0, L("Pinned posts"), "", 0, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4311,7 +4319,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *list = bookmark_list(&snac);
*body = html_timeline(&snac, list, 0, skip, show,
- 0, L("Bookmarked posts"), "", 0, error);
+ 0, L("Bookmarked posts"), "", 0, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4326,7 +4334,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *list = draft_list(&snac);
*body = html_timeline(&snac, list, 0, skip, show,
- 0, L("Post drafts"), "", 0, error);
+ 0, L("Post drafts"), "", 0, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4341,7 +4349,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *list = scheduled_list(&snac);
*body = html_timeline(&snac, list, 0, skip, show,
- 0, L("Scheduled posts"), "", 0, error);
+ 0, L("Scheduled posts"), "", 0, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4367,7 +4375,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *title = xs_fmt(L("Showing timeline for list '%s'"), name);
*body = html_timeline(&snac, ttl, 0, skip, show,
- xs_list_len(next), title, base, 1, error);
+ xs_list_len(next), title, base, 1, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
@@ -4387,7 +4395,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
list = xs_list_append(list, md5);
- *body = html_timeline(&snac, list, 1, 0, 0, 0, NULL, "", 1, error);
+ *body = html_timeline(&snac, list, 1, 0, 0, 0, NULL, "", 1, error, terse);
*b_size = strlen(*body);
status = HTTP_STATUS_OK;
}
--
cgit v1.2.3
From 481c0315ef7ccd2eaf0ec9c6eaa17cbbd7efeb2c Mon Sep 17 00:00:00 2001
From: grunfink
Date: Tue, 9 Dec 2025 13:38:56 +0100
Subject: If terse is set, history is also hidden.
---
html.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 32ed057..8f7c4a9 100644
--- a/html.c
+++ b/html.c
@@ -3248,7 +3248,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
if (list && user && read_only) {
/** history **/
- if (xs_type(xs_dict_get(srv_config, "disable_history")) != XSTYPE_TRUE) {
+ if (xs_type(xs_dict_get(srv_config, "disable_history")) != XSTYPE_TRUE && !terse) {
xs_html *ul = xs_html_tag("ul", NULL);
xs_html *history = xs_html_tag("div",
--
cgit v1.2.3
From 85ed0eb0d535700a5df837c37f51848811e461a0 Mon Sep 17 00:00:00 2001
From: violette
Date: Thu, 18 Dec 2025 07:58:24 +0100
Subject: Added emoji reactions (contributed by violette).
---
html.c | 317 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 305 insertions(+), 12 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 8f7c4a9..8cc0067 100644
--- a/html.c
+++ b/html.c
@@ -54,9 +54,10 @@ int login(snac *user, const xs_dict *headers)
return logged_in;
}
-
-xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *proxy)
-/* replaces all the :shortnames: with the emojis in tag */
+xs_str *_replace_shortnames(xs_str *s, const xs_list *tag, int ems,
+ const char *proxy, const xs_list *cl, const char *act)
+/* replace but also adds a class list and an actor in its alt text.
+ * Used for emoji reactions */
{
if (!xs_is_null(tag)) {
xs *tag_list = NULL;
@@ -69,11 +70,15 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p
tag_list = xs_dup(tag);
}
- xs *style = xs_fmt("height: %dem; width: %dem; vertical-align: middle;", ems, ems);
+ xs *style = xs_fmt("max-height: %dem; max-width: %dem;", ems, ems);
xs *class = xs_fmt("snac-emoji snac-emoji-%d-em", ems);
+ if (cl)
+ class = xs_str_cat(class, " ", xs_join(cl, " "));
- const xs_dict *v;
int c = 0;
+ const xs_val *v;
+
+ c = 0;
xs_set rep_emoji;
xs_set_init(&rep_emoji);
@@ -100,6 +105,8 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p
if (!xs_is_string(mt))
mt = xs_mime_by_ext(u);
+ act = act ? xs_fmt("%s\n%s", n, act) : xs_fmt("%s", n);
+
if (strcmp(mt, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg")))
s = xs_replace_i(s, n, "");
else {
@@ -108,8 +115,8 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p
xs_html *img = xs_html_sctag("img",
xs_html_attr("loading", "lazy"),
xs_html_attr("src", url),
- xs_html_attr("alt", n),
- xs_html_attr("title", n),
+ xs_html_attr("alt", act),
+ xs_html_attr("title", act),
xs_html_attr("class", class),
xs_html_attr("style", style));
@@ -130,6 +137,13 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p
}
+xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *proxy)
+/* replaces all the :shortnames: with the emojis in tag */
+{
+ return _replace_shortnames(s, tag, ems, proxy, NULL, NULL);
+}
+
+
xs_str *actor_name(xs_dict *actor, const char *proxy)
/* gets the actor name */
{
@@ -430,6 +444,52 @@ void html_note_render_visibility(snac* user, xs_html *form, const int scope)
xs_html_add(form, paragraph);
}
+/* html_note but moddled for emoji's needs. here and not bellow, since the
+ * other one is already so complex. */
+xs_html *html_emoji(snac *user, const char *summary,
+ const char *div_id, const char *form_id,
+ const char* placeholder, const char *post_id,
+ const char* eid)
+{
+ xs *action = xs_fmt("%s/admin/action", user->actor);
+
+ xs_html *form;
+ const int react = eid == NULL ? 0 : 1;
+
+ xs_html *note = xs_html_tag("div",
+ xs_html_tag("details",
+ xs_html_tag("summary",
+ xs_html_text(summary)),
+ xs_html_tag("p", NULL),
+ xs_html_tag("div",
+ xs_html_attr("class", "snac-note"),
+ xs_html_attr("id", div_id),
+ form = xs_html_tag("form",
+ xs_html_attr("autocomplete", "off"),
+ xs_html_attr("method", "post"),
+ xs_html_attr("action", action),
+ xs_html_attr("enctype", "multipart/form-data"),
+ xs_html_attr("id", form_id),
+ xs_html_sctag("input",
+ xs_html_attr("type", "hidden"),
+ xs_html_attr("name", "id"),
+ xs_html_attr("value", post_id)),
+ xs_html_sctag("input",
+ xs_html_attr("type", react ? "hidden" : "text"),
+ xs_html_attr("name", "eid"),
+ xs_html_attr(react ? "value" : "placeholder", react ? eid : placeholder)),
+ xs_html_text(" "),
+ xs_html_sctag("input",
+ xs_html_attr("type", "submit"),
+ xs_html_attr("name", "action"),
+ xs_html_attr("eid", "action"),
+ xs_html_attr("value", react ? L("EmojiUnreact") : L("EmojiReact"))),
+ xs_html_text(" "),
+ xs_html_tag("p", NULL)))));
+
+ return note;
+}
+
xs_html *html_note(snac *user, const char *summary,
const char *div_id, const char *form_id,
const char *ta_plh, const char *ta_content,
@@ -1356,6 +1416,28 @@ xs_html *html_top_controls(snac *user)
xs_html_attr("value", L("Like"))),
xs_html_text(" "),
xs_html_text(L("(by URL)"))),
+ xs_html_tag("form",
+ xs_html_attr("autocomplete", "off"),
+ xs_html_attr("method", "post"),
+ xs_html_attr("action", ops_action),
+ xs_html_sctag("input",
+ xs_html_attr("type", "text"),
+ xs_html_attr("name", "eid"),
+ xs_html_attr("required", "required"),
+ xs_html_attr("placeholder", ":neocat:")),
+ xs_html_text(" "),
+ xs_html_sctag("input",
+ xs_html_attr("type", "text"),
+ xs_html_attr("name", "id"),
+ xs_html_attr("required", "required"),
+ xs_html_attr("placeholder", "https:/" "/fedi.example.com/bob/...")),
+ xs_html_text(" "),
+ xs_html_sctag("input",
+ xs_html_attr("type", "submit"),
+ xs_html_attr("name", "action"),
+ xs_html_attr("value", L("EmojiReact"))),
+ xs_html_text(" "),
+ xs_html_text(L("(by URL)"))),
xs_html_tag("p", NULL)));
/** user settings **/
@@ -2019,6 +2101,21 @@ xs_html *html_entry_controls(snac *user, const char *actor,
xs_html_tag("p", NULL));
}
+ { /** emoji react **/
+ /* the post textarea */
+ xs *div_id = xs_fmt("%s_reply", md5);
+ xs *form_id = xs_fmt("%s_reply_form", md5);
+
+ xs_html_add(controls, xs_html_tag("div",
+ xs_html_tag("p", NULL),
+ html_emoji(
+ user, L("Emoji react"),
+ div_id, form_id,
+ ":neocat:", id,
+ emoji_reacted(user, id))),
+ xs_html_tag("p", NULL));
+ }
+
{ /** reply **/
/* the post textarea */
xs *ct = build_mentions(user, msg);
@@ -2345,6 +2442,168 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
xs_html_add(snac_content_wrap,
snac_content);
+ /* add all emoji reacts */
+ int is_emoji = 0;
+ {
+ int c = 0;
+ const xs_dict *k;
+ xs *ls = xs_list_new();
+ xs *sfrl = xs_dict_new();
+ xs *rl = object_get_emoji_reacts(id);
+
+ xs_dict *m = NULL;
+ while (xs_list_next(rl, &v, &c)) {
+ if (valid_status(object_get_by_md5(v, &m))) {
+ const char *content = xs_dict_get(m, "content");
+ const char *actor = xs_dict_get(m, "actor");
+ const xs_list *contentl = xs_dict_get(sfrl, content);
+ xs *actors = xs_list_new();
+ actors = xs_list_append(actors, actor);
+ char me = actor && user && strcmp(actor, user->actor) == 0;
+ int count = 1;
+
+ if (contentl) {
+ count = atoi(xs_list_get(contentl, 0)) + 1;
+ const xs_list *actorsc = xs_list_get(contentl, 1);
+ if (strncmp(xs_list_get(contentl, 2), "1", 1) == 0)
+ me = 1;
+
+ if (xs_list_in(actorsc, actor) != -1) {
+ xs_free(actors);
+ actors = xs_dup(actorsc);
+ }
+ else
+ actors = xs_list_cat(actors, actorsc);
+ }
+
+ xs *fl = xs_list_new();
+ fl = xs_list_append(fl, xs_fmt("%d", count), actors, xs_fmt("%d", me));
+ sfrl = xs_dict_append(sfrl, content, fl);
+ }
+ }
+
+ c = 0;
+
+ while (xs_list_next(rl, &k, &c)) {
+ if (valid_status(object_get_by_md5(k, &m))) {
+ const xs_dict *tag = xs_dict_get(m, "tag");
+ const xs_dict *ide = xs_dict_get(m, "id");
+
+ const char *content = xs_dict_get(m, "content");
+ const char *shortname;
+ shortname = xs_dict_get(m, "content");
+
+ const xs_list *items = xs_dict_get(sfrl, content);
+ const char *nb = xs_list_get(items, 0);
+ const xs_list *actors = xs_list_get(items, 1);
+ const char me = *xs_list_get(items, 2) == '1';
+
+ if (!xs_is_null(nb)) {
+ is_emoji = 1;
+
+ const char *act = atoi(nb) > 1 ?
+ xs_fmt("%d different actors \n\t%s", atoi(nb), xs_join(actors, ",\n\t")) :
+ xs_dict_get(m, "actor");
+
+ xs *class = xs_list_new();
+ class = xs_list_append(class, "snac-reaction");
+
+ xs_html *ret = NULL;
+ if (tag && shortname) {
+ xs *cl = xs_list_new();
+ cl = xs_list_append(cl, "snac-reaction-image");
+ xs *emoji = _replace_shortnames(xs_dup(shortname), tag, 2, proxy, cl, act);
+
+ if (me)
+ class = xs_list_append(class, "snac-reacted");
+
+ ret = xs_html_tag("button",
+ xs_html_attr("type", "submit"),
+ xs_html_attr("name", "action"),
+ xs_html_attr("value", me ? L("EmojiReact") : L("EmojiUnreact")),
+ xs_html_raw(emoji),
+ xs_html_tag("span",
+ xs_html_raw(nb),
+ xs_html_attr("style", "padding-left: 5px;")),
+ xs_html_attr("title", act),
+ xs_html_attr("class", xs_join(class, " ")));
+
+ if (!(ide && xs_startswith(ide, srv_baseurl)))
+ xs_html_add(ret, xs_html_attr("disabled", "true"));
+ }
+ else if (shortname) {
+ xs *sn = xs_dup(shortname);
+ const char *sna = sn;
+ unsigned int utf = xs_utf8_dec((const char **)&sna);
+
+ if (xs_is_emoji(utf)) {
+ const char *style = "font-size: large;";
+ if (me)
+ class = xs_list_append(class, "snac-reacted");
+ ret = xs_html_tag("button",
+ xs_html_attr("type", "submit"),
+ xs_html_attr("name", "action"),
+ xs_html_attr("value", me ? L("EmojiUnreact") : L("EmojiReact")),
+ xs_html_raw(xs_fmt("%d", utf)),
+ xs_html_tag("span",
+ xs_html_raw(nb),
+ xs_html_attr("style", "font-size: initial; padding-left: 5px;")),
+ xs_html_attr("title", act),
+ xs_html_attr("class", xs_join(class, " ")),
+ xs_html_attr("style", style));
+ }
+ }
+ if (ret) {
+ xs *s1;
+ if (user) {
+ xs *action = xs_fmt("%s/admin/action", user->actor);
+ xs *form_id = xs_fmt("%s_reply_form", md5);
+
+ xs_html *form =
+ xs_html_tag("form",
+ xs_html_attr("autocomplete", "off"),
+ xs_html_attr("method", "post"),
+ xs_html_attr("action", action),
+ xs_html_attr("enctype", "multipart/form-data"),
+ xs_html_attr("style", "display: inline-flex;"
+ "vertical-align: middle;"),
+ xs_html_attr("id", form_id),
+ xs_html_sctag("input",
+ xs_html_attr("type", "hidden"),
+ xs_html_attr("name", "id"),
+ xs_html_attr("value", id)),
+ xs_html_sctag("input",
+ xs_html_attr("type", "hidden"),
+ xs_html_attr("name", "eid"),
+ xs_html_attr("value", shortname)),
+ ret);
+ s1 = xs_html_render(form);
+ }
+ else
+ s1 = xs_html_render(ret);
+
+ ls = xs_list_append(ls, s1);
+ sfrl = xs_dict_del(sfrl, content);
+ }
+ }
+ }
+ }
+
+ c = 0;
+
+ xs_html *emoji_div;
+ if (xs_list_len(ls) > 0) {
+ emoji_div = xs_html_tag("div", xs_html_text(L("Emoji reactions: ")),
+ xs_html_attr("class", "snac-reaction-div"));
+
+ while (ls != NULL && xs_list_next(ls, &k, &c))
+ xs_html_add(emoji_div, xs_html_raw(k));
+
+ xs_html_add(snac_content_wrap, emoji_div);
+ }
+
+ }
+
{
/** build the content string **/
const char *content = xs_dict_get(msg, "content");
@@ -2371,7 +2630,8 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
c = xs_replace_i(c, "
", "
"); - c = xs_str_cat(c, "
"); + if (is_emoji == 0) + c = xs_str_cat(c, "
");
/* replace the :shortnames: */
c = replace_shortnames(c, xs_dict_get(msg, "tag"), 2, proxy);
@@ -3686,9 +3946,18 @@ xs_str *html_notifications(snac *user, int skip, int show)
if (strcmp(type, "EmojiReact") == 0 || strcmp(type, "Like") == 0) {
const char *content = xs_dict_get_path(noti, "msg.content");
+ xs *cd = xs_dup(content);
+ const char *sna = cd;
+ const xs_dict *tag = xs_dict_get_path(noti, "msg.tag");
+ unsigned int utf = xs_utf8_dec((const char **)&sna);
+
+ int isEmoji = 0;
+ if (xs_is_emoji(utf) || (tag && xs_list_len(tag) > 0))
+ isEmoji = 1;
+
if (xs_type(content) == XSTYPE_STRING) {
xs *emoji = replace_shortnames(xs_dup(content), xs_dict_get_path(noti, "msg.tag"), 1, proxy);
- wrk = xs_fmt("%s (%s️)", type, emoji);
+ wrk = xs_fmt("%s (%s️)", isEmoji ? "EmojiReact" : "Like", emoji);
label = wrk;
}
}
@@ -4583,8 +4852,8 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs *msg = msg_admiration(&snac, id, *action == 'L' ? "Like" : "Announce");
if (msg != NULL) {
+ timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, *action == 'L' ? 1 : 0, msg);
enqueue_message(&snac, msg);
- timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, *action == 'L' ? 1 : 0);
status = HTTP_STATUS_SEE_OTHER;
}
@@ -4892,12 +5161,36 @@ int html_post_handler(const xs_dict *req, const char *q_path,
status = HTTP_STATUS_SEE_OTHER;
+ if (strcmp(action, L("EmojiUnreact")) == 0) { /** **/
+ const char *eid = xs_dict_get(p_vars, "eid");
+
+ if (eid != NULL) {
+ xs *n_msg = msg_emoji_unreact(&snac, id, eid);
+
+ if (n_msg != NULL)
+ enqueue_message(&snac, n_msg);
+ }
+ }
+ else
+ if (strcmp(action, L("EmojiReact")) == 0) { /** **/
+ const char *eid = xs_dict_get(p_vars, "eid");
+
+ eid = xs_strip_chars_i(xs_dup(eid), ":");
+
+ const xs_dict *ret = msg_emoji_init(&snac, id, eid);
+ /* fails if either invalid or already reacted */
+ if (!ret)
+ ret = msg_emoji_unreact(&snac, id, eid);
+ if (!ret)
+ status = HTTP_STATUS_NOT_FOUND;
+ }
+ else
if (strcmp(action, L("Like")) == 0) { /** **/
xs *msg = msg_admiration(&snac, id, "Like");
if (msg != NULL) {
+ timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, 1, msg);
enqueue_message(&snac, msg);
- timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, 1);
}
}
else
@@ -4905,8 +5198,8 @@ int html_post_handler(const xs_dict *req, const char *q_path,
xs *msg = msg_admiration(&snac, id, "Announce");
if (msg != NULL) {
+ timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, 0, msg);
enqueue_message(&snac, msg);
- timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, 0);
}
}
else
--
cgit v1.2.3
From 7c065cbc9879582985cef3d3ad8b2ae197b8b851 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Thu, 18 Dec 2025 08:09:10 +0100
Subject: Fixed some xs_dup() leaks.
---
html.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 8cc0067..dae84b7 100644
--- a/html.c
+++ b/html.c
@@ -5173,9 +5173,9 @@ int html_post_handler(const xs_dict *req, const char *q_path,
}
else
if (strcmp(action, L("EmojiReact")) == 0) { /** **/
- const char *eid = xs_dict_get(p_vars, "eid");
+ xs *eid = xs_dup(xs_dict_get(p_vars, "eid"));
- eid = xs_strip_chars_i(xs_dup(eid), ":");
+ eid = xs_strip_chars_i(eid, ":");
const xs_dict *ret = msg_emoji_init(&snac, id, eid);
/* fails if either invalid or already reacted */
--
cgit v1.2.3
From ce667add2cfedcc6d57c521899dfb9d2e3e6e1d7 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Thu, 18 Dec 2025 08:13:54 +0100
Subject: Fixed some xs_join() uses.
---
html.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index dae84b7..6ee0707 100644
--- a/html.c
+++ b/html.c
@@ -72,8 +72,10 @@ xs_str *_replace_shortnames(xs_str *s, const xs_list *tag, int ems,
xs *style = xs_fmt("max-height: %dem; max-width: %dem;", ems, ems);
xs *class = xs_fmt("snac-emoji snac-emoji-%d-em", ems);
- if (cl)
- class = xs_str_cat(class, " ", xs_join(cl, " "));
+ if (cl) {
+ xs *l = xs_join(cl, " ");
+ class = xs_str_cat(class, " ", l);
+ }
int c = 0;
const xs_val *v;
@@ -2501,9 +2503,10 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
if (!xs_is_null(nb)) {
is_emoji = 1;
- const char *act = atoi(nb) > 1 ?
- xs_fmt("%d different actors \n\t%s", atoi(nb), xs_join(actors, ",\n\t")) :
- xs_dict_get(m, "actor");
+ xs *al = xs_join(actors, ",\n\t");
+ xs *act = atoi(nb) > 1 ?
+ xs_fmt("%d different actors \n\t%s", atoi(nb), al) :
+ xs_dup(xs_dict_get(m, "actor"));
xs *class = xs_list_new();
class = xs_list_append(class, "snac-reaction");
@@ -2517,6 +2520,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
if (me)
class = xs_list_append(class, "snac-reacted");
+ xs *l1 = xs_join(class, " ");
ret = xs_html_tag("button",
xs_html_attr("type", "submit"),
xs_html_attr("name", "action"),
@@ -2526,7 +2530,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
xs_html_raw(nb),
xs_html_attr("style", "padding-left: 5px;")),
xs_html_attr("title", act),
- xs_html_attr("class", xs_join(class, " ")));
+ xs_html_attr("class", l1));
if (!(ide && xs_startswith(ide, srv_baseurl)))
xs_html_add(ret, xs_html_attr("disabled", "true"));
@@ -2540,6 +2544,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
const char *style = "font-size: large;";
if (me)
class = xs_list_append(class, "snac-reacted");
+ xs *l1 = xs_join(class, " ");
ret = xs_html_tag("button",
xs_html_attr("type", "submit"),
xs_html_attr("name", "action"),
@@ -2549,7 +2554,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
xs_html_raw(nb),
xs_html_attr("style", "font-size: initial; padding-left: 5px;")),
xs_html_attr("title", act),
- xs_html_attr("class", xs_join(class, " ")),
+ xs_html_attr("class", l1),
xs_html_attr("style", style));
}
}
--
cgit v1.2.3
From c8ee70f6df7276b7c02f902cc544d209139697b2 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Thu, 18 Dec 2025 08:20:15 +0100
Subject: Fixed some xs_fmt() usages.
---
html.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 6ee0707..c317c1a 100644
--- a/html.c
+++ b/html.c
@@ -55,7 +55,7 @@ int login(snac *user, const xs_dict *headers)
}
xs_str *_replace_shortnames(xs_str *s, const xs_list *tag, int ems,
- const char *proxy, const xs_list *cl, const char *act)
+ const char *proxy, const xs_list *cl, const char *act_o)
/* replace but also adds a class list and an actor in its alt text.
* Used for emoji reactions */
{
@@ -107,7 +107,7 @@ xs_str *_replace_shortnames(xs_str *s, const xs_list *tag, int ems,
if (!xs_is_string(mt))
mt = xs_mime_by_ext(u);
- act = act ? xs_fmt("%s\n%s", n, act) : xs_fmt("%s", n);
+ xs *act = act_o ? xs_fmt("%s\n%s", n, act) : xs_fmt("%s", n);
if (strcmp(mt, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg")))
s = xs_replace_i(s, n, "");
@@ -2479,7 +2479,9 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
}
xs *fl = xs_list_new();
- fl = xs_list_append(fl, xs_fmt("%d", count), actors, xs_fmt("%d", me));
+ xs *c1 = xs_fmt("%d", count);
+ xs *c2 = xs_fmt("%d", me);
+ fl = xs_list_append(fl, c1, actors, c2);
sfrl = xs_dict_append(sfrl, content, fl);
}
}
@@ -2545,11 +2547,12 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
if (me)
class = xs_list_append(class, "snac-reacted");
xs *l1 = xs_join(class, " ");
+ xs *s1 = xs_fmt("%d", utf);
ret = xs_html_tag("button",
xs_html_attr("type", "submit"),
xs_html_attr("name", "action"),
xs_html_attr("value", me ? L("EmojiUnreact") : L("EmojiReact")),
- xs_html_raw(xs_fmt("%d", utf)),
+ xs_html_raw(s1),
xs_html_tag("span",
xs_html_raw(nb),
xs_html_attr("style", "font-size: initial; padding-left: 5px;")),
--
cgit v1.2.3
From 219f3e6808bdcf8a03cce404caa5cb6a008d00c5 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Thu, 18 Dec 2025 08:54:21 +0100
Subject: Fixed leak in emoji_reacted().
---
html.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index c317c1a..48273f2 100644
--- a/html.c
+++ b/html.c
@@ -2107,14 +2107,15 @@ xs_html *html_entry_controls(snac *user, const char *actor,
/* the post textarea */
xs *div_id = xs_fmt("%s_reply", md5);
xs *form_id = xs_fmt("%s_reply_form", md5);
+ xs *e_react = emoji_reacted(user, id);
xs_html_add(controls, xs_html_tag("div",
xs_html_tag("p", NULL),
html_emoji(
- user, L("Emoji react"),
+ user, L("Emoji react..."),
div_id, form_id,
":neocat:", id,
- emoji_reacted(user, id))),
+ e_react)),
xs_html_tag("p", NULL));
}
--
cgit v1.2.3
From 2903b29e653d8549319ceabbb65de408d2e5c073 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Thu, 18 Dec 2025 08:58:04 +0100
Subject: Fixed more minor leaks.
---
html.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 48273f2..8700ac4 100644
--- a/html.c
+++ b/html.c
@@ -2454,8 +2454,8 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
xs *sfrl = xs_dict_new();
xs *rl = object_get_emoji_reacts(id);
- xs_dict *m = NULL;
while (xs_list_next(rl, &v, &c)) {
+ xs *m = NULL;
if (valid_status(object_get_by_md5(v, &m))) {
const char *content = xs_dict_get(m, "content");
const char *actor = xs_dict_get(m, "actor");
@@ -2490,6 +2490,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
c = 0;
while (xs_list_next(rl, &k, &c)) {
+ xs *m = NULL;
if (valid_status(object_get_by_md5(k, &m))) {
const xs_dict *tag = xs_dict_get(m, "tag");
const xs_dict *ide = xs_dict_get(m, "id");
--
cgit v1.2.3
From da6d275933e9dac513386ac2bc567d3568ab0217 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Thu, 18 Dec 2025 09:45:55 +0100
Subject: Strip surrounding colons in emoji pictures, if they are still there.
---
html.c | 2 ++
1 file changed, 2 insertions(+)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 8700ac4..e59e622 100644
--- a/html.c
+++ b/html.c
@@ -2521,6 +2521,8 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
cl = xs_list_append(cl, "snac-reaction-image");
xs *emoji = _replace_shortnames(xs_dup(shortname), tag, 2, proxy, cl, act);
+ emoji = xs_strip_chars_i(emoji, ":");
+
if (me)
class = xs_list_append(class, "snac-reacted");
--
cgit v1.2.3
From 9f3f8d237ac32f60c8471515dcb64095f1c4ccd6 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Thu, 18 Dec 2025 10:02:43 +0100
Subject: Fixed typo.
---
html.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index e59e622..f1b004b 100644
--- a/html.c
+++ b/html.c
@@ -107,7 +107,7 @@ xs_str *_replace_shortnames(xs_str *s, const xs_list *tag, int ems,
if (!xs_is_string(mt))
mt = xs_mime_by_ext(u);
- xs *act = act_o ? xs_fmt("%s\n%s", n, act) : xs_fmt("%s", n);
+ xs *act = act_o ? xs_fmt("%s\n%s", n, act_o) : xs_fmt("%s", n);
if (strcmp(mt, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg")))
s = xs_replace_i(s, n, "");
--
cgit v1.2.3
From e233f3f904e64d6ecaffdf68f8532e1587681fe3 Mon Sep 17 00:00:00 2001
From: violette
Date: Fri, 19 Dec 2025 09:54:50 +0100
Subject: Some fixes.
---
html.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index f1b004b..f6c93c7 100644
--- a/html.c
+++ b/html.c
@@ -2500,11 +2500,12 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
shortname = xs_dict_get(m, "content");
const xs_list *items = xs_dict_get(sfrl, content);
- const char *nb = xs_list_get(items, 0);
- const xs_list *actors = xs_list_get(items, 1);
- const char me = *xs_list_get(items, 2) == '1';
- if (!xs_is_null(nb)) {
+ if (!xs_is_null(items)) {
+ const char *nb = xs_list_get(items, 0);
+ const xs_list *actors = xs_list_get(items, 1);
+ const char me = *xs_list_get(items, 2) == '1';
+
is_emoji = 1;
xs *al = xs_join(actors, ",\n\t");
--
cgit v1.2.3
From a97d3ac11628cd9244f97d2304d972abfb2b4824 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Fri, 19 Dec 2025 15:27:51 +0100
Subject: Reindex tags when editing a post.
Tags that were deleted in the post message are not deleted, though.
---
html.c | 3 +++
1 file changed, 3 insertions(+)
(limited to 'html.c')
diff --git a/html.c b/html.c
index f6c93c7..0b84e56 100644
--- a/html.c
+++ b/html.c
@@ -5141,6 +5141,9 @@ int html_post_handler(const xs_dict *req, const char *q_path,
/* overwrite object, not updating the indexes */
object_add_ow(edit_id, msg);
+ /* index tags */
+ tag_index(edit_id, msg);
+
/* update message */
c_msg = msg_update(&snac, msg);
}
--
cgit v1.2.3
From 79c32485dffa95107216c2251ffa111d7cdef432 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Sat, 20 Dec 2025 13:15:34 +0100
Subject: Fixed failed search when blank surround the query string.
---
html.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 0b84e56..20ad839 100644
--- a/html.c
+++ b/html.c
@@ -4343,9 +4343,13 @@ int html_get_handler(const xs_dict *req, const char *q_path,
status = HTTP_STATUS_UNAUTHORIZED;
}
else {
- const char *q = xs_dict_get(q_vars, "q");
+ xs *q = NULL;
+ const char *q1 = xs_dict_get(q_vars, "q");
xs *url_acct = NULL;
+ if (xs_is_string(q1))
+ q = xs_strip_i(xs_dup(q1));
+
/* searching for an URL? */
if (q && xs_match(q, "https://*|http://*")) {
/* may by an actor; try a webfinger */
--
cgit v1.2.3
From a1f0a89931ad1ac51e28c318e29ef7f1cfc25255 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Fri, 26 Dec 2025 21:15:19 +0100
Subject: Revert "Fixed failed search when blank surround the query string."
This reverts commit 79c32485dffa95107216c2251ffa111d7cdef432.
---
html.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 20ad839..0b84e56 100644
--- a/html.c
+++ b/html.c
@@ -4343,13 +4343,9 @@ int html_get_handler(const xs_dict *req, const char *q_path,
status = HTTP_STATUS_UNAUTHORIZED;
}
else {
- xs *q = NULL;
- const char *q1 = xs_dict_get(q_vars, "q");
+ const char *q = xs_dict_get(q_vars, "q");
xs *url_acct = NULL;
- if (xs_is_string(q1))
- q = xs_strip_i(xs_dup(q1));
-
/* searching for an URL? */
if (q && xs_match(q, "https://*|http://*")) {
/* may by an actor; try a webfinger */
--
cgit v1.2.3
From be4dd4ea7f58a31546ad873d5b464fdb8b289ec8 Mon Sep 17 00:00:00 2001
From: grunfink
Date: Fri, 26 Dec 2025 21:24:08 +0100
Subject: Fixed failed search when blank surround the query string.
This time, without fucking up everything.
---
html.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
(limited to 'html.c')
diff --git a/html.c b/html.c
index 0b84e56..3e692bd 100644
--- a/html.c
+++ b/html.c
@@ -4343,9 +4343,15 @@ int html_get_handler(const xs_dict *req, const char *q_path,
status = HTTP_STATUS_UNAUTHORIZED;
}
else {
- const char *q = xs_dict_get(q_vars, "q");
+ const char *q = NULL;
+ xs *cq = xs_dup(xs_dict_get(q_vars, "q"));
xs *url_acct = NULL;
+ if (xs_is_string(cq)) {
+ cq = xs_strip_i(cq);
+ q = cq;
+ }
+
/* searching for an URL? */
if (q && xs_match(q, "https://*|http://*")) {
/* may by an actor; try a webfinger */
--
cgit v1.2.3
From b64bebd412f10e7a29f92220624e8423aaf5d883 Mon Sep 17 00:00:00 2001
From: Alexandre Oliva
Date: Sun, 28 Dec 2025 20:59:12 +0100
Subject: introduce separate people/ pages
When you have lots of followers or followees or pending follows,
constructing the entire people page to look up information about a
single user can take a while and be quite wasteful when you want to
look up a single user. Introduce and prefer people/ breaks page, cannot nest them */
+ ret = xs_replace_i(xs_dup(pronouns), " ", "");
+ ret = xs_replace_i(ret, " breaks page, cannot nest them */
- ret = xs_replace_i(xs_dup(pronouns), " ", "");
- ret = xs_replace_i(ret, "