From 128cc54608fc4ecbf8c9f93eb2c45eddd81a2fe6 Mon Sep 17 00:00:00 2001 From: green Date: Sat, 22 Mar 2025 19:37:23 +0100 Subject: Added tittle text and class to custom emojis --- html.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index 78a9854..3d8f0e1 100644 --- a/html.c +++ b/html.c @@ -93,6 +93,8 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p xs_html_attr("loading", "lazy"), xs_html_attr("src", url), xs_html_attr("alt", n), + xs_html_attr("title", n), + xs_html_attr("class", "snac-emoji"), xs_html_attr("style", style)); xs *s1 = xs_html_render(img); -- cgit v1.2.3 From 307aab92be9b9e0ea7676e05b1c752371ed0f7b9 Mon Sep 17 00:00:00 2001 From: default Date: Mon, 24 Mar 2025 17:29:17 +0100 Subject: In replace_shortnames(), avoid repeated emojis. --- html.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index 78a9854..abb8562 100644 --- a/html.c +++ b/html.c @@ -72,6 +72,9 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p const xs_dict *v; int c = 0; + xs_set rep_emoji; + xs_set_init(&rep_emoji); + while (xs_list_next(tag_list, &v, &c)) { const char *t = xs_dict_get(v, "type"); @@ -79,6 +82,10 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p const char *n = xs_dict_get(v, "name"); const xs_dict *i = xs_dict_get(v, "icon"); + /* avoid repeated emojis (Misskey seems to return this) */ + if (xs_set_add(&rep_emoji, n) == 0) + continue; + if (xs_is_string(n) && xs_is_dict(i)) { const char *u = xs_dict_get(i, "url"); const char *mt = xs_dict_get(i, "mediaType"); @@ -104,6 +111,8 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p } } } + + xs_set_free(&rep_emoji); } return s; -- cgit v1.2.3 From e8b00b31906e316598e26e92a9b156a42ff5a860 Mon Sep 17 00:00:00 2001 From: default Date: Mon, 31 Mar 2025 20:23:24 +0200 Subject: Added some code for the future. --- html.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index d549f75..115e8c4 100644 --- a/html.c +++ b/html.c @@ -559,6 +559,30 @@ xs_html *html_note(snac *user, const char *summary, xs_html_text(L("End in 1 day")))))); } +#if 0 + /* scheduled post data */ + xs *sched_date = xs_dup(""); + xs *sched_time = xs_dup(""); + + xs_html_add(form, + xs_html_tag("p", NULL), + xs_html_tag("details", + xs_html_tag("summary", + xs_html_text(L("Scheduled post..."))), + xs_html_tag("p", + xs_html_text(L("Post date: ")), + xs_html_sctag("input", + xs_html_attr("type", "date"), + xs_html_attr("value", sched_date), + xs_html_attr("name", "post_date")), + xs_html_text(" "), + xs_html_text(L("Post time: ")), + xs_html_sctag("input", + xs_html_attr("type", "time"), + xs_html_attr("value", sched_time), + xs_html_attr("name", "post_time"))))); +#endif + xs_html_add(form, xs_html_tag("p", NULL), xs_html_sctag("input", @@ -4186,12 +4210,14 @@ int html_post_handler(const xs_dict *req, const char *q_path, snac_debug(&snac, 1, xs_fmt("web action '%s' received", p_path)); /* post note */ - const xs_str *content = xs_dict_get(p_vars, "content"); - const xs_str *in_reply_to = xs_dict_get(p_vars, "in_reply_to"); - const xs_str *to = xs_dict_get(p_vars, "to"); - const xs_str *sensitive = xs_dict_get(p_vars, "sensitive"); - const xs_str *summary = xs_dict_get(p_vars, "summary"); - const xs_str *edit_id = xs_dict_get(p_vars, "edit_id"); + const char *content = xs_dict_get(p_vars, "content"); + const char *in_reply_to = xs_dict_get(p_vars, "in_reply_to"); + const char *to = xs_dict_get(p_vars, "to"); + const char *sensitive = xs_dict_get(p_vars, "sensitive"); + const char *summary = xs_dict_get(p_vars, "summary"); + const char *edit_id = xs_dict_get(p_vars, "edit_id"); + const char *post_date = xs_dict_get_def(p_vars, "post_date", ""); + const char *post_time = xs_dict_get_def(p_vars, "post_time", ""); int priv = !xs_is_null(xs_dict_get(p_vars, "mentioned_only")); int store_as_draft = !xs_is_null(xs_dict_get(p_vars, "is_draft")); xs *attach_list = xs_list_new(); @@ -4279,6 +4305,23 @@ int html_post_handler(const xs_dict *req, const char *q_path, msg = xs_dict_set(msg, "summary", xs_is_null(summary) ? "..." : summary); } + if (*post_date) { + /* scheduled post */ + xs *sched_date = xs_fmt("%sT%s:00", post_date, *post_time ? post_time : "12:00"); + time_t t = xs_parse_localtime(sched_date, "%Y-%m-%dT%H:%M:%S"); + + if (t != 0) { + xs *iso_date = xs_str_iso_date(t); + msg = xs_dict_set(msg, "published", iso_date); + + snac_debug(&snac, 1, xs_fmt("Scheduled date: [%s]", iso_date)); + } + else { + snac_log(&snac, xs_fmt("Invalid scheduled date: [%s]", sched_date)); + post_date = ""; + } + } + if (xs_is_null(edit_id)) { /* new message */ const char *id = xs_dict_get(msg, "id"); -- cgit v1.2.3 From 1e21c2271e0ae55dbe69ce9ff033589a239a3f95 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 1 Apr 2025 05:47:08 +0200 Subject: Some more work for future posts. --- html.c | 111 +++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 44 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 115e8c4..d4cbb35 100644 --- a/html.c +++ b/html.c @@ -350,7 +350,7 @@ xs_html *html_note(snac *user, const char *summary, const xs_val *mnt_only, const char *redir, const char *in_reply_to, int poll, const xs_list *att_files, const xs_list *att_alt_texts, - int is_draft) + int is_draft, const char *published) /* Yes, this is a FUCKTON of arguments and I'm a bit embarrased */ { xs *action = xs_fmt("%s/admin/note", user->actor); @@ -440,6 +440,34 @@ xs_html *html_note(snac *user, const char *summary, xs_html_attr("name", "is_draft"), xs_html_attr(is_draft ? "checked" : "", NULL)))); + /* post date and time */ + xs *post_date = NULL; + xs *post_time = NULL; + + if (xs_is_string(published)) { + time_t t = xs_parse_iso_date(published, 0); + + if (t > 0) { + post_date = xs_str_time(t, "%Y-%m-%d", 1); + post_time = xs_str_time(t, "%H:%M:%S", 1); + } + } + + xs_html_add(form, + xs_html_tag("p", + xs_html_text(L("Post date and time (empty, right now; in the future, schedule for later):")), + xs_html_sctag("br", NULL), + xs_html_sctag("input", + xs_html_attr("type", "date"), + xs_html_attr("value", post_date ? post_date : ""), + xs_html_attr("name", "post_date")), + xs_html_text(" "), + xs_html_sctag("input", + xs_html_attr("type", "time"), + xs_html_attr("value", post_time ? post_time : ""), + xs_html_attr("step", "1"), + xs_html_attr("name", "post_time")))); + if (edit_id) xs_html_add(form, xs_html_sctag("input", @@ -559,30 +587,6 @@ xs_html *html_note(snac *user, const char *summary, xs_html_text(L("End in 1 day")))))); } -#if 0 - /* scheduled post data */ - xs *sched_date = xs_dup(""); - xs *sched_time = xs_dup(""); - - xs_html_add(form, - xs_html_tag("p", NULL), - xs_html_tag("details", - xs_html_tag("summary", - xs_html_text(L("Scheduled post..."))), - xs_html_tag("p", - xs_html_text(L("Post date: ")), - xs_html_sctag("input", - xs_html_attr("type", "date"), - xs_html_attr("value", sched_date), - xs_html_attr("name", "post_date")), - xs_html_text(" "), - xs_html_text(L("Post time: ")), - xs_html_sctag("input", - xs_html_attr("type", "time"), - xs_html_attr("value", sched_time), - xs_html_attr("name", "post_time"))))); -#endif - xs_html_add(form, xs_html_tag("p", NULL), xs_html_sctag("input", @@ -1151,7 +1155,7 @@ xs_html *html_top_controls(snac *user) NULL, NULL, xs_stock(XSTYPE_FALSE), "", xs_stock(XSTYPE_FALSE), NULL, - NULL, 1, NULL, NULL, 0), + NULL, 1, NULL, NULL, 0, NULL), /** operations **/ xs_html_tag("details", @@ -1809,7 +1813,8 @@ xs_html *html_entry_controls(snac *user, const char *actor, id, NULL, xs_dict_get(msg, "sensitive"), xs_dict_get(msg, "summary"), xs_stock(is_msg_public(msg) ? XSTYPE_FALSE : XSTYPE_TRUE), redir, - NULL, 0, att_files, att_alt_texts, is_draft(user, id))), + NULL, 0, att_files, att_alt_texts, is_draft(user, id), + xs_dict_get(msg, "published"))), xs_html_tag("p", NULL)); } @@ -1828,7 +1833,7 @@ xs_html *html_entry_controls(snac *user, const char *actor, NULL, NULL, xs_dict_get(msg, "sensitive"), xs_dict_get(msg, "summary"), xs_stock(is_msg_public(msg) ? XSTYPE_FALSE : XSTYPE_TRUE), redir, - id, 0, NULL, NULL, 0)), + id, 0, NULL, NULL, 0, NULL)), xs_html_tag("p", NULL)); } @@ -3165,7 +3170,7 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c NULL, actor_id, xs_stock(XSTYPE_FALSE), "", xs_stock(XSTYPE_FALSE), NULL, - NULL, 0, NULL, NULL, 0), + NULL, 0, NULL, NULL, 0, NULL), xs_html_tag("p", NULL)); xs_html_add(snac_post, snac_controls); @@ -4305,23 +4310,29 @@ int html_post_handler(const xs_dict *req, const char *q_path, msg = xs_dict_set(msg, "summary", xs_is_null(summary) ? "..." : summary); } - if (*post_date) { - /* scheduled post */ - xs *sched_date = xs_fmt("%sT%s:00", post_date, *post_time ? post_time : "12:00"); - time_t t = xs_parse_localtime(sched_date, "%Y-%m-%dT%H:%M:%S"); + if (xs_is_string(post_date) && *post_date) { + xs *local_pubdate = xs_fmt("%sT%s", post_date, + xs_is_string(post_time) && *post_time ? post_time : "00:00:00"); + + time_t t = xs_parse_iso_date(local_pubdate, 1); if (t != 0) { xs *iso_date = xs_str_iso_date(t); msg = xs_dict_set(msg, "published", iso_date); - snac_debug(&snac, 1, xs_fmt("Scheduled date: [%s]", iso_date)); - } - else { - snac_log(&snac, xs_fmt("Invalid scheduled date: [%s]", sched_date)); - post_date = ""; + snac_debug(&snac, 1, xs_fmt("Published date: [%s]", iso_date)); } + else + snac_log(&snac, xs_fmt("Invalid post date: [%s]", local_pubdate)); } + /* is the published date from the future? */ + int future_post = 0; + xs *right_now = xs_str_utctime(0, ISO_DATE_SPEC); + + if (strcmp(xs_dict_get(msg, "published"), right_now) > 0) + future_post = 1; + if (xs_is_null(edit_id)) { /* new message */ const char *id = xs_dict_get(msg, "id"); @@ -4329,6 +4340,10 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (store_as_draft) { draft_add(&snac, id, msg); } + else + if (future_post) { + snac_log(&snac, xs_fmt("DUMMY scheduled post 1 %s", id)); + } else { c_msg = msg_create(&snac, msg); timeline_add(&snac, id, msg); @@ -4340,7 +4355,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (valid_status(object_get(edit_id, &p_msg))) { /* copy relevant fields from previous version */ - char *fields[] = { "id", "context", "url", "published", + char *fields[] = { "id", "context", "url", "to", "inReplyTo", NULL }; int n; @@ -4356,15 +4371,23 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (is_draft(&snac, edit_id)) { /* message was previously a draft; it's a create activity */ - /* set the published field to now */ - xs *published = xs_str_utctime(0, ISO_DATE_SPEC); - msg = xs_dict_set(msg, "published", published); + /* if the date is from the past, overwrite it with right_now */ + if (strcmp(xs_dict_get(msg, "published"), right_now) < 0) { + snac_debug(&snac, 1, xs_fmt("setting draft ancient date to %s", right_now)); + msg = xs_dict_set(msg, "published", right_now); + } /* overwrite object */ object_add_ow(edit_id, msg); - c_msg = msg_create(&snac, msg); - timeline_add(&snac, edit_id, msg); + if (future_post) { + snac_log(&snac, xs_fmt("DUMMY scheduled post 2 %s", edit_id)); + } + else { + c_msg = msg_create(&snac, msg); + timeline_add(&snac, edit_id, msg); + } + draft_del(&snac, edit_id); } else { -- cgit v1.2.3 From 5090e4e77489d7e4e2d358c417c83be8f76307cb Mon Sep 17 00:00:00 2001 From: default Date: Tue, 1 Apr 2025 06:14:46 +0200 Subject: Added more scheduling code. --- html.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index d4cbb35..bc8a645 100644 --- a/html.c +++ b/html.c @@ -2870,6 +2870,18 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, xs_html_text(L("drafts"))))); } + { + /* show the list of scheduled posts */ + xs *url = xs_fmt("%s/sched", user->actor); + xs_html_add(lol, + xs_html_tag("li", + xs_html_tag("a", + xs_html_attr("href", url), + xs_html_attr("class", "snac-list-link"), + xs_html_attr("title", L("Scheduled posts")), + xs_html_text(L("scheduled posts"))))); + } + /* the list of followed hashtags */ const char *followed_hashtags = xs_dict_get(user->config, "followed_hashtags"); @@ -3919,6 +3931,21 @@ int html_get_handler(const xs_dict *req, const char *q_path, } } else + if (strcmp(p_path, "sched") == 0) { /** list of scheduled posts **/ + if (!login(&snac, req)) { + *body = xs_dup(uid); + status = HTTP_STATUS_UNAUTHORIZED; + } + else { + xs *list = scheduled_list(&snac); + + *body = html_timeline(&snac, list, 0, skip, show, + 0, L("Scheduled posts"), "", 0, error); + *b_size = strlen(*body); + status = HTTP_STATUS_OK; + } + } + else if (xs_startswith(p_path, "list/")) { /** list timelines **/ if (!login(&snac, req)) { *body = xs_dup(uid); @@ -4342,7 +4369,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, } else if (future_post) { - snac_log(&snac, xs_fmt("DUMMY scheduled post 1 %s", id)); + schedule_add(&snac, id, msg); } else { c_msg = msg_create(&snac, msg); @@ -4381,7 +4408,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, object_add_ow(edit_id, msg); if (future_post) { - snac_log(&snac, xs_fmt("DUMMY scheduled post 2 %s", edit_id)); + schedule_add(&snac, edit_id, msg); } else { c_msg = msg_create(&snac, msg); @@ -4390,7 +4417,15 @@ int html_post_handler(const xs_dict *req, const char *q_path, draft_del(&snac, edit_id); } + else + if (is_scheduled(&snac, edit_id)) { + /* editing an scheduled post; just update it */ + schedule_add(&snac, edit_id, msg); + } else { + /* ignore the (possibly changed) published date */ + msg = xs_dict_set(msg, "published", xs_dict_get(p_msg, "published")); + /* set the updated field */ xs *updated = xs_str_utctime(0, ISO_DATE_SPEC); msg = xs_dict_set(msg, "updated", updated); @@ -4474,6 +4509,9 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (strcmp(action, L("Hide")) == 0) { /** **/ if (is_draft(&snac, id)) draft_del(&snac, id); + else + if (is_scheduled(&snac, id)) + schedule_del(&snac, id); else hide(&snac, id); } @@ -4570,6 +4608,8 @@ int html_post_handler(const xs_dict *req, const char *q_path, draft_del(&snac, id); + schedule_del(&snac, id); + snac_log(&snac, xs_fmt("deleted entry %s", id)); } } -- cgit v1.2.3 From dde907f55a6c63f7d1bb8345f7850b51cd028a7b Mon Sep 17 00:00:00 2001 From: default Date: Tue, 1 Apr 2025 09:02:35 +0200 Subject: Only show date edition controls if it's new, drafted or scheduled. --- html.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index bc8a645..008c05b 100644 --- a/html.c +++ b/html.c @@ -453,20 +453,22 @@ xs_html *html_note(snac *user, const char *summary, } } - xs_html_add(form, - xs_html_tag("p", - xs_html_text(L("Post date and time (empty, right now; in the future, schedule for later):")), - xs_html_sctag("br", NULL), - xs_html_sctag("input", - xs_html_attr("type", "date"), - xs_html_attr("value", post_date ? post_date : ""), - xs_html_attr("name", "post_date")), - xs_html_text(" "), - xs_html_sctag("input", - xs_html_attr("type", "time"), - xs_html_attr("value", post_time ? post_time : ""), - xs_html_attr("step", "1"), - xs_html_attr("name", "post_time")))); + if (edit_id == NULL || is_draft || is_scheduled(user, edit_id)) { + xs_html_add(form, + xs_html_tag("p", + xs_html_text(L("Post date and time (empty, right now; in the future, schedule for later):")), + xs_html_sctag("br", NULL), + xs_html_sctag("input", + xs_html_attr("type", "date"), + xs_html_attr("value", post_date ? post_date : ""), + xs_html_attr("name", "post_date")), + xs_html_text(" "), + xs_html_sctag("input", + xs_html_attr("type", "time"), + xs_html_attr("value", post_time ? post_time : ""), + xs_html_attr("step", "1"), + xs_html_attr("name", "post_time")))); + } if (edit_id) xs_html_add(form, -- cgit v1.2.3 From 3cec0d3ebeeef595f509c52e6c0ac3682ba67e6f Mon Sep 17 00:00:00 2001 From: default Date: Fri, 4 Apr 2025 08:07:56 +0200 Subject: Vote objects no longer have a content of "". --- html.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index 008c05b..25a2e90 100644 --- a/html.c +++ b/html.c @@ -4824,6 +4824,9 @@ int html_post_handler(const xs_dict *req, const char *q_path, /* set the option */ msg = xs_dict_append(msg, "name", v); + /* delete the content */ + msg = xs_dict_del(msg, "content"); + xs *c_msg = msg_create(&snac, msg); enqueue_message(&snac, c_msg); -- cgit v1.2.3 From bb5a2445dac94a4d90b7d455b7723416a3df13ba Mon Sep 17 00:00:00 2001 From: default Date: Fri, 4 Apr 2025 16:48:11 +0200 Subject: Added a (CSS hidden) hr tag after each post. --- html.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index 25a2e90..eff55e7 100644 --- a/html.c +++ b/html.c @@ -2731,6 +2731,11 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } } + /* add an invisible hr, to help differentiate between posts in text browsers */ + xs_html_add(entry_top, + xs_html_sctag("hr", + xs_html_attr("style", "display: none"))); + return entry_top; } -- cgit v1.2.3 From 9f6d34eddadafbd79bc608c1cb650d9c90b5a0d3 Mon Sep 17 00:00:00 2001 From: default Date: Sat, 5 Apr 2025 13:51:03 +0200 Subject: Use instead of 'display: none' style. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index eff55e7..5ede8f9 100644 --- a/html.c +++ b/html.c @@ -2734,7 +2734,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, /* add an invisible hr, to help differentiate between posts in text browsers */ xs_html_add(entry_top, xs_html_sctag("hr", - xs_html_attr("style", "display: none"))); + xs_html_attr("hidden", NULL))); return entry_top; } -- cgit v1.2.3 From 7f7d42c52db934da6af8d3cdd7c03dd95a08cbaf Mon Sep 17 00:00:00 2001 From: default Date: Sun, 6 Apr 2025 07:44:12 +0200 Subject: Post attachments now have random names. --- html.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 5ede8f9..9ff5625 100644 --- a/html.c +++ b/html.c @@ -14,6 +14,7 @@ #include "xs_curl.h" #include "xs_unicode.h" #include "xs_url.h" +#include "xs_random.h" #include "snac.h" @@ -4286,9 +4287,12 @@ int html_post_handler(const xs_dict *req, const char *q_path, const char *fn = xs_list_get(attach_file, 0); if (xs_is_string(fn) && *fn != '\0') { + char rnd[32]; + xs_rnd_buf(rnd, sizeof(rnd)); + char *ext = strrchr(fn, '.'); - xs *hash = xs_md5_hex(fn, strlen(fn)); - xs *id = xs_fmt("%s%s", hash, ext); + xs *hash = xs_md5_hex(rnd, strlen(rnd)); + xs *id = xs_fmt("p-%s%s", hash, ext ? ext : ""); xs *url = xs_fmt("%s/s/%s", snac.actor, id); int fo = xs_number_get(xs_list_get(attach_file, 1)); int fs = xs_number_get(xs_list_get(attach_file, 2)); -- cgit v1.2.3 From 6f884e0d5d4eb9be41764c5ae16da52fed997e88 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 6 Apr 2025 07:50:51 +0200 Subject: The avatar and header images have a prefix in their names. --- html.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 9ff5625..a598038 100644 --- a/html.c +++ b/html.c @@ -4290,9 +4290,9 @@ int html_post_handler(const xs_dict *req, const char *q_path, char rnd[32]; xs_rnd_buf(rnd, sizeof(rnd)); - char *ext = strrchr(fn, '.'); + const char *ext = strrchr(fn, '.'); xs *hash = xs_md5_hex(rnd, strlen(rnd)); - xs *id = xs_fmt("p-%s%s", hash, ext ? ext : ""); + xs *id = xs_fmt("post-%s%s", hash, ext ? ext : ""); xs *url = xs_fmt("%s/s/%s", snac.actor, id); int fo = xs_number_get(xs_list_get(attach_file, 1)); int fs = xs_number_get(xs_list_get(attach_file, 2)); @@ -4764,7 +4764,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (xs_startswith(mimetype, "image/")) { const char *ext = strrchr(fn, '.'); xs *hash = xs_md5_hex(fn, strlen(fn)); - xs *id = xs_fmt("%s%s", hash, ext); + xs *id = xs_fmt("%s-%s%s", uploads[n], hash, ext ? ext : ""); xs *url = xs_fmt("%s/s/%s", snac.actor, id); int fo = xs_number_get(xs_list_get(uploaded_file, 1)); int fs = xs_number_get(xs_list_get(uploaded_file, 2)); -- cgit v1.2.3 From 32b7fa2fcb8d77cab49f0b17af75669139901859 Mon Sep 17 00:00:00 2001 From: default Date: Thu, 10 Apr 2025 08:25:35 +0200 Subject: Shorten link label in Attachments. --- html.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index a598038..e303d72 100644 --- a/html.c +++ b/html.c @@ -2439,13 +2439,19 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, name = NULL; } else { + xs *d_href = xs_dup(o_href); + if (strlen(d_href) > 64) { + d_href[64] = '\0'; + d_href = xs_str_cat(d_href, "..."); + } + xs_html_add(content_attachments, xs_html_tag("p", xs_html_tag("a", xs_html_attr("href", o_href), xs_html_text(L("Attachment")), xs_html_text(": "), - xs_html_text(o_href)))); + xs_html_text(d_href)))); /* do not generate an Alt... */ name = NULL; -- cgit v1.2.3 From cbe25ddb853281aa800befea31e8f6dac0206411 Mon Sep 17 00:00:00 2001 From: default Date: Thu, 10 Apr 2025 08:40:54 +0200 Subject: Hide the scheduled post date and time behind a 'details'. --- html.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index e303d72..b5d8946 100644 --- a/html.c +++ b/html.c @@ -457,18 +457,22 @@ xs_html *html_note(snac *user, const char *summary, if (edit_id == NULL || is_draft || is_scheduled(user, edit_id)) { xs_html_add(form, xs_html_tag("p", - xs_html_text(L("Post date and time (empty, right now; in the future, schedule for later):")), - xs_html_sctag("br", NULL), - xs_html_sctag("input", - xs_html_attr("type", "date"), - xs_html_attr("value", post_date ? post_date : ""), - xs_html_attr("name", "post_date")), - xs_html_text(" "), - xs_html_sctag("input", - xs_html_attr("type", "time"), - xs_html_attr("value", post_time ? post_time : ""), - xs_html_attr("step", "1"), - xs_html_attr("name", "post_time")))); + xs_html_tag("details", + xs_html_tag("summary", + xs_html_text(L("Scheduled post..."))), + xs_html_tag("p", + xs_html_text(L("Post date and time:")), + xs_html_sctag("br", NULL), + xs_html_sctag("input", + xs_html_attr("type", "date"), + xs_html_attr("value", post_date ? post_date : ""), + xs_html_attr("name", "post_date")), + xs_html_text(" "), + xs_html_sctag("input", + xs_html_attr("type", "time"), + xs_html_attr("value", post_time ? post_time : ""), + xs_html_attr("step", "1"), + xs_html_attr("name", "post_time")))))); } if (edit_id) -- cgit v1.2.3 From 9a238a937e31b36e7ee35109c09764019ee3af1f Mon Sep 17 00:00:00 2001 From: default Date: Sun, 13 Apr 2025 09:23:43 +0200 Subject: Added some preliminary support for time zones (for scheduled posts). --- html.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index b5d8946..afbc716 100644 --- a/html.c +++ b/html.c @@ -4359,19 +4359,23 @@ int html_post_handler(const xs_dict *req, const char *q_path, } if (xs_is_string(post_date) && *post_date) { - xs *local_pubdate = xs_fmt("%sT%s", post_date, + xs *post_pubdate = xs_fmt("%sT%s", post_date, xs_is_string(post_time) && *post_time ? post_time : "00:00:00"); - time_t t = xs_parse_iso_date(local_pubdate, 1); + time_t t = xs_parse_iso_date(post_pubdate, 0); if (t != 0) { + const char *tz = xs_dict_get_def(snac.config, "tz", "UTC"); + + t -= xs_tz_offset(tz); + xs *iso_date = xs_str_iso_date(t); msg = xs_dict_set(msg, "published", iso_date); snac_debug(&snac, 1, xs_fmt("Published date: [%s]", iso_date)); } else - snac_log(&snac, xs_fmt("Invalid post date: [%s]", local_pubdate)); + snac_log(&snac, xs_fmt("Invalid post date: [%s]", post_pubdate)); } /* is the published date from the future? */ -- cgit v1.2.3 From f1f288699805b13bcd8f296667923ae5d2ae45ed Mon Sep 17 00:00:00 2001 From: default Date: Sun, 13 Apr 2025 09:33:17 +0200 Subject: Fixed offset sign because I'm a MORON. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index afbc716..b04e001 100644 --- a/html.c +++ b/html.c @@ -4367,7 +4367,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (t != 0) { const char *tz = xs_dict_get_def(snac.config, "tz", "UTC"); - t -= xs_tz_offset(tz); + t += xs_tz_offset(tz); xs *iso_date = xs_str_iso_date(t); msg = xs_dict_set(msg, "published", iso_date); -- cgit v1.2.3 From fb9e0fd21b7210e2ff71cc364b2285b1231fff60 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 13 Apr 2025 10:04:31 +0200 Subject: Mention the timezone in the 'post date and time' prompt. --- html.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index b04e001..68a6b73 100644 --- a/html.c +++ b/html.c @@ -455,13 +455,15 @@ xs_html *html_note(snac *user, const char *summary, } if (edit_id == NULL || is_draft || is_scheduled(user, edit_id)) { + xs *pdat = xs_fmt(L("Post date and time (timezone: %s):"), xs_dict_get_def(user->config, "tz", "UTC")); + xs_html_add(form, xs_html_tag("p", xs_html_tag("details", xs_html_tag("summary", xs_html_text(L("Scheduled post..."))), xs_html_tag("p", - xs_html_text(L("Post date and time:")), + xs_html_text(pdat), xs_html_sctag("br", NULL), xs_html_sctag("input", xs_html_attr("type", "date"), -- cgit v1.2.3 From 81538904210e9092760ce7c6b043eaaa166509b6 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 13 Apr 2025 14:12:37 +0200 Subject: More timezone tweaks. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 68a6b73..a6f79de 100644 --- a/html.c +++ b/html.c @@ -4369,7 +4369,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (t != 0) { const char *tz = xs_dict_get_def(snac.config, "tz", "UTC"); - t += xs_tz_offset(tz); + t -= xs_tz_offset(tz); xs *iso_date = xs_str_iso_date(t); msg = xs_dict_set(msg, "published", iso_date); -- cgit v1.2.3 From 848bd3e865fb2daf75d76cbb75a4a39f9b82b516 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 13 Apr 2025 14:30:50 +0200 Subject: Cache the timezone inside the snac struct. --- html.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index a6f79de..2e7f87c 100644 --- a/html.c +++ b/html.c @@ -455,7 +455,7 @@ xs_html *html_note(snac *user, const char *summary, } if (edit_id == NULL || is_draft || is_scheduled(user, edit_id)) { - xs *pdat = xs_fmt(L("Post date and time (timezone: %s):"), xs_dict_get_def(user->config, "tz", "UTC")); + xs *pdat = xs_fmt(L("Post date and time (timezone: %s):"), user->tz); xs_html_add(form, xs_html_tag("p", @@ -4367,9 +4367,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, time_t t = xs_parse_iso_date(post_pubdate, 0); if (t != 0) { - const char *tz = xs_dict_get_def(snac.config, "tz", "UTC"); - - t -= xs_tz_offset(tz); + t -= xs_tz_offset(snac.tz); xs *iso_date = xs_str_iso_date(t); msg = xs_dict_set(msg, "published", iso_date); -- cgit v1.2.3 From 251d31e10e7ab70d9480b2e056d1d76260de7046 Mon Sep 17 00:00:00 2001 From: green Date: Sat, 22 Mar 2025 20:44:27 +0100 Subject: emoji in external bios (i hope) --- html.c | 1 + 1 file changed, 1 insertion(+) (limited to 'html.c') diff --git a/html.c b/html.c index 68a6b73..428d64e 100644 --- a/html.c +++ b/html.c @@ -3112,6 +3112,7 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c if (!xs_is_null(c)) { xs *sc = sanitize(c); + sc = replace_shortnames(sc, xs_dict_get(actor, "tag"), 2, proxy); xs_html *snac_content = xs_html_tag("div", xs_html_attr("class", "snac-content")); -- cgit v1.2.3 From 7f10057cff51748f7fb96021dc755127991cdbf9 Mon Sep 17 00:00:00 2001 From: green Date: Sat, 22 Mar 2025 21:31:01 +0100 Subject: fixed broken emojis on akkoma --- html.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 428d64e..a70f303 100644 --- a/html.c +++ b/html.c @@ -91,8 +91,18 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p const char *u = xs_dict_get(i, "url"); const char *mt = xs_dict_get(i, "mediaType"); - if (xs_is_string(u) && xs_is_string(mt)) { - if (strcmp(mt, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg"))) + if (xs_is_string(u)) { + // on akkoma instances mediaType is not present. + // but we need to to know if the image is an svg or not. + // for now, i just use the file extention, which may not be the most reliable... + int is_svg = 0; + if (xs_is_string(mt)) { + is_svg = (strcmp(mt, "image/svg+xml") == 0); + } else { + is_svg = xs_endswith(u, ".svg"); + } + + if (is_svg && !xs_is_true(xs_dict_get(srv_config, "enable_svg"))) s = xs_replace_i(s, n, ""); else { xs *url = make_url(u, proxy, 0); @@ -3112,6 +3122,10 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c if (!xs_is_null(c)) { xs *sc = sanitize(c); + + // replace shortnames in bio + // bug: this somehow fires twice on one specific user + // @ielenia@ck.catwithaclari.net sc = replace_shortnames(sc, xs_dict_get(actor, "tag"), 2, proxy); xs_html *snac_content = xs_html_tag("div", -- cgit v1.2.3 From a28638b4c18abacabd02fef4a51dde80bf4d5db4 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 13 Apr 2025 14:39:46 +0200 Subject: More timezone work. --- html.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index 2e7f87c..d807f4b 100644 --- a/html.c +++ b/html.c @@ -1318,6 +1318,27 @@ xs_html *html_top_controls(snac *user) xs_html_attr("value", lang))); } + /* timezone */ + xs_html *tz_select = xs_html_tag("select", + xs_html_attr("name", "tz")); + + xs *tzs = xs_tz_list(); + const char *tz; + + xs_list_foreach(tzs, tz) { + if (strcmp(tz, user->tz) == 0) + xs_html_add(tz_select, + xs_html_tag("option", + xs_html_text(tz), + xs_html_attr("value", tz), + xs_html_attr("selected", "selected"))); + else + xs_html_add(tz_select, + xs_html_tag("option", + xs_html_text(tz), + xs_html_attr("value", tz))); + } + xs *user_setup_action = xs_fmt("%s/admin/user-setup", user->actor); xs_html_add(top_controls, @@ -1513,6 +1534,11 @@ xs_html *html_top_controls(snac *user) xs_html_sctag("br", NULL), lang_select), + xs_html_tag("p", + xs_html_text(L("Time zone:")), + xs_html_sctag("br", NULL), + tz_select), + xs_html_tag("p", xs_html_text(L("New password:")), xs_html_sctag("br", NULL), @@ -4755,6 +4781,8 @@ int html_post_handler(const xs_dict *req, const char *q_path, snac.config = xs_dict_set(snac.config, "show_contact_metrics", xs_stock(XSTYPE_FALSE)); if ((v = xs_dict_get(p_vars, "web_ui_lang")) != NULL) snac.config = xs_dict_set(snac.config, "lang", v); + if ((v = xs_dict_get(p_vars, "tz")) != NULL) + snac.config = xs_dict_set(snac.config, "tz", v); snac.config = xs_dict_set(snac.config, "latitude", xs_dict_get_def(p_vars, "latitude", "")); snac.config = xs_dict_set(snac.config, "longitude", xs_dict_get_def(p_vars, "longitude", "")); -- cgit v1.2.3 From 5fd3823e14639931177656a51e71b74d886d4f9a Mon Sep 17 00:00:00 2001 From: green Date: Mon, 24 Mar 2025 02:44:58 +0100 Subject: emojis in usernames in web ui --- html.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index a70f303..b31897b 100644 --- a/html.c +++ b/html.c @@ -980,10 +980,16 @@ static xs_html *html_user_body(snac *user, int read_only) xs_dict_get(user->config, "uid"), xs_dict_get(srv_config, "host")); + // also try to make emojis render in local usernames, specifically in the user info thing in the web ui + xs *name_tags = xs_list_new(); + xs *name1 = not_really_markdown(xs_dict_get(user->config, "name"), NULL, &name_tags); + xs *name2 = sanitize(name1); + name2 = replace_shortnames(name2, name_tags, 1, proxy); + xs_html_add(top_user, xs_html_tag("p", xs_html_attr("class", "p-name snac-top-user-name"), - xs_html_text(xs_dict_get(user->config, "name"))), + xs_html_raw(name2)), xs_html_tag("p", xs_html_attr("class", "snac-top-user-id"), xs_html_text(handle))); -- cgit v1.2.3 From 544a20fb2ae81fcdf1103f37d6c57428a8d401c4 Mon Sep 17 00:00:00 2001 From: green Date: Mon, 24 Mar 2025 11:24:39 +0100 Subject: EmojiReact notifications show up as emojis --- html.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index b31897b..3c5903d 100644 --- a/html.c +++ b/html.c @@ -3350,7 +3350,8 @@ xs_str *html_notifications(snac *user, int skip, int show) continue; xs *a_name = actor_name(actor, proxy); - const char *label = type; + xs *label_sanatized = sanitize(type); + const char *label = label_sanatized; if (strcmp(type, "Create") == 0) label = L("Mention"); @@ -3365,7 +3366,8 @@ xs_str *html_notifications(snac *user, int skip, int show) const char *content = xs_dict_get_path(noti, "msg.content"); if (xs_type(content) == XSTYPE_STRING) { - wrk = xs_fmt("%s (%s)", type, content); + xs *emoji = replace_shortnames(xs_dup(content), xs_dict_get_path(noti, "msg.tag"), 1, proxy); + wrk = xs_fmt("%s (%s)", type, emoji); label = wrk; } } @@ -3377,7 +3379,7 @@ xs_str *html_notifications(snac *user, int skip, int show) xs_html *this_html_label = xs_html_container( xs_html_tag("b", - xs_html_text(label), + xs_html_raw(label), xs_html_text(" by "), xs_html_tag("a", xs_html_attr("href", actor_id), -- cgit v1.2.3 From 4408859f8dcb8f83670d75f1128e1120ea318ec9 Mon Sep 17 00:00:00 2001 From: green Date: Mon, 24 Mar 2025 12:47:15 +0100 Subject: also display the emoji for likes --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 3c5903d..103ce3d 100644 --- a/html.c +++ b/html.c @@ -3362,7 +3362,7 @@ xs_str *html_notifications(snac *user, int skip, int show) if (strcmp(type, "Undo") == 0 && strcmp(utype, "Follow") == 0) label = L("Unfollow"); else - if (strcmp(type, "EmojiReact") == 0) { + if (strcmp(type, "EmojiReact") == 0 || strcmp(type, "Like") == 0) { const char *content = xs_dict_get_path(noti, "msg.content"); if (xs_type(content) == XSTYPE_STRING) { -- cgit v1.2.3 From fbd81b604315f569ce5714fdc9d3caa78daaa83a Mon Sep 17 00:00:00 2001 From: green Date: Wed, 26 Mar 2025 01:40:14 +0100 Subject: mime types for apng and svg check --- html.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 103ce3d..c8015a1 100644 --- a/html.c +++ b/html.c @@ -95,14 +95,10 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p // on akkoma instances mediaType is not present. // but we need to to know if the image is an svg or not. // for now, i just use the file extention, which may not be the most reliable... - int is_svg = 0; - if (xs_is_string(mt)) { - is_svg = (strcmp(mt, "image/svg+xml") == 0); - } else { - is_svg = xs_endswith(u, ".svg"); - } + if (!xs_is_string(mt)) + mt = xs_mime_by_ext(u); - if (is_svg && !xs_is_true(xs_dict_get(srv_config, "enable_svg"))) + if (strcmp(mt, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg"))) s = xs_replace_i(s, n, ""); else { xs *url = make_url(u, proxy, 0); -- cgit v1.2.3 From 21a99e55081a58f1396d49fb70824f91a8e7c2ab Mon Sep 17 00:00:00 2001 From: green Date: Wed, 9 Apr 2025 03:09:53 +0200 Subject: emoji: refactor + emoji in display names on front page --- html.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index c8015a1..f3d5ee9 100644 --- a/html.c +++ b/html.c @@ -143,6 +143,26 @@ xs_str *actor_name(xs_dict *actor, const char *proxy) } +xs_str *format_text_with_emoji(snac *user, const char *text, int ems, const char *proxy) +/* needed when we have local text with no tags attached */ +{ + xs *tags = xs_list_new(); + xs *name1 = not_really_markdown(text, NULL, &tags); + + xs_str *name3; + if (user) { + xs *name2 = process_tags(user, name1, &tags); + name3 = sanitize(name2); + } + else { + name3 = sanitize(name1); + name3 = xs_replace_i(name3, "
", ""); + } + + return replace_shortnames(name3, tags, ems, proxy); +} + + xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, const char *udate, const char *url, int priv, int in_people, const char *proxy, const char *lang, @@ -976,16 +996,12 @@ static xs_html *html_user_body(snac *user, int read_only) xs_dict_get(user->config, "uid"), xs_dict_get(srv_config, "host")); - // also try to make emojis render in local usernames, specifically in the user info thing in the web ui - xs *name_tags = xs_list_new(); - xs *name1 = not_really_markdown(xs_dict_get(user->config, "name"), NULL, &name_tags); - xs *name2 = sanitize(name1); - name2 = replace_shortnames(name2, name_tags, 1, proxy); + xs *display_name = format_text_with_emoji(NULL, xs_dict_get(user->config, "name"), 1, proxy); xs_html_add(top_user, xs_html_tag("p", xs_html_attr("class", "p-name snac-top-user-name"), - xs_html_raw(name2)), + xs_html_raw(display_name)), xs_html_tag("p", xs_html_attr("class", "snac-top-user-id"), xs_html_text(handle))); @@ -1013,16 +1029,11 @@ static xs_html *html_user_body(snac *user, int read_only) } if (read_only) { - xs *tags = xs_list_new(); - xs *bio1 = not_really_markdown(xs_dict_get(user->config, "bio"), NULL, &tags); - xs *bio2 = process_tags(user, bio1, &tags); - xs *bio3 = sanitize(bio2); - - bio3 = replace_shortnames(bio3, tags, 2, proxy); + xs *bio = format_text_with_emoji(user, xs_dict_get(user->config, "bio"), 2, proxy); xs_html *top_user_bio = xs_html_tag("div", xs_html_attr("class", "p-note snac-top-user-bio"), - xs_html_raw(bio3)); /* already sanitized */ + xs_html_raw(bio)); /* already sanitized */ xs_html_add(top_user, top_user_bio); @@ -3675,7 +3686,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, if (xs_is_true(xs_dict_get(srv_config, "strict_public_timelines"))) list = timeline_simple_list(&snac, "public", skip, show, &more); - else + else list = timeline_list(&snac, "public", skip, show, &more); xs *pins = pinned_list(&snac); -- cgit v1.2.3 From 1a6c3c5e815933e42f1b0be0e0fa2d44ac78036b Mon Sep 17 00:00:00 2001 From: green Date: Sun, 23 Mar 2025 02:32:47 +0100 Subject: better control over the emoji class --- html.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index f3d5ee9..be89453 100644 --- a/html.c +++ b/html.c @@ -69,6 +69,7 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p } xs *style = xs_fmt("height: %dem; width: %dem; vertical-align: middle;", ems, ems); + xs *class = xs_fmt("snac-emoji snac-emoji-%d-em", ems); const xs_dict *v; int c = 0; @@ -108,7 +109,7 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p xs_html_attr("src", url), xs_html_attr("alt", n), xs_html_attr("title", n), - xs_html_attr("class", "snac-emoji"), + xs_html_attr("class", class), xs_html_attr("style", style)); xs *s1 = xs_html_render(img); -- cgit v1.2.3 From 13c9306abe425eeea710bc11e08da8d3fddbeaf2 Mon Sep 17 00:00:00 2001 From: green Date: Sun, 13 Apr 2025 15:04:19 +0200 Subject: emoji variant selector in react notifications --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index be89453..1cd9dd9 100644 --- a/html.c +++ b/html.c @@ -3375,7 +3375,7 @@ xs_str *html_notifications(snac *user, int skip, int show) 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️)", type, emoji); label = wrk; } } -- cgit v1.2.3 From 0c03e6c9d9a6b65fede94cc9eab34a05746f8d5e Mon Sep 17 00:00:00 2001 From: green Date: Sun, 13 Apr 2025 15:44:24 +0200 Subject: cleaned up old changes and outdated comments --- html.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 1cd9dd9..b9f2419 100644 --- a/html.c +++ b/html.c @@ -3136,10 +3136,6 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c if (!xs_is_null(c)) { xs *sc = sanitize(c); - - // replace shortnames in bio - // bug: this somehow fires twice on one specific user - // @ielenia@ck.catwithaclari.net sc = replace_shortnames(sc, xs_dict_get(actor, "tag"), 2, proxy); xs_html *snac_content = xs_html_tag("div", -- cgit v1.2.3 From 610fc0917d21ac0dfb0fb5b125fe8004af03a8ca Mon Sep 17 00:00:00 2001 From: grunfink Date: Tue, 22 Apr 2025 15:47:55 +0200 Subject: Added an alt to avatars. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index d807f4b..e3a955b 100644 --- a/html.c +++ b/html.c @@ -189,7 +189,7 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, xs_html_attr("loading", "lazy"), xs_html_attr("class", "snac-avatar"), xs_html_attr("src", avatar), - xs_html_attr("alt", "")), + xs_html_attr("alt", "[?]")), xs_html_tag("a", xs_html_attr("href", href), xs_html_attr("class", "p-author h-card snac-author"), -- cgit v1.2.3 From 136b7c1581ae6e4aac4a1e4fa04340eb9aab7943 Mon Sep 17 00:00:00 2001 From: grunfink Date: Sat, 3 May 2025 18:23:54 +0200 Subject: No longer drop text/html attachements. --- html.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index e3a955b..288968d 100644 --- a/html.c +++ b/html.c @@ -2392,10 +2392,6 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, if (content && xs_str_in(content, o_href) != -1) continue; - /* drop silently any attachment that may include JavaScript */ - if (strcmp(type, "text/html") == 0) - continue; - if (strcmp(type, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg"))) continue; -- cgit v1.2.3 From 6878e3fc939c3dac9853a3a33bfab7a289c7648b Mon Sep 17 00:00:00 2001 From: grunfink Date: Sat, 3 May 2025 18:55:10 +0200 Subject: Also add direct and markdown links in posts as attachments. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 288968d..0652892 100644 --- a/html.c +++ b/html.c @@ -2388,7 +2388,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, const char *o_href = xs_dict_get(a, "href"); const char *name = xs_dict_get(a, "name"); - /* if this image is already in the post content, skip */ + /* if this URL is already in the post content, skip */ if (content && xs_str_in(content, o_href) != -1) continue; -- cgit v1.2.3 From 605b60c06ea882cd61df7f2d834c02cce6dd254d Mon Sep 17 00:00:00 2001 From: grunfink Date: Sat, 3 May 2025 19:16:21 +0200 Subject: New function enqueue_webmention(). The q_msg is queued, but nothing is done yet. --- html.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 0652892..e114ea7 100644 --- a/html.c +++ b/html.c @@ -4488,8 +4488,10 @@ int html_post_handler(const xs_dict *req, const char *q_path, snac_log(&snac, xs_fmt("cannot get object '%s' for editing", edit_id)); } - if (c_msg != NULL) + if (c_msg != NULL) { enqueue_message(&snac, c_msg); + enqueue_webmention(msg); + } history_del(&snac, "timeline.html_"); } -- cgit v1.2.3 From ee84140ecceb07dad8ea36cc5aa29b91bbb48a56 Mon Sep 17 00:00:00 2001 From: grunfink Date: Sun, 18 May 2025 08:23:48 +0200 Subject: Added a pending follow request count next to the "people" link. --- html.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index aec7d0a..6c7af51 100644 --- a/html.c +++ b/html.c @@ -923,7 +923,9 @@ static xs_html *html_user_body(snac *user, int read_only) } else { int n_len = notify_new_num(user); + int p_len = pending_count(user); xs_html *notify_count = NULL; + xs_html *pending_follow_count = NULL; /* show the number of new notifications, if there are any */ if (n_len) { @@ -935,6 +937,15 @@ static xs_html *html_user_body(snac *user, int read_only) else notify_count = xs_html_text(""); + if (p_len) { + xs *s = xs_fmt(" %d ", p_len); + pending_follow_count = xs_html_tag("sup", + xs_html_attr("style", "background-color: red; color: white;"), + xs_html_text(s)); + } + else + pending_follow_count = xs_html_text(""); + xs *admin_url = xs_fmt("%s/admin", user->actor); xs *notify_url = xs_fmt("%s/notifications", user->actor); xs *people_url = xs_fmt("%s/people", user->actor); @@ -957,6 +968,7 @@ static xs_html *html_user_body(snac *user, int read_only) xs_html_tag("a", xs_html_attr("href", people_url), xs_html_text(L("people"))), + pending_follow_count, xs_html_text(" - "), xs_html_tag("a", xs_html_attr("href", instance_url), -- cgit v1.2.3 From 072ae21013dc924c6bb3378a2480b571a66aba98 Mon Sep 17 00:00:00 2001 From: grunfink Date: Sun, 18 May 2025 09:38:38 +0200 Subject: Operations on the 'people' page redirects back to it instead of 'admin'. --- html.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 6c7af51..b27db7a 100644 --- a/html.c +++ b/html.c @@ -3149,6 +3149,8 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c xs_html_tag("summary", xs_html_text("...")))); + xs *redir = xs_fmt("%s/people", user->actor); + const char *actor_id; xs_list_foreach(list, actor_id) { @@ -3200,6 +3202,10 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c xs_html_attr("type", "hidden"), xs_html_attr("name", "actor"), xs_html_attr("value", actor_id)), + xs_html_sctag("input", + xs_html_attr("type", "hidden"), + xs_html_attr("name", "hard-redir"), + xs_html_attr("value", redir)), xs_html_sctag("input", xs_html_attr("type", "hidden"), xs_html_attr("name", "actor-form"), @@ -5003,12 +5009,19 @@ int html_post_handler(const xs_dict *req, const char *q_path, } if (status == HTTP_STATUS_SEE_OTHER) { - const char *redir = xs_dict_get(p_vars, "redir"); + const char *hard_redir = xs_dict_get(p_vars, "hard-redir"); - if (xs_is_null(redir)) - redir = "top"; + if (xs_is_string(hard_redir)) + *body = xs_dup(hard_redir); + else { + const char *redir = xs_dict_get(p_vars, "redir"); + + if (xs_is_null(redir)) + redir = "top"; + + *body = xs_fmt("%s/admin#%s", snac.actor, redir); + } - *body = xs_fmt("%s/admin#%s", snac.actor, redir); *b_size = strlen(*body); } -- cgit v1.2.3 From 00fd1a1c3eb99c9e441276a7ce8697a1582152b7 Mon Sep 17 00:00:00 2001 From: green Date: Sat, 29 Mar 2025 01:27:46 +0100 Subject: performance: functions to get the number of followers --- html.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index b27db7a..4483dd7 100644 --- a/html.c +++ b/html.c @@ -821,11 +821,7 @@ xs_html *html_user_head(snac *user, const char *desc, const char *url) /* show metrics in og:description? */ if (xs_is_true(xs_dict_get(user->config, "show_contact_metrics"))) { - xs *fwers = follower_list(user); - xs *fwing = following_list(user); - - xs *s1 = xs_fmt(L("%d following, %d followers"), - xs_list_len(fwing), xs_list_len(fwers)); + xs *s1 = xs_fmt(L("%d following, %d followers"), following_list_len(user), follower_list_len(user)); s1 = xs_str_cat(s1, " ยท "); @@ -1166,11 +1162,7 @@ static xs_html *html_user_body(snac *user, int read_only) } if (xs_is_true(xs_dict_get(user->config, "show_contact_metrics"))) { - xs *fwers = follower_list(user); - xs *fwing = following_list(user); - - xs *s1 = xs_fmt(L("%d following, %d followers"), - xs_list_len(fwing), xs_list_len(fwers)); + xs *s1 = xs_fmt(L("%d following, %d followers"), following_list_len(user), follower_list_len(user)); xs_html_add(top_user, xs_html_tag("p", -- cgit v1.2.3 From c950981cca0896558ffae7e66b76f43f1ec49969 Mon Sep 17 00:00:00 2001 From: grunfink Date: Mon, 19 May 2025 20:14:07 +0200 Subject: Improved post language markup. --- html.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index b27db7a..5293dfe 100644 --- a/html.c +++ b/html.c @@ -332,7 +332,8 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, } -xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, const char *proxy, const char *md5) +xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, + const char *proxy, const char *md5, const char *lang) { xs *actor = NULL; xs_html *actor_icon = NULL; @@ -341,7 +342,6 @@ xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, con const char *date = NULL; const char *udate = NULL; const char *url = NULL; - const char *lang = NULL; int priv = 0; const char *type = xs_dict_get(msg, "type"); @@ -353,16 +353,6 @@ xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, con date = xs_dict_get(msg, "published"); udate = xs_dict_get(msg, "updated"); - lang = xs_dict_get(msg, "contentMap"); - if (xs_is_dict(lang)) { - const char *v; - int c = 0; - - xs_dict_next(lang, &lang, &v, &c); - } - else - lang = NULL; - actor_icon = html_actor_icon(user, actor, date, udate, url, priv, 0, proxy, lang, md5); } @@ -1951,6 +1941,15 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, return xs_html_tag("mark", xs_html_text(L("Truncated (too deep)"))); + const char *lang = NULL; + const xs_dict *cmap = xs_dict_get(msg, "contentMap"); + if (xs_is_dict(cmap)) { + const char *dummy; + int c = 0; + + xs_dict_next(cmap, &lang, &dummy, &c); + } + if (strcmp(type, "Follow") == 0) { return xs_html_tag("div", xs_html_attr("class", "snac-post"), @@ -1959,7 +1958,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, xs_html_tag("div", xs_html_attr("class", "snac-origin"), xs_html_text(L("follows you"))), - html_msg_icon(read_only ? NULL : user, xs_dict_get(msg, "actor"), msg, proxy, NULL))); + html_msg_icon(read_only ? NULL : user, xs_dict_get(msg, "actor"), msg, proxy, NULL, lang))); } else if (!xs_match(type, POSTLIKE_OBJECT_TYPE)) { @@ -2140,13 +2139,17 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } xs_html_add(post_header, - html_msg_icon(read_only ? NULL : user, actor, msg, proxy, md5)); + html_msg_icon(read_only ? NULL : user, actor, msg, proxy, md5, lang)); /** post content **/ xs_html *snac_content_wrap = xs_html_tag("div", xs_html_attr("class", "e-content snac-content")); + if (xs_is_string(lang)) + xs_html_add(snac_content_wrap, + xs_html_attr("lang", lang)); + xs_html_add(entry, snac_content_wrap); -- cgit v1.2.3