From 09803021648ea958a889cc2aa743d5f8c65ecbae Mon Sep 17 00:00:00 2001 From: default Date: Tue, 11 Feb 2025 19:40:30 +0100 Subject: Don't show the bookmark emoji to strangers. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index e742e94..7b6495b 100644 --- a/html.c +++ b/html.c @@ -1839,7 +1839,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, xs_html_raw(" 📌 "))); } - if (user && is_bookmarked(user, id)) { + if (user && !read_only && is_bookmarked(user, id)) { /* add a bookmark emoji */ xs_html_add(score, xs_html_tag("span", -- cgit From e237a35f0d51683511e87e68c2fe3fd9bdf3ef9e Mon Sep 17 00:00:00 2001 From: default Date: Thu, 13 Feb 2025 19:38:54 +0100 Subject: Drop SVG attachments, as they may include JavaScript. --- html.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index 7b6495b..d713fbb 100644 --- a/html.c +++ b/html.c @@ -2242,6 +2242,11 @@ 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, "image/svg+xml") == 0 || + strcmp(type, "text/html") == 0) + continue; + /* do this attachment include an icon? */ const xs_dict *icon = xs_dict_get(a, "icon"); if (xs_type(icon) == XSTYPE_DICT) { -- cgit From 92a70be7f23577949bc8c50b736fa37086176e20 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 07:04:14 +0100 Subject: Minor string tweak. --- html.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index d713fbb..10ce4ce 100644 --- a/html.c +++ b/html.c @@ -1052,8 +1052,8 @@ static xs_html *html_user_body(snac *user, int read_only) const char *longitude = xs_dict_get_def(user->config, "longitude", ""); if (*latitude && *longitude) { - xs *label = xs_fmt(L("%s,%s"), latitude, longitude); - xs *url = xs_fmt(L("https://openstreetmap.org/search?query=%s,%s"), + xs *label = xs_fmt("%s,%s", latitude, longitude); + xs *url = xs_fmt("https://openstreetmap.org/search?query=%s,%s", latitude, longitude); xs_html_add(top_user, -- cgit From b19b7154534c04de68792175e19eeacbcefe7c44 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 08:58:59 +0100 Subject: Disable "shortnames" of the image/svg+xml mediaType. --- html.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index d713fbb..e45b0b2 100644 --- a/html.c +++ b/html.c @@ -69,7 +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); - const char *v; + const xs_dict *v; int c = 0; while (xs_list_next(tag_list, &v, &c)) { @@ -77,19 +77,25 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p if (t && strcmp(t, "Emoji") == 0) { const char *n = xs_dict_get(v, "name"); - const char *i = xs_dict_get(v, "icon"); + const xs_dict *i = xs_dict_get(v, "icon"); - if (n && i) { + if (xs_is_string(n) && xs_is_dict(i)) { const char *u = xs_dict_get(i, "url"); - xs *url = make_url(u, proxy, 0); + const char *mt = xs_dict_get(i, "mediaType"); + + if (xs_is_string(u) && xs_is_string(mt) && strcmp(mt, "image/svg+xml")) { + xs *url = make_url(u, proxy, 0); - xs_html *img = xs_html_sctag("img", - xs_html_attr("loading", "lazy"), - xs_html_attr("src", url), - xs_html_attr("style", style)); + xs_html *img = xs_html_sctag("img", + xs_html_attr("loading", "lazy"), + xs_html_attr("src", url), + xs_html_attr("style", style)); - xs *s1 = xs_html_render(img); - s = xs_replace_i(s, n, s1); + xs *s1 = xs_html_render(img); + s = xs_replace_i(s, n, s1); + } + else + s = xs_replace_i(s, n, ""); } } } -- cgit From 26d0f5cbc3e07ecec2418b3377d3597c610e5a70 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 09:17:24 +0100 Subject: Some variable renaming. --- html.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 42b9b48..94e55fd 100644 --- a/html.c +++ b/html.c @@ -17,7 +17,7 @@ #include "snac.h" -int login(snac *snac, const xs_dict *headers) +int login(snac *user, const xs_dict *headers) /* tries a login */ { int logged_in = 0; @@ -31,23 +31,23 @@ int login(snac *snac, const xs_dict *headers) xs *l1 = xs_split_n(s2, ":", 1); if (xs_list_len(l1) == 2) { - const char *user = xs_list_get(l1, 0); + const char *uid = xs_list_get(l1, 0); const char *pwd = xs_list_get(l1, 1); const char *addr = xs_or(xs_dict_get(headers, "remote-addr"), xs_dict_get(headers, "x-forwarded-for")); - if (badlogin_check(user, addr)) { - logged_in = check_password(user, pwd, - xs_dict_get(snac->config, "passwd")); + if (badlogin_check(uid, addr)) { + logged_in = check_password(uid, pwd, + xs_dict_get(user->config, "passwd")); if (!logged_in) - badlogin_inc(user, addr); + badlogin_inc(uid, addr); } } } if (logged_in) - lastlog_write(snac, "web"); + lastlog_write(user, "web"); return logged_in; } -- cgit From fc6a975f7b26aaa12136769be20b23a9f67e5a91 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 09:23:56 +0100 Subject: More variable renaming. --- html.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 94e55fd..78a7d32 100644 --- a/html.c +++ b/html.c @@ -1091,16 +1091,16 @@ static xs_html *html_user_body(snac *user, int read_only) } -xs_html *html_top_controls(snac *snac) +xs_html *html_top_controls(snac *user) /* generates the top controls */ { - xs *ops_action = xs_fmt("%s/admin/action", snac->actor); + xs *ops_action = xs_fmt("%s/admin/action", user->actor); xs_html *top_controls = xs_html_tag("div", xs_html_attr("class", "snac-top-controls"), /** new post **/ - html_note(snac, L("New Post..."), + html_note(user, L("New Post..."), "new_post_div", "new_post_form", L("What's on your mind?"), "", NULL, NULL, @@ -1170,53 +1170,53 @@ xs_html *html_top_controls(snac *snac) const char *email = "[disabled by admin]"; if (xs_type(xs_dict_get(srv_config, "disable_email_notifications")) != XSTYPE_TRUE) { - email = xs_dict_get(snac->config_o, "email"); + email = xs_dict_get(user->config_o, "email"); if (xs_is_null(email)) { - email = xs_dict_get(snac->config, "email"); + email = xs_dict_get(user->config, "email"); if (xs_is_null(email)) email = ""; } } - const char *cw = xs_dict_get(snac->config, "cw"); + const char *cw = xs_dict_get(user->config, "cw"); if (xs_is_null(cw)) cw = ""; - const char *telegram_bot = xs_dict_get(snac->config, "telegram_bot"); + const char *telegram_bot = xs_dict_get(user->config, "telegram_bot"); if (xs_is_null(telegram_bot)) telegram_bot = ""; - const char *telegram_chat_id = xs_dict_get(snac->config, "telegram_chat_id"); + const char *telegram_chat_id = xs_dict_get(user->config, "telegram_chat_id"); if (xs_is_null(telegram_chat_id)) telegram_chat_id = ""; - const char *ntfy_server = xs_dict_get(snac->config, "ntfy_server"); + const char *ntfy_server = xs_dict_get(user->config, "ntfy_server"); if (xs_is_null(ntfy_server)) ntfy_server = ""; - const char *ntfy_token = xs_dict_get(snac->config, "ntfy_token"); + const char *ntfy_token = xs_dict_get(user->config, "ntfy_token"); if (xs_is_null(ntfy_token)) ntfy_token = ""; - const char *purge_days = xs_dict_get(snac->config, "purge_days"); + const char *purge_days = xs_dict_get(user->config, "purge_days"); if (!xs_is_null(purge_days) && xs_type(purge_days) == XSTYPE_NUMBER) purge_days = (char *)xs_number_str(purge_days); else purge_days = "0"; - const xs_val *d_dm_f_u = xs_dict_get(snac->config, "drop_dm_from_unknown"); - const xs_val *bot = xs_dict_get(snac->config, "bot"); - const xs_val *a_private = xs_dict_get(snac->config, "private"); - const xs_val *auto_boost = xs_dict_get(snac->config, "auto_boost"); - const xs_val *coll_thrds = xs_dict_get(snac->config, "collapse_threads"); - const xs_val *pending = xs_dict_get(snac->config, "approve_followers"); - const xs_val *show_foll = xs_dict_get(snac->config, "show_contact_metrics"); - const char *latitude = xs_dict_get_def(snac->config, "latitude", ""); - const char *longitude = xs_dict_get_def(snac->config, "longitude", ""); + const xs_val *d_dm_f_u = xs_dict_get(user->config, "drop_dm_from_unknown"); + const xs_val *bot = xs_dict_get(user->config, "bot"); + const xs_val *a_private = xs_dict_get(user->config, "private"); + const xs_val *auto_boost = xs_dict_get(user->config, "auto_boost"); + const xs_val *coll_thrds = xs_dict_get(user->config, "collapse_threads"); + const xs_val *pending = xs_dict_get(user->config, "approve_followers"); + const xs_val *show_foll = xs_dict_get(user->config, "show_contact_metrics"); + const char *latitude = xs_dict_get_def(user->config, "latitude", ""); + const char *longitude = xs_dict_get_def(user->config, "longitude", ""); xs *metadata = NULL; - const xs_dict *md = xs_dict_get(snac->config, "metadata"); + const xs_dict *md = xs_dict_get(user->config, "metadata"); if (xs_type(md) == XSTYPE_DICT) { const xs_str *k; @@ -1238,7 +1238,7 @@ xs_html *html_top_controls(snac *snac) else metadata = xs_str_new(NULL); - xs *user_setup_action = xs_fmt("%s/admin/user-setup", snac->actor); + xs *user_setup_action = xs_fmt("%s/admin/user-setup", user->actor); xs_html_add(top_controls, xs_html_tag("details", @@ -1257,7 +1257,7 @@ xs_html *html_top_controls(snac *snac) xs_html_sctag("input", xs_html_attr("type", "text"), xs_html_attr("name", "name"), - xs_html_attr("value", xs_dict_get(snac->config, "name")), + xs_html_attr("value", xs_dict_get(user->config, "name")), xs_html_attr("placeholder", L("Your name")))), xs_html_tag("p", xs_html_text(L("Avatar: ")), @@ -1287,7 +1287,7 @@ xs_html *html_top_controls(snac *snac) xs_html_attr("cols", "40"), xs_html_attr("rows", "4"), xs_html_attr("placeholder", L("Write about yourself here...")), - xs_html_text(xs_dict_get(snac->config, "bio")))), + xs_html_text(xs_dict_get(user->config, "bio")))), xs_html_sctag("input", xs_html_attr("type", "checkbox"), xs_html_attr("name", "cw"), @@ -1450,8 +1450,8 @@ xs_html *html_top_controls(snac *snac) xs_html_tag("p", NULL))))); - xs *followed_hashtags_action = xs_fmt("%s/admin/followed-hashtags", snac->actor); - xs *followed_hashtags = xs_join(xs_dict_get_def(snac->config, + xs *followed_hashtags_action = xs_fmt("%s/admin/followed-hashtags", user->actor); + xs *followed_hashtags = xs_join(xs_dict_get_def(user->config, "followed_hashtags", xs_stock(XSTYPE_LIST)), "\n"); xs_html_add(top_controls, -- cgit From bf9d8cb202b625b277b775ee5dd0d6a4de336040 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 09:25:57 +0100 Subject: More variable renaming. --- html.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 78a7d32..09a078b 100644 --- a/html.c +++ b/html.c @@ -1502,7 +1502,7 @@ static xs_html *html_button(char *clss, char *label, char *hint) } -xs_str *build_mentions(snac *snac, const xs_dict *msg) +xs_str *build_mentions(snac *user, const xs_dict *msg) /* returns a string with the mentions in msg */ { xs_str *s = xs_str_new(NULL); @@ -1516,7 +1516,7 @@ xs_str *build_mentions(snac *snac, const xs_dict *msg) const char *name = xs_dict_get(v, "name"); if (type && strcmp(type, "Mention") == 0 && - href && strcmp(href, snac->actor) != 0 && name) { + href && strcmp(href, user->actor) != 0 && name) { xs *s1 = NULL; if (name[0] != '@') { -- cgit From 866050306a94f5484bc1bfb3dc20d8761f9bb161 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 09:29:37 +0100 Subject: More variable renaming. --- html.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 09a078b..f860dc1 100644 --- a/html.c +++ b/html.c @@ -1557,7 +1557,7 @@ xs_str *build_mentions(snac *user, const xs_dict *msg) } -xs_html *html_entry_controls(snac *snac, const char *actor, +xs_html *html_entry_controls(snac *user, const char *actor, const xs_dict *msg, const char *md5) { const char *id = xs_dict_get(msg, "id"); @@ -1566,7 +1566,7 @@ xs_html *html_entry_controls(snac *snac, const char *actor, xs *likes = object_likes(id); xs *boosts = object_announces(id); - xs *action = xs_fmt("%s/admin/action", snac->actor); + xs *action = xs_fmt("%s/admin/action", user->actor); xs *redir = xs_fmt("%s_entry", md5); xs_html *form; @@ -1593,8 +1593,8 @@ xs_html *html_entry_controls(snac *snac, const char *actor, xs_html_attr("name", "redir"), xs_html_attr("value", redir)))); - if (!xs_startswith(id, snac->actor)) { - if (xs_list_in(likes, snac->md5) == -1) { + if (!xs_startswith(id, user->actor)) { + if (xs_list_in(likes, user->md5) == -1) { /* not already liked; add button */ xs_html_add(form, html_button("like", L("Like"), L("Say you like this post"))); @@ -1606,7 +1606,7 @@ xs_html *html_entry_controls(snac *snac, const char *actor, } } else { - if (is_pinned(snac, id)) + if (is_pinned(user, id)) xs_html_add(form, html_button("unpin", L("Unpin"), L("Unpin this post from your timeline"))); else @@ -1615,7 +1615,7 @@ xs_html *html_entry_controls(snac *snac, const char *actor, } if (is_msg_public(msg)) { - if (xs_list_in(boosts, snac->md5) == -1) { + if (xs_list_in(boosts, user->md5) == -1) { /* not already boosted; add button */ xs_html_add(form, html_button("boost", L("Boost"), L("Announce this post to your followers"))); @@ -1627,16 +1627,16 @@ xs_html *html_entry_controls(snac *snac, const char *actor, } } - if (is_bookmarked(snac, id)) + if (is_bookmarked(user, id)) xs_html_add(form, html_button("unbookmark", L("Unbookmark"), L("Delete this post from your bookmarks"))); else xs_html_add(form, html_button("bookmark", L("Bookmark"), L("Add this post to your bookmarks"))); - if (strcmp(actor, snac->actor) != 0) { + if (strcmp(actor, user->actor) != 0) { /* controls for other actors than this one */ - if (following_check(snac, actor)) { + if (following_check(user, actor)) { xs_html_add(form, html_button("unfollow", L("Unfollow"), L("Stop following this user's activity"))); } @@ -1646,7 +1646,7 @@ xs_html *html_entry_controls(snac *snac, const char *actor, } if (!xs_is_null(group)) { - if (following_check(snac, group)) { + if (following_check(user, group)) { xs_html_add(form, html_button("unfollow", L("Unfollow Group"), L("Stop following this group or channel"))); @@ -1672,7 +1672,7 @@ xs_html *html_entry_controls(snac *snac, const char *actor, const char *prev_src = xs_dict_get(msg, "sourceContent"); - if (!xs_is_null(prev_src) && strcmp(actor, snac->actor) == 0) { /** edit **/ + if (!xs_is_null(prev_src) && strcmp(actor, user->actor) == 0) { /** edit **/ /* post can be edited */ xs *div_id = xs_fmt("%s_edit", md5); xs *form_id = xs_fmt("%s_edit_form", md5); @@ -1699,26 +1699,26 @@ xs_html *html_entry_controls(snac *snac, const char *actor, xs_html_add(controls, xs_html_tag("div", xs_html_tag("p", NULL), - html_note(snac, L("Edit..."), + html_note(user, L("Edit..."), div_id, form_id, "", prev_src, 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(snac, id))), + NULL, 0, att_files, att_alt_texts, is_draft(user, id))), xs_html_tag("p", NULL)); } { /** reply **/ /* the post textarea */ - xs *ct = build_mentions(snac, msg); + xs *ct = build_mentions(user, msg); xs *div_id = xs_fmt("%s_reply", md5); xs *form_id = xs_fmt("%s_reply_form", md5); xs *redir = xs_fmt("%s_entry", md5); xs_html_add(controls, xs_html_tag("div", xs_html_tag("p", NULL), - html_note(snac, L("Reply..."), + html_note(user, L("Reply..."), div_id, form_id, "", ct, NULL, NULL, -- cgit From c523216bf3fbee74897f15b4526e0ea5bef22c90 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 09:32:37 +0100 Subject: More variable renaming. --- html.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index f860dc1..140d955 100644 --- a/html.c +++ b/html.c @@ -2896,7 +2896,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, } -xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t, const char *proxy) +xs_html *html_people_list(snac *user, xs_list *list, char *header, char *t, const char *proxy) { xs_html *snac_posts; xs_html *people = xs_html_tag("div", @@ -2921,7 +2921,7 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t, cons xs_html_attr("name", md5)), xs_html_tag("div", xs_html_attr("class", "snac-post-header"), - html_actor_icon(snac, actor, xs_dict_get(actor, "published"), + html_actor_icon(user, actor, xs_dict_get(actor, "published"), NULL, NULL, 0, 1, proxy, NULL, NULL))); /* content (user bio) */ @@ -2945,7 +2945,7 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t, cons } /* buttons */ - xs *btn_form_action = xs_fmt("%s/admin/action", snac->actor); + xs *btn_form_action = xs_fmt("%s/admin/action", user->actor); xs_html *snac_controls = xs_html_tag("div", xs_html_attr("class", "snac-controls")); @@ -2965,12 +2965,12 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t, cons xs_html_add(snac_controls, form); - if (following_check(snac, actor_id)) { + if (following_check(user, actor_id)) { xs_html_add(form, html_button("unfollow", L("Unfollow"), L("Stop following this user's activity"))); - if (is_limited(snac, actor_id)) + if (is_limited(user, actor_id)) xs_html_add(form, html_button("unlimit", L("Unlimit"), L("Allow announces (boosts) from this user"))); @@ -2984,12 +2984,12 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t, cons html_button("follow", L("Follow"), L("Start following this user's activity"))); - if (follower_check(snac, actor_id)) + if (follower_check(user, actor_id)) xs_html_add(form, html_button("delete", L("Delete"), L("Delete this user"))); } - if (pending_check(snac, actor_id)) { + if (pending_check(user, actor_id)) { xs_html_add(form, html_button("approve", L("Approve"), L("Approve this follow request"))); @@ -2998,7 +2998,7 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t, cons html_button("discard", L("Discard"), L("Discard this follow request"))); } - if (is_muted(snac, actor_id)) + if (is_muted(user, actor_id)) xs_html_add(form, html_button("unmute", L("Unmute"), L("Stop blocking activities from this user"))); @@ -3013,7 +3013,7 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t, cons xs_html_add(snac_controls, xs_html_tag("p", NULL), - html_note(snac, L("Direct Message..."), + html_note(user, L("Direct Message..."), dm_div_id, dm_form_id, "", "", NULL, actor_id, -- cgit From 02bc18eb118fcd93f5cd90a056f7b78dfe64382f Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 10:04:46 +0100 Subject: Redefined L() to use lang_str(). --- html.c | 15 +++++++++++++-- httpd.c | 2 ++ snac.h | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 140d955..f81cab2 100644 --- a/html.c +++ b/html.c @@ -627,6 +627,9 @@ static xs_html *html_instance_body(void) const char *email = xs_dict_get(srv_config, "admin_email"); const char *acct = xs_dict_get(srv_config, "admin_account"); + /* for L() */ + const snac *user = NULL; + xs *blurb = xs_replace(snac_blurb, "%host%", host); xs_html *dl; @@ -1486,7 +1489,7 @@ xs_html *html_top_controls(snac *user) } -static xs_html *html_button(char *clss, char *label, char *hint) +static xs_html *html_button(const char *clss, const char *label, const char *hint) { xs *c = xs_fmt("snac-btn-%s", clss); @@ -2584,6 +2587,8 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, xs_html *html_footer(void) { + const snac *user = NULL; + return xs_html_tag("div", xs_html_attr("class", "snac-footer"), xs_html_tag("a", @@ -2896,7 +2901,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, } -xs_html *html_people_list(snac *user, xs_list *list, char *header, char *t, const char *proxy) +xs_html *html_people_list(snac *user, xs_list *list, const char *header, const char *t, const char *proxy) { xs_html *snac_posts; xs_html *people = xs_html_tag("div", @@ -3327,6 +3332,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, { const char *accept = xs_dict_get(req, "accept"); int status = HTTP_STATUS_NOT_FOUND; + const snac *user = NULL; snac snac; xs *uid = NULL; const char *p_path; @@ -3393,6 +3399,8 @@ int html_get_handler(const xs_dict *req, const char *q_path, return HTTP_STATUS_NOT_FOUND; } + user = &snac; + if (xs_is_true(xs_dict_get(srv_config, "proxy_media"))) proxy = 1; @@ -4016,6 +4024,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, (void)ctype; int status = 0; + const snac *user = NULL; snac snac; const char *uid; const char *p_path; @@ -4039,6 +4048,8 @@ int html_post_handler(const xs_dict *req, const char *q_path, return HTTP_STATUS_UNAUTHORIZED; } + user = &snac; + p_vars = xs_dict_get(req, "p_vars"); if (p_path && strcmp(p_path, "admin/note") == 0) { /** **/ diff --git a/httpd.c b/httpd.c index d22bb14..22a148d 100644 --- a/httpd.c +++ b/httpd.c @@ -211,6 +211,8 @@ int server_get_handler(xs_dict *req, const char *q_path, { int status = 0; + const snac *user = NULL; + /* is it the server root? */ if (*q_path == '\0' || strcmp(q_path, "/") == 0) { const xs_dict *q_vars = xs_dict_get(req, "q_vars"); diff --git a/snac.h b/snac.h index 69b1b74..e2b6b5f 100644 --- a/snac.h +++ b/snac.h @@ -37,7 +37,7 @@ extern xs_dict *srv_langs; extern int dbglevel; -#define L(s) (s) +#define L(s) lang_str((s), user) #define POSTLIKE_OBJECT_TYPE "Note|Question|Page|Article|Video|Audio|Event" -- cgit From 78bd0263ce56ce8d8544389971daa3d6cdd5c25e Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 10:08:26 +0100 Subject: html_footer() now receives an optional snac *user argument. --- html.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index f81cab2..6a71035 100644 --- a/html.c +++ b/html.c @@ -2585,10 +2585,8 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } -xs_html *html_footer(void) +xs_html *html_footer(const snac *user) { - const snac *user = NULL; - return xs_html_tag("div", xs_html_attr("class", "snac-footer"), xs_html_tag("a", @@ -2895,7 +2893,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, } xs_html_add(body, - html_footer()); + html_footer(user)); return xs_html_render_s(html, "\n"); } @@ -3064,7 +3062,7 @@ xs_str *html_people(snac *user) html_user_head(user, NULL, NULL), xs_html_add(html_user_body(user, 0), lists, - html_footer())); + html_footer(user))); return xs_html_render_s(html, "\n"); } @@ -3314,7 +3312,7 @@ xs_str *html_notifications(snac *user, int skip, int show) xs_set_free(&rep); xs_html_add(body, - html_footer()); + html_footer(user)); /* set the check time to now */ xs *dummy = notify_check_time(user, 1); @@ -3569,7 +3567,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, html_user_head(&snac, NULL, NULL), xs_html_add(html_user_body(&snac, 0), page, - html_footer())); + html_footer(user))); *body = xs_html_render_s(html, "\n"); *b_size = strlen(*body); -- cgit From d8ae88e779d8d27868c5357424132eab48bf18a5 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 18:19:21 +0100 Subject: Some message tweaks. --- html.c | 6 +- po/en.po | 342 +++++++++++++++++++++++++++++++-------------------------------- 2 files changed, 170 insertions(+), 178 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 6a71035..e11abd1 100644 --- a/html.c +++ b/html.c @@ -744,9 +744,11 @@ xs_html *html_user_head(snac *user, const char *desc, const char *url) xs *fwers = follower_list(user); xs *fwing = following_list(user); - xs *s1 = xs_fmt(L("%d following, %d followers · "), + xs *s1 = xs_fmt(L("%d following, %d followers"), xs_list_len(fwing), xs_list_len(fwers)); + s1 = xs_str_cat(s1, " · "); + s_desc = xs_str_prepend_i(s_desc, s1); } @@ -1078,7 +1080,7 @@ static xs_html *html_user_body(snac *user, int read_only) xs *fwers = follower_list(user); xs *fwing = following_list(user); - xs *s1 = xs_fmt(L("%d following %d followers"), + xs *s1 = xs_fmt(L("%d following, %d followers"), xs_list_len(fwing), xs_list_len(fwers)); xs_html_add(top_user, diff --git a/po/en.po b/po/en.po index cb19c67..303b7a5 100644 --- a/po/en.po +++ b/po/en.po @@ -8,686 +8,676 @@ msgstr "" "Language: en\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:361 +#: html.c:367 msgid "Sensitive content: " msgstr "" -#: html.c:369 +#: html.c:375 msgid "Sensitive content description" msgstr "" -#: html.c:382 +#: html.c:388 msgid "Only for mentioned people: " msgstr "" -#: html.c:405 +#: html.c:411 msgid "Reply to (URL): " msgstr "" -#: html.c:414 +#: html.c:420 msgid "Don't send, but store as a draft" msgstr "" -#: html.c:415 +#: html.c:421 msgid "Draft:" msgstr "" -#: html.c:435 +#: html.c:441 msgid "Attachments..." msgstr "" -#: html.c:458 +#: html.c:464 msgid "File:" msgstr "" -#: html.c:462 +#: html.c:468 msgid "Clear this field to delete the attachment" msgstr "" -#: html.c:471 html.c:496 +#: html.c:477 html.c:502 msgid "Attachment description" msgstr "" -#: html.c:507 +#: html.c:513 msgid "Poll..." msgstr "" -#: html.c:509 +#: html.c:515 msgid "Poll options (one per line, up to 8):" msgstr "" -#: html.c:521 +#: html.c:527 msgid "One choice" msgstr "" -#: html.c:524 +#: html.c:530 msgid "Multiple choices" msgstr "" -#: html.c:530 +#: html.c:536 msgid "End in 5 minutes" msgstr "" -#: html.c:534 +#: html.c:540 msgid "End in 1 hour" msgstr "" -#: html.c:537 +#: html.c:543 msgid "End in 1 day" msgstr "" -#: html.c:545 +#: html.c:551 msgid "Post" msgstr "" -#: html.c:639 html.c:646 +#: html.c:648 html.c:655 msgid "Site description" msgstr "" -#: html.c:657 +#: html.c:666 msgid "Admin email" msgstr "" -#: html.c:670 +#: html.c:679 msgid "Admin account" msgstr "" -#: html.c:738 +#: html.c:747 html.c:1083 #, c-format -msgid "%d following, %d followers " +msgid "%d following, %d followers" msgstr "" -#: html.c:826 +#: html.c:837 msgid "RSS" msgstr "" -#: html.c:831 html.c:859 +#: html.c:842 html.c:870 msgid "private" msgstr "" -#: html.c:855 +#: html.c:866 msgid "public" msgstr "" -#: html.c:863 +#: html.c:874 msgid "notifications" msgstr "" -#: html.c:868 +#: html.c:879 msgid "people" msgstr "" -#: html.c:872 +#: html.c:883 msgid "instance" msgstr "" -#: html.c:881 +#: html.c:892 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" msgstr "" -#: html.c:882 +#: html.c:893 msgid "Content search" msgstr "" -#: html.c:1004 +#: html.c:1015 msgid "verified link" msgstr "" -#: html.c:1061 html.c:2382 html.c:2395 html.c:2404 +#: html.c:1072 html.c:2393 html.c:2406 html.c:2415 msgid "Location: " msgstr "" -#: html.c:1072 -#, c-format -msgid "%d following %d followers" -msgstr "" - -#: html.c:1097 +#: html.c:1108 msgid "New Post..." msgstr "" -#: html.c:1099 +#: html.c:1110 msgid "What's on your mind?" msgstr "" -#: html.c:1108 +#: html.c:1119 msgid "Operations..." msgstr "" -#: html.c:1123 html.c:1639 html.c:2978 html.c:4276 +#: html.c:1134 html.c:1650 html.c:2989 html.c:4293 msgid "Follow" msgstr "" -#: html.c:1125 +#: html.c:1136 msgid "(by URL or user@host)" msgstr "" -#: html.c:1140 html.c:1615 html.c:4228 +#: html.c:1151 html.c:1626 html.c:4245 msgid "Boost" msgstr "" -#: html.c:1142 html.c:1159 +#: html.c:1153 html.c:1170 msgid "(by URL)" msgstr "" -#: html.c:1157 html.c:1594 html.c:4219 +#: html.c:1168 html.c:1605 html.c:4236 msgid "Like" msgstr "" -#: html.c:1240 +#: html.c:1251 msgid "User Settings..." msgstr "" -#: html.c:1249 +#: html.c:1260 msgid "Display name:" msgstr "" -#: html.c:1255 +#: html.c:1266 msgid "Your name" msgstr "" -#: html.c:1257 +#: html.c:1268 msgid "Avatar: " msgstr "" -#: html.c:1265 +#: html.c:1276 msgid "Delete current avatar" msgstr "" -#: html.c:1267 +#: html.c:1278 msgid "Header image (banner): " msgstr "" -#: html.c:1275 +#: html.c:1286 msgid "Delete current header image" msgstr "" -#: html.c:1277 +#: html.c:1288 msgid "Bio:" msgstr "" -#: html.c:1283 +#: html.c:1294 msgid "Write about yourself here..." msgstr "" -#: html.c:1292 +#: html.c:1303 msgid "Always show sensitive content" msgstr "" -#: html.c:1294 +#: html.c:1305 msgid "Email address for notifications:" msgstr "" -#: html.c:1302 +#: html.c:1313 msgid "Telegram notifications (bot key and chat id):" msgstr "" -#: html.c:1316 +#: html.c:1327 msgid "ntfy notifications (ntfy server and token):" msgstr "" -#: html.c:1330 +#: html.c:1341 msgid "Maximum days to keep posts (0: server settings):" msgstr "" -#: html.c:1344 +#: html.c:1355 msgid "Drop direct messages from people you don't follow" msgstr "" -#: html.c:1353 +#: html.c:1364 msgid "This account is a bot" msgstr "" -#: html.c:1362 +#: html.c:1373 msgid "Auto-boost all mentions to this account" msgstr "" -#: html.c:1371 +#: html.c:1382 msgid "This account is private (posts are not shown through the web)" msgstr "" -#: html.c:1381 +#: html.c:1392 msgid "Collapse top threads by default" msgstr "" -#: html.c:1390 +#: html.c:1401 msgid "Follow requests must be approved" msgstr "" -#: html.c:1399 +#: html.c:1410 msgid "Publish follower and following metrics" msgstr "" -#: html.c:1401 +#: html.c:1412 msgid "Current location:" msgstr "" -#: html.c:1415 +#: html.c:1426 msgid "Profile metadata (key=value pairs in each line):" msgstr "" -#: html.c:1426 +#: html.c:1437 msgid "New password:" msgstr "" -#: html.c:1433 +#: html.c:1444 msgid "Repeat new password:" msgstr "" -#: html.c:1443 +#: html.c:1454 msgid "Update user info" msgstr "" -#: html.c:1454 +#: html.c:1465 msgid "Followed hashtags..." msgstr "" -#: html.c:1456 +#: html.c:1467 msgid "One hashtag per line" msgstr "" -#: html.c:1477 +#: html.c:1488 msgid "Update hashtags" msgstr "" -#: html.c:1594 +#: html.c:1605 msgid "Say you like this post" msgstr "" -#: html.c:1599 html.c:4237 +#: html.c:1610 html.c:4254 msgid "Unlike" msgstr "" -#: html.c:1599 +#: html.c:1610 msgid "Nah don't like it that much" msgstr "" -#: html.c:1605 html.c:4369 +#: html.c:1616 html.c:4386 msgid "Unpin" msgstr "" -#: html.c:1605 +#: html.c:1616 msgid "Unpin this post from your timeline" msgstr "" -#: html.c:1608 html.c:4364 +#: html.c:1619 html.c:4381 msgid "Pin" msgstr "" -#: html.c:1608 +#: html.c:1619 msgid "Pin this post to the top of your timeline" msgstr "" -#: html.c:1615 +#: html.c:1626 msgid "Announce this post to your followers" msgstr "" -#: html.c:1620 html.c:4245 +#: html.c:1631 html.c:4262 msgid "Unboost" msgstr "" -#: html.c:1620 +#: html.c:1631 msgid "I regret I boosted this" msgstr "" -#: html.c:1626 html.c:4379 +#: html.c:1637 html.c:4396 msgid "Unbookmark" msgstr "" -#: html.c:1626 +#: html.c:1637 msgid "Delete this post from your bookmarks" msgstr "" -#: html.c:1629 html.c:4374 +#: html.c:1640 html.c:4391 msgid "Bookmark" msgstr "" -#: html.c:1629 +#: html.c:1640 msgid "Add this post to your bookmarks" msgstr "" -#: html.c:1635 html.c:2964 html.c:3152 html.c:4289 +#: html.c:1646 html.c:2975 html.c:3163 html.c:4306 msgid "Unfollow" msgstr "" -#: html.c:1635 html.c:2965 +#: html.c:1646 html.c:2976 msgid "Stop following this user's activity" msgstr "" -#: html.c:1639 html.c:2979 +#: html.c:1650 html.c:2990 msgid "Start following this user's activity" msgstr "" -#: html.c:1645 html.c:4319 +#: html.c:1656 html.c:4336 msgid "Unfollow Group" msgstr "" -#: html.c:1646 +#: html.c:1657 msgid "Stop following this group or channel" msgstr "" -#: html.c:1650 html.c:4306 +#: html.c:1661 html.c:4323 msgid "Follow Group" msgstr "" -#: html.c:1651 +#: html.c:1662 msgid "Start following this group or channel" msgstr "" -#: html.c:1656 html.c:3001 html.c:4253 +#: html.c:1667 html.c:3012 html.c:4270 msgid "MUTE" msgstr "" -#: html.c:1657 +#: html.c:1668 msgid "Block any activity from this user forever" msgstr "" -#: html.c:1662 html.c:2983 html.c:4336 +#: html.c:1673 html.c:2994 html.c:4353 msgid "Delete" msgstr "" -#: html.c:1662 +#: html.c:1673 msgid "Delete this post" msgstr "" -#: html.c:1665 html.c:4261 +#: html.c:1676 html.c:4278 msgid "Hide" msgstr "" -#: html.c:1665 +#: html.c:1676 msgid "Hide this post and its children" msgstr "" -#: html.c:1696 +#: html.c:1707 msgid "Edit..." msgstr "" -#: html.c:1715 +#: html.c:1726 msgid "Reply..." msgstr "" -#: html.c:1766 +#: html.c:1777 msgid "Truncated (too deep)" msgstr "" -#: html.c:1775 +#: html.c:1786 msgid "follows you" msgstr "" -#: html.c:1838 +#: html.c:1849 msgid "Pinned" msgstr "" -#: html.c:1846 +#: html.c:1857 msgid "Bookmarked" msgstr "" -#: html.c:1854 +#: html.c:1865 msgid "Poll" msgstr "" -#: html.c:1861 +#: html.c:1872 msgid "Voted" msgstr "" -#: html.c:1870 +#: html.c:1881 msgid "Event" msgstr "" -#: html.c:1902 html.c:1931 +#: html.c:1913 html.c:1942 msgid "boosted" msgstr "" -#: html.c:1947 +#: html.c:1958 msgid "in reply to" msgstr "" -#: html.c:1998 +#: html.c:2009 msgid " [SENSITIVE CONTENT]" msgstr "" -#: html.c:2175 +#: html.c:2186 msgid "Vote" msgstr "" -#: html.c:2185 +#: html.c:2196 msgid "Closed" msgstr "" -#: html.c:2210 +#: html.c:2221 msgid "Closes in" msgstr "" -#: html.c:2289 +#: html.c:2300 msgid "Video" msgstr "" -#: html.c:2304 +#: html.c:2315 msgid "Audio" msgstr "" -#: html.c:2326 +#: html.c:2337 msgid "Attachment" msgstr "" -#: html.c:2340 +#: html.c:2351 msgid "Alt..." msgstr "" -#: html.c:2353 +#: html.c:2364 msgid "Source channel or community" msgstr "" -#: html.c:2447 +#: html.c:2458 msgid "Time: " msgstr "" -#: html.c:2522 +#: html.c:2533 msgid "Older..." msgstr "" -#: html.c:2585 +#: html.c:2596 msgid "about this site" msgstr "" -#: html.c:2587 +#: html.c:2598 msgid "powered by " msgstr "" -#: html.c:2652 +#: html.c:2663 msgid "Dismiss" msgstr "" -#: html.c:2669 +#: html.c:2680 #, c-format msgid "Timeline for list '%s'" msgstr "" -#: html.c:2688 html.c:3714 +#: html.c:2699 html.c:3728 msgid "Pinned posts" msgstr "" -#: html.c:2700 html.c:3729 +#: html.c:2711 html.c:3743 msgid "Bookmarked posts" msgstr "" -#: html.c:2712 html.c:3744 +#: html.c:2723 html.c:3758 msgid "Post drafts" msgstr "" -#: html.c:2771 +#: html.c:2782 msgid "No more unseen posts" msgstr "" -#: html.c:2775 html.c:2875 +#: html.c:2786 html.c:2886 msgid "Back to top" msgstr "" -#: html.c:2828 +#: html.c:2839 msgid "History" msgstr "" -#: html.c:2880 html.c:3300 +#: html.c:2891 html.c:3311 msgid "More..." msgstr "" -#: html.c:2969 html.c:4272 +#: html.c:2980 html.c:4289 msgid "Unlimit" msgstr "" -#: html.c:2970 +#: html.c:2981 msgid "Allow announces (boosts) from this user" msgstr "" -#: html.c:2973 html.c:4268 +#: html.c:2984 html.c:4285 msgid "Limit" msgstr "" -#: html.c:2974 +#: html.c:2985 msgid "Block announces (boosts) from this user" msgstr "" -#: html.c:2983 +#: html.c:2994 msgid "Delete this user" msgstr "" -#: html.c:2988 html.c:4384 +#: html.c:2999 html.c:4401 msgid "Approve" msgstr "" -#: html.c:2989 +#: html.c:3000 msgid "Approve this follow request" msgstr "" -#: html.c:2992 html.c:4408 +#: html.c:3003 html.c:4425 msgid "Discard" msgstr "" -#: html.c:2992 +#: html.c:3003 msgid "Discard this follow request" msgstr "" -#: html.c:2997 html.c:4257 +#: html.c:3008 html.c:4274 msgid "Unmute" msgstr "" -#: html.c:2998 +#: html.c:3009 msgid "Stop blocking activities from this user" msgstr "" -#: html.c:3002 +#: html.c:3013 msgid "Block any activity from this user" msgstr "" -#: html.c:3010 +#: html.c:3021 msgid "Direct Message..." msgstr "" -#: html.c:3045 +#: html.c:3056 msgid "Pending follow confirmations" msgstr "" -#: html.c:3049 +#: html.c:3060 msgid "People you follow" msgstr "" -#: html.c:3050 +#: html.c:3061 msgid "People that follow you" msgstr "" -#: html.c:3089 +#: html.c:3100 msgid "Clear all" msgstr "" -#: html.c:3146 +#: html.c:3157 msgid "Mention" msgstr "" -#: html.c:3149 +#: html.c:3160 msgid "Finished poll" msgstr "" -#: html.c:3164 +#: html.c:3175 msgid "Follow Request" msgstr "" -#: html.c:3247 +#: html.c:3258 msgid "Context" msgstr "" -#: html.c:3258 +#: html.c:3269 msgid "New" msgstr "" -#: html.c:3273 +#: html.c:3284 msgid "Already seen" msgstr "" -#: html.c:3288 +#: html.c:3299 msgid "None" msgstr "" -#: html.c:3539 +#: html.c:3553 #, c-format msgid "Search results for account %s" msgstr "" -#: html.c:3546 +#: html.c:3560 #, c-format msgid "Account %s not found" msgstr "" -#: html.c:3577 +#: html.c:3591 #, c-format msgid "Search results for tag %s" msgstr "" -#: html.c:3577 +#: html.c:3591 #, c-format msgid "Nothing found for tag %s" msgstr "" -#: html.c:3593 +#: html.c:3607 #, c-format msgid "Search results for '%s' (may be more)" msgstr "" -#: html.c:3596 +#: html.c:3610 #, c-format msgid "Search results for '%s'" msgstr "" -#: html.c:3599 +#: html.c:3613 #, c-format msgid "No more matches for '%s'" msgstr "" -#: html.c:3601 +#: html.c:3615 #, c-format msgid "Nothing found for '%s'" msgstr "" -#: html.c:3699 +#: html.c:3713 msgid "Showing instance timeline" msgstr "" -#: html.c:3767 +#: html.c:3781 #, c-format msgid "Showing timeline for list '%s'" msgstr "" -#: httpd.c:248 +#: httpd.c:250 #, c-format msgid "Search results for tag #%s" msgstr "" -#: httpd.c:257 +#: httpd.c:259 msgid "Recent posts by users in this instance" msgstr "" - -#: html.c:738 -#, c-format -msgid "%d following, %d followers · " -msgstr "" -- cgit From f0f93b84bec5373f9c6567b7b415ea77ca0bd064 Mon Sep 17 00:00:00 2001 From: default Date: Sat, 15 Feb 2025 06:00:19 +0100 Subject: Optimized lang_str(). --- data.c | 19 ++++++------------- html.c | 17 +++++++++++++++-- snac.h | 1 + 3 files changed, 22 insertions(+), 15 deletions(-) (limited to 'html.c') diff --git a/data.c b/data.c index f935b39..4308aa5 100644 --- a/data.c +++ b/data.c @@ -4072,21 +4072,14 @@ void badlogin_inc(const char *user, const char *addr) const char *lang_str(const char *str, const snac *user) /* returns a translated string */ { - if (user && xs_is_string(str) && xs_is_dict(srv_langs)) { - /* get user preference */ - const char *lang = xs_dict_get(user->config, "lang"); + const char *n_str = str; - if (xs_is_string(lang)) { - const xs_dict *strs = xs_dict_get(srv_langs, lang); + if (user && xs_is_dict(user->lang) && xs_is_string(str)) { + n_str = xs_dict_get(user->lang, str); - if (xs_is_dict(strs)) { - const char *n_str = xs_dict_get(strs, str); - - if (xs_is_string(n_str)) - str = n_str; - } - } + if (xs_is_null(n_str) || *n_str == '\0') + n_str = str; } - return str; + return n_str; } diff --git a/html.c b/html.c index e11abd1..5068b49 100644 --- a/html.c +++ b/html.c @@ -3326,6 +3326,17 @@ xs_str *html_notifications(snac *user, int skip, int show) } +void set_user_lang(snac *user) +/* sets the language dict according to user configuration */ +{ + user->lang = NULL; + const char *lang = xs_dict_get(user->config, "lang"); + + if (xs_is_string(lang)) + user->lang = xs_dict_get(srv_langs, lang); +} + + int html_get_handler(const xs_dict *req, const char *q_path, char **body, int *b_size, char **ctype, xs_str **etag, xs_str **last_modified) @@ -3399,7 +3410,8 @@ int html_get_handler(const xs_dict *req, const char *q_path, return HTTP_STATUS_NOT_FOUND; } - user = &snac; + user = &snac; /* for L() */ + set_user_lang(&snac); if (xs_is_true(xs_dict_get(srv_config, "proxy_media"))) proxy = 1; @@ -4048,7 +4060,8 @@ int html_post_handler(const xs_dict *req, const char *q_path, return HTTP_STATUS_UNAUTHORIZED; } - user = &snac; + user = &snac; /* for L() */ + set_user_lang(&snac); p_vars = xs_dict_get(req, "p_vars"); diff --git a/snac.h b/snac.h index e2b6b5f..ac1abcd 100644 --- a/snac.h +++ b/snac.h @@ -60,6 +60,7 @@ typedef struct { xs_dict *links; /* validated links */ xs_str *actor; /* actor url */ xs_str *md5; /* actor url md5 */ + const xs_dict *lang;/* string translation dict */ } snac; typedef struct { -- cgit From 1554a207e653d626c194b7d8113a55358c0dcdf7 Mon Sep 17 00:00:00 2001 From: default Date: Sat, 15 Feb 2025 06:35:47 +0100 Subject: The interface language preference can now be set. --- data.c | 1 + html.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'html.c') diff --git a/data.c b/data.c index e0b4936..e9837bb 100644 --- a/data.c +++ b/data.c @@ -151,6 +151,7 @@ int srv_open(const char *basedir, int auto_upgrade) /* languages */ srv_langs = xs_dict_new(); + srv_langs = xs_dict_set(srv_langs, "en", xs_stock(XSTYPE_NULL)); xs *l_dir = xs_fmt("%s/lang/", srv_basedir); mkdirx(l_dir); diff --git a/html.c b/html.c index 5068b49..6573630 100644 --- a/html.c +++ b/html.c @@ -1243,6 +1243,28 @@ xs_html *html_top_controls(snac *user) else metadata = xs_str_new(NULL); + /* ui language */ + xs_html *lang_select = xs_html_tag("select", + xs_html_attr("name", "web_ui_lang")); + + const char *u_lang = xs_dict_get_def(user->config, "lang", "en"); + const char *lang; + const xs_dict *langs; + + xs_dict_foreach(srv_langs, lang, langs) { + if (strcmp(u_lang, lang) == 0) + xs_html_add(lang_select, + xs_html_tag("option", + xs_html_text(lang), + xs_html_attr("value", lang), + xs_html_attr("selected", "selected"))); + else + xs_html_add(lang_select, + xs_html_tag("option", + xs_html_text(lang), + xs_html_attr("value", lang))); + } + xs *user_setup_action = xs_fmt("%s/admin/user-setup", user->actor); xs_html_add(top_controls, @@ -1433,6 +1455,11 @@ xs_html *html_top_controls(snac *user) "/example.com/my-blog\nGPG Key=1FA54\n..."), xs_html_text(metadata))), + xs_html_tag("p", + xs_html_text(L("Web interface language:")), + xs_html_sctag("br", NULL), + lang_select), + xs_html_tag("p", xs_html_text(L("New password:")), xs_html_sctag("br", NULL), @@ -4505,6 +4532,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_TRUE)); else 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); 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