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