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(+) 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(-) 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 d19806a72db3585048c57f8940a74ec04f16e125 Mon Sep 17 00:00:00 2001 From: green Date: Mon, 24 Mar 2025 02:27:10 +0100 Subject: maybe a fix for username emojis --- activitypub.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/activitypub.c b/activitypub.c index 4c22c25..ee7c9b1 100644 --- a/activitypub.c +++ b/activitypub.c @@ -1327,6 +1327,11 @@ xs_dict *msg_actor(snac *snac) msg = xs_dict_set(msg, "preferredUsername", snac->uid); msg = xs_dict_set(msg, "published", xs_dict_get(snac->config, "published")); + // this exists so we get the emoji tags from our name too. + // and then we just throw away the result, because it's kinda useless to have markdown in the dysplay name. + // right now, only emojies in bio actually work for local users + xs *name_dummy = not_really_markdown(xs_dict_get(snac->config, "name"), NULL, &tags); + xs *f_bio_2 = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL, &tags); f_bio = process_tags(snac, f_bio_2, &tags); msg = xs_dict_set(msg, "summary", f_bio); -- 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(-) 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(-) 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(-) 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 +++------- xs_mime.h | 1 + 2 files changed, 4 insertions(+), 7 deletions(-) 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); diff --git a/xs_mime.h b/xs_mime.h index 6f65382..5f70922 100644 --- a/xs_mime.h +++ b/xs_mime.h @@ -38,6 +38,7 @@ const char *xs_mime_types[] = { "ogv", "video/ogg", "opus", "audio/ogg", "png", "image/png", + "apng", "image/apng", "svg", "image/svg+xml", "svgz", "image/svg+xml", "txt", "text/plain", -- cgit v1.2.3 From 8c2abef699a98652c290bafd844f8ae2c25eef7f Mon Sep 17 00:00:00 2001 From: green Date: Wed, 26 Mar 2025 01:44:20 +0100 Subject: the fucking list is sotted. oopps --- xs_mime.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs_mime.h b/xs_mime.h index 5f70922..0146385 100644 --- a/xs_mime.h +++ b/xs_mime.h @@ -16,6 +16,7 @@ extern const char *xs_mime_types[]; const char *xs_mime_types[] = { "3gp", "video/3gpp", "aac", "audio/aac", + "apng", "image/apng", "avif", "image/avif", "css", "text/css", "flac", "audio/flac", @@ -38,7 +39,6 @@ const char *xs_mime_types[] = { "ogv", "video/ogg", "opus", "audio/ogg", "png", "image/png", - "apng", "image/apng", "svg", "image/svg+xml", "svgz", "image/svg+xml", "txt", "text/plain", -- cgit v1.2.3 From e251c61382d4cd39ed89876a37962acab1122f84 Mon Sep 17 00:00:00 2001 From: green Date: Tue, 1 Apr 2025 23:08:48 +0200 Subject: allow emoji urls with no extension --- format.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/format.c b/format.c index b2b585d..43dd638 100644 --- a/format.c +++ b/format.c @@ -385,7 +385,8 @@ xs_str *not_really_markdown(const char *content, xs_list **attach, xs_list **tag const char *t = NULL; /* is it an URL to an image? */ - if (xs_startswith(v, "https:/" "/") && xs_startswith((t = xs_mime_by_ext(v)), "image/")) { + if (xs_startswith(v, "https:/" "/") && + (xs_startswith((t = xs_mime_by_ext(v)), "image/") || strrchr(v, '.') == NULL)) { if (tag && xs_str_in(s, k) != -1) { /* add the emoji to the tag list */ xs *e = xs_dict_new(); -- cgit v1.2.3 From 15100ad81941c967ce34cc7534bf9b6d7b585e91 Mon Sep 17 00:00:00 2001 From: green Date: Tue, 1 Apr 2025 23:12:21 +0200 Subject: check the extension in a different way --- format.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/format.c b/format.c index 43dd638..1bb2cf1 100644 --- a/format.c +++ b/format.c @@ -10,6 +10,7 @@ #include "xs_match.h" #include "snac.h" +#include /* emoticons, people laughing and such */ const char *smileys[] = { @@ -382,11 +383,11 @@ xs_str *not_really_markdown(const char *content, xs_list **attach, xs_list **tag const char *k, *v; while (xs_dict_next(d, &k, &v, &c)) { - const char *t = NULL; + const char *t = xs_mime_by_ext(v); /* is it an URL to an image? */ if (xs_startswith(v, "https:/" "/") && - (xs_startswith((t = xs_mime_by_ext(v)), "image/") || strrchr(v, '.') == NULL)) { + (xs_startswith(t, "image/") || strcmp(t, "application/octet-stream") == 0)) { if (tag && xs_str_in(s, k) != -1) { /* add the emoji to the tag list */ xs *e = xs_dict_new(); -- 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 +++++++++++++++++++++++++-------------- httpd.c | 4 +++- snac.h | 1 + 3 files changed, 29 insertions(+), 15 deletions(-) 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); diff --git a/httpd.c b/httpd.c index 22a148d..836c256 100644 --- a/httpd.c +++ b/httpd.c @@ -139,6 +139,8 @@ static xs_str *greeting_html(void) snac user; if (strcmp(uid, "relay") && user_open(&user, uid)) { + xs *formatted_name = format_text_with_emoji(NULL, xs_dict_get(user.config, "name"), 1, NULL); + xs_html_add(ul, xs_html_tag("li", xs_html_tag("a", @@ -148,7 +150,7 @@ static xs_str *greeting_html(void) xs_html_text("@"), xs_html_text(host), xs_html_text(" ("), - xs_html_text(xs_dict_get(user.config, "name")), + xs_html_raw(formatted_name), xs_html_text(")")))); user_free(&user); diff --git a/snac.h b/snac.h index 0d2aafe..90f8bd8 100644 --- a/snac.h +++ b/snac.h @@ -373,6 +373,7 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path, char **body, int *b_size, char **ctype); xs_dict *emojis(void); +xs_str *format_text_with_emoji(snac *user, const char *text, int ems, const char *proxy); xs_str *not_really_markdown(const char *content, xs_list **attach, xs_list **tag); xs_str *sanitize(const char *content); xs_str *encode_html(const char *str); -- 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(-) 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(-) 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 --- activitypub.c | 5 ++--- format.c | 1 - html.c | 4 ---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/activitypub.c b/activitypub.c index ee7c9b1..2403a62 100644 --- a/activitypub.c +++ b/activitypub.c @@ -34,7 +34,7 @@ const char *susie_cool = "+ZcgN7wF7ZVihXkfSlWIVzIA6dbQzaygllpNuTX" "ZmmFNlvxADX1+o0cUPMbAAAAAElFTkSuQmCC"; -const char *susie_muertos = +const char *susie_muertos = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQAAAAC" "CEkxzAAAAV0lEQVQoz4XQsQ0AMQxCUW/A/lv+DT" "ic6zGRolekIMyMELNp8PiCEw6Q4w4NoAt53IH5m" @@ -1328,8 +1328,7 @@ xs_dict *msg_actor(snac *snac) msg = xs_dict_set(msg, "published", xs_dict_get(snac->config, "published")); // this exists so we get the emoji tags from our name too. - // and then we just throw away the result, because it's kinda useless to have markdown in the dysplay name. - // right now, only emojies in bio actually work for local users + // and then we just throw away the result, because it's kinda useless to have markdown in the display name. xs *name_dummy = not_really_markdown(xs_dict_get(snac->config, "name"), NULL, &tags); xs *f_bio_2 = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL, &tags); diff --git a/format.c b/format.c index 1bb2cf1..3089955 100644 --- a/format.c +++ b/format.c @@ -10,7 +10,6 @@ #include "xs_match.h" #include "snac.h" -#include /* emoticons, people laughing and such */ const char *smileys[] = { 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