summaryrefslogtreecommitdiff
path: root/html.c
diff options
context:
space:
mode:
Diffstat (limited to 'html.c')
-rw-r--r--html.c111
1 files changed, 89 insertions, 22 deletions
diff --git a/html.c b/html.c
index 6573630..a90a51f 100644
--- a/html.c
+++ b/html.c
@@ -83,16 +83,20 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p
83 const char *u = xs_dict_get(i, "url"); 83 const char *u = xs_dict_get(i, "url");
84 const char *mt = xs_dict_get(i, "mediaType"); 84 const char *mt = xs_dict_get(i, "mediaType");
85 85
86 if (xs_is_string(u) && xs_is_string(mt) && strcmp(mt, "image/svg+xml")) { 86 if (xs_is_string(u) && xs_is_string(mt)) {
87 xs *url = make_url(u, proxy, 0); 87 if (strcmp(mt, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg")))
88 s = xs_replace_i(s, n, "");
89 else {
90 xs *url = make_url(u, proxy, 0);
88 91
89 xs_html *img = xs_html_sctag("img", 92 xs_html *img = xs_html_sctag("img",
90 xs_html_attr("loading", "lazy"), 93 xs_html_attr("loading", "lazy"),
91 xs_html_attr("src", url), 94 xs_html_attr("src", url),
92 xs_html_attr("style", style)); 95 xs_html_attr("style", style));
93 96
94 xs *s1 = xs_html_render(img); 97 xs *s1 = xs_html_render(img);
95 s = xs_replace_i(s, n, s1); 98 s = xs_replace_i(s, n, s1);
99 }
96 } 100 }
97 else 101 else
98 s = xs_replace_i(s, n, ""); 102 s = xs_replace_i(s, n, "");
@@ -412,7 +416,7 @@ xs_html *html_note(snac *user, const char *summary,
412 xs_html_sctag("input", 416 xs_html_sctag("input",
413 xs_html_attr("type", "url"), 417 xs_html_attr("type", "url"),
414 xs_html_attr("name", "in_reply_to"), 418 xs_html_attr("name", "in_reply_to"),
415 xs_html_attr("placeholder", "Optional URL to reply to"))); 419 xs_html_attr("placeholder", L("Optional URL to reply to"))));
416 420
417 xs_html_add(form, 421 xs_html_add(form,
418 xs_html_tag("p", NULL), 422 xs_html_tag("p", NULL),
@@ -519,7 +523,7 @@ xs_html *html_note(snac *user, const char *summary,
519 xs_html_attr("name", "poll_options"), 523 xs_html_attr("name", "poll_options"),
520 xs_html_attr("rows", "4"), 524 xs_html_attr("rows", "4"),
521 xs_html_attr("wrap", "virtual"), 525 xs_html_attr("wrap", "virtual"),
522 xs_html_attr("placeholder", "Option 1...\nOption 2...\nOption 3...\n..."))), 526 xs_html_attr("placeholder", L("Option 1...\nOption 2...\nOption 3...\n...")))),
523 xs_html_tag("select", 527 xs_html_tag("select",
524 xs_html_attr("name", "poll_multiple"), 528 xs_html_attr("name", "poll_multiple"),
525 xs_html_tag("option", 529 xs_html_tag("option",
@@ -1338,13 +1342,13 @@ xs_html *html_top_controls(snac *user)
1338 xs_html_attr("type", "text"), 1342 xs_html_attr("type", "text"),
1339 xs_html_attr("name", "telegram_bot"), 1343 xs_html_attr("name", "telegram_bot"),
1340 xs_html_attr("value", telegram_bot), 1344 xs_html_attr("value", telegram_bot),
1341 xs_html_attr("placeholder", "Bot API key")), 1345 xs_html_attr("placeholder", L("Bot API key"))),
1342 xs_html_text(" "), 1346 xs_html_text(" "),
1343 xs_html_sctag("input", 1347 xs_html_sctag("input",
1344 xs_html_attr("type", "text"), 1348 xs_html_attr("type", "text"),
1345 xs_html_attr("name", "telegram_chat_id"), 1349 xs_html_attr("name", "telegram_chat_id"),
1346 xs_html_attr("value", telegram_chat_id), 1350 xs_html_attr("value", telegram_chat_id),
1347 xs_html_attr("placeholder", "Chat id"))), 1351 xs_html_attr("placeholder", L("Chat id")))),
1348 xs_html_tag("p", 1352 xs_html_tag("p",
1349 xs_html_text(L("ntfy notifications (ntfy server and token):")), 1353 xs_html_text(L("ntfy notifications (ntfy server and token):")),
1350 xs_html_sctag("br", NULL), 1354 xs_html_sctag("br", NULL),
@@ -1352,13 +1356,13 @@ xs_html *html_top_controls(snac *user)
1352 xs_html_attr("type", "text"), 1356 xs_html_attr("type", "text"),
1353 xs_html_attr("name", "ntfy_server"), 1357 xs_html_attr("name", "ntfy_server"),
1354 xs_html_attr("value", ntfy_server), 1358 xs_html_attr("value", ntfy_server),
1355 xs_html_attr("placeholder", "ntfy server - full URL (example: https://ntfy.sh/YourTopic)")), 1359 xs_html_attr("placeholder", L("ntfy server - full URL (example: https://ntfy.sh/YourTopic)"))),
1356 xs_html_text(" "), 1360 xs_html_text(" "),
1357 xs_html_sctag("input", 1361 xs_html_sctag("input",
1358 xs_html_attr("type", "text"), 1362 xs_html_attr("type", "text"),
1359 xs_html_attr("name", "ntfy_token"), 1363 xs_html_attr("name", "ntfy_token"),
1360 xs_html_attr("value", ntfy_token), 1364 xs_html_attr("value", ntfy_token),
1361 xs_html_attr("placeholder", "ntfy token - if needed"))), 1365 xs_html_attr("placeholder", L("ntfy token - if needed")))),
1362 xs_html_tag("p", 1366 xs_html_tag("p",
1363 xs_html_text(L("Maximum days to keep posts (0: server settings):")), 1367 xs_html_text(L("Maximum days to keep posts (0: server settings):")),
1364 xs_html_sctag("br", NULL), 1368 xs_html_sctag("br", NULL),
@@ -1514,6 +1518,38 @@ xs_html *html_top_controls(snac *user)
1514 xs_html_attr("class", "button"), 1518 xs_html_attr("class", "button"),
1515 xs_html_attr("value", L("Update hashtags"))))))); 1519 xs_html_attr("value", L("Update hashtags")))))));
1516 1520
1521 xs *blocked_hashtags_action = xs_fmt("%s/admin/blocked-hashtags", user->actor);
1522 xs *blocked_hashtags = xs_join(xs_dict_get_def(user->config,
1523 "blocked_hashtags", xs_stock(XSTYPE_LIST)), "\n");
1524
1525 xs_html_add(top_controls,
1526 xs_html_tag("details",
1527 xs_html_tag("summary",
1528 xs_html_text(L("Blocked hashtags..."))),
1529 xs_html_tag("p",
1530 xs_html_text(L("One hashtag per line"))),
1531 xs_html_tag("div",
1532 xs_html_attr("class", "snac-blocked-hashtags"),
1533 xs_html_tag("form",
1534 xs_html_attr("autocomplete", "off"),
1535 xs_html_attr("method", "post"),
1536 xs_html_attr("action", blocked_hashtags_action),
1537 xs_html_attr("enctype", "multipart/form-data"),
1538
1539 xs_html_tag("textarea",
1540 xs_html_attr("name", "blocked_hashtags"),
1541 xs_html_attr("cols", "40"),
1542 xs_html_attr("rows", "4"),
1543 xs_html_attr("placeholder", "#cats\n#windowfriday\n#classicalmusic"),
1544 xs_html_text(blocked_hashtags)),
1545
1546 xs_html_tag("br", NULL),
1547
1548 xs_html_sctag("input",
1549 xs_html_attr("type", "submit"),
1550 xs_html_attr("class", "button"),
1551 xs_html_attr("value", L("Update hashtags")))))));
1552
1517 return top_controls; 1553 return top_controls;
1518} 1554}
1519 1555
@@ -2281,8 +2317,10 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
2281 continue; 2317 continue;
2282 2318
2283 /* drop silently any attachment that may include JavaScript */ 2319 /* drop silently any attachment that may include JavaScript */
2284 if (strcmp(type, "image/svg+xml") == 0 || 2320 if (strcmp(type, "text/html") == 0)
2285 strcmp(type, "text/html") == 0) 2321 continue;
2322
2323 if (strcmp(type, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg")))
2286 continue; 2324 continue;
2287 2325
2288 /* do this attachment include an icon? */ 2326 /* do this attachment include an icon? */
@@ -2724,7 +2762,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
2724 xs_html_attr("href", url), 2762 xs_html_attr("href", url),
2725 xs_html_attr("class", "snac-list-link"), 2763 xs_html_attr("class", "snac-list-link"),
2726 xs_html_attr("title", L("Pinned posts")), 2764 xs_html_attr("title", L("Pinned posts")),
2727 xs_html_text("pinned")))); 2765 xs_html_text(L("pinned")))));
2728 } 2766 }
2729 2767
2730 { 2768 {
@@ -2736,7 +2774,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
2736 xs_html_attr("href", url), 2774 xs_html_attr("href", url),
2737 xs_html_attr("class", "snac-list-link"), 2775 xs_html_attr("class", "snac-list-link"),
2738 xs_html_attr("title", L("Bookmarked posts")), 2776 xs_html_attr("title", L("Bookmarked posts")),
2739 xs_html_text("bookmarks")))); 2777 xs_html_text(L("bookmarks")))));
2740 } 2778 }
2741 2779
2742 { 2780 {
@@ -2748,7 +2786,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
2748 xs_html_attr("href", url), 2786 xs_html_attr("href", url),
2749 xs_html_attr("class", "snac-list-link"), 2787 xs_html_attr("class", "snac-list-link"),
2750 xs_html_attr("title", L("Post drafts")), 2788 xs_html_attr("title", L("Post drafts")),
2751 xs_html_text("drafts")))); 2789 xs_html_text(L("drafts")))));
2752 } 2790 }
2753 2791
2754 /* the list of followed hashtags */ 2792 /* the list of followed hashtags */
@@ -3982,7 +4020,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
3982 const char *b64 = xs_dict_get(q_vars, "content"); 4020 const char *b64 = xs_dict_get(q_vars, "content");
3983 int sz; 4021 int sz;
3984 xs *content = xs_base64_dec(b64, &sz); 4022 xs *content = xs_base64_dec(b64, &sz);
3985 xs *msg = msg_note(&snac, content, NULL, NULL, NULL, 0, NULL); 4023 xs *msg = msg_note(&snac, content, NULL, NULL, NULL, 0, NULL, NULL);
3986 xs *c_msg = msg_create(&snac, msg); 4024 xs *c_msg = msg_create(&snac, msg);
3987 4025
3988 timeline_add(&snac, xs_dict_get(msg, "id"), msg); 4026 timeline_add(&snac, xs_dict_get(msg, "id"), msg);
@@ -4182,7 +4220,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
4182 enqueue_close_question(&snac, xs_dict_get(msg, "id"), end_secs); 4220 enqueue_close_question(&snac, xs_dict_get(msg, "id"), end_secs);
4183 } 4221 }
4184 else 4222 else
4185 msg = msg_note(&snac, content_2, to, in_reply_to, attach_list, priv, NULL); 4223 msg = msg_note(&snac, content_2, to, in_reply_to, attach_list, priv, NULL, NULL);
4186 4224
4187 if (sensitive != NULL) { 4225 if (sensitive != NULL) {
4188 msg = xs_dict_set(msg, "sensitive", xs_stock(XSTYPE_TRUE)); 4226 msg = xs_dict_set(msg, "sensitive", xs_stock(XSTYPE_TRUE));
@@ -4621,7 +4659,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
4621 int c = 0; 4659 int c = 0;
4622 4660
4623 while (xs_list_next(ls, &v, &c)) { 4661 while (xs_list_next(ls, &v, &c)) {
4624 xs *msg = msg_note(&snac, "", actor, irt, NULL, 1, NULL); 4662 xs *msg = msg_note(&snac, "", actor, irt, NULL, 1, NULL, NULL);
4625 4663
4626 /* set the option */ 4664 /* set the option */
4627 msg = xs_dict_append(msg, "name", v); 4665 msg = xs_dict_append(msg, "name", v);
@@ -4683,6 +4721,35 @@ int html_post_handler(const xs_dict *req, const char *q_path,
4683 4721
4684 status = HTTP_STATUS_SEE_OTHER; 4722 status = HTTP_STATUS_SEE_OTHER;
4685 } 4723 }
4724 else
4725 if (p_path && strcmp(p_path, "admin/blocked-hashtags") == 0) { /** **/
4726 const char *hashtags = xs_dict_get(p_vars, "blocked_hashtags");
4727
4728 if (xs_is_string(hashtags)) {
4729 xs *new_hashtags = xs_list_new();
4730 xs *l = xs_split(hashtags, "\n");
4731 const char *v;
4732
4733 xs_list_foreach(l, v) {
4734 xs *s1 = xs_strip_i(xs_dup(v));
4735 s1 = xs_replace_i(s1, " ", "");
4736
4737 if (*s1 == '\0')
4738 continue;
4739
4740 xs *s2 = xs_utf8_to_lower(s1);
4741 if (*s2 != '#')
4742 s2 = xs_str_prepend_i(s2, "#");
4743
4744 new_hashtags = xs_list_append(new_hashtags, s2);
4745 }
4746
4747 snac.config = xs_dict_set(snac.config, "blocked_hashtags", new_hashtags);
4748 user_persist(&snac, 0);
4749 }
4750
4751 status = HTTP_STATUS_SEE_OTHER;
4752 }
4686 4753
4687 if (status == HTTP_STATUS_SEE_OTHER) { 4754 if (status == HTTP_STATUS_SEE_OTHER) {
4688 const char *redir = xs_dict_get(p_vars, "redir"); 4755 const char *redir = xs_dict_get(p_vars, "redir");