summaryrefslogtreecommitdiff
path: root/html.c
diff options
context:
space:
mode:
authorGravatar byte2026-01-12 01:25:49 +0100
committerGravatar byte2026-01-12 01:25:49 +0100
commit6ad2365a41dd84ee925d7921a1c5756499d6fb17 (patch)
tree032fac55b062deb6010814bfc5c2b656e1b1ef28 /html.c
parentUpdated RELEASE_NOTES. (diff)
downloadsnac2-6ad2365a41dd84ee925d7921a1c5756499d6fb17.tar.gz
snac2-6ad2365a41dd84ee925d7921a1c5756499d6fb17.tar.xz
snac2-6ad2365a41dd84ee925d7921a1c5756499d6fb17.zip
user-specified word mutes and matching
Diffstat (limited to 'html.c')
-rw-r--r--html.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/html.c b/html.c
index d5294cb..ebd9331 100644
--- a/html.c
+++ b/html.c
@@ -16,6 +16,7 @@
16#include "xs_url.h" 16#include "xs_url.h"
17#include "xs_random.h" 17#include "xs_random.h"
18#include "xs_http.h" 18#include "xs_http.h"
19#include "xs_list_tools.h"
19 20
20#include "snac.h" 21#include "snac.h"
21 22
@@ -1864,6 +1865,38 @@ xs_html *html_top_controls(snac *user)
1864 xs_html_attr("class", "button"), 1865 xs_html_attr("class", "button"),
1865 xs_html_attr("value", L("Update hashtags"))))))); 1866 xs_html_attr("value", L("Update hashtags")))))));
1866 1867
1868 xs *muted_words_action = xs_fmt("%s/admin/muted-words", user->actor);
1869 xs *muted_words = xs_join(xs_dict_get_def(user->config,
1870 "muted_words", xs_stock(XSTYPE_LIST)), "\n");
1871
1872 xs_html_add(top_controls,
1873 xs_html_tag("details",
1874 xs_html_tag("summary",
1875 xs_html_text(L("Muted words..."))),
1876 xs_html_tag("p",
1877 xs_html_text(L("One word per line, partial matches count"))),
1878 xs_html_tag("div",
1879 xs_html_attr("class", "snac-muted-words"),
1880 xs_html_tag("form",
1881 xs_html_attr("autocomplete", "off"),
1882 xs_html_attr("method", "post"),
1883 xs_html_attr("action", muted_words_action),
1884 xs_html_attr("enctype", "multipart/form-data"),
1885
1886 xs_html_tag("textarea",
1887 xs_html_attr("name", "muted_words"),
1888 xs_html_attr("cols", "40"),
1889 xs_html_attr("rows", "4"),
1890 xs_html_attr("placeholder", "nascar\nsuperbowl\nFIFA"),
1891 xs_html_text(muted_words)),
1892
1893 xs_html_tag("br", NULL),
1894
1895 xs_html_sctag("input",
1896 xs_html_attr("type", "submit"),
1897 xs_html_attr("class", "button"),
1898 xs_html_attr("value", L("Update muted words")))))));
1899
1867 return top_controls; 1900 return top_controls;
1868} 1901}
1869 1902
@@ -2144,6 +2177,30 @@ xs_html *html_entry_controls(snac *user, const char *actor,
2144} 2177}
2145 2178
2146 2179
2180static const xs_str* words_in_content(const xs_list *words, const xs_val *content)
2181/* returns a word that matches any of the words in content */
2182{
2183 if (!xs_is_list(words) || !xs_is_string(content)) {
2184 return NULL;
2185 }
2186 xs *c = xs_split(content, " ");
2187 xs *sc = xs_list_sort(c, NULL);
2188
2189 const xs_str *wv;
2190 const xs_str *cv;
2191 xs_list_foreach(words, wv) {
2192 xs_list_foreach(sc, cv) {
2193 xs_tolower_i((xs_str*)cv);
2194 if(xs_str_in(cv, wv) != -1){
2195 return wv;
2196 }
2197 }
2198 }
2199
2200 return NULL;
2201}
2202
2203
2147xs_html *html_entry(snac *user, xs_dict *msg, int read_only, 2204xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
2148 int level, const char *md5, int hide_children) 2205 int level, const char *md5, int hide_children)
2149{ 2206{
@@ -2438,6 +2495,17 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
2438 xs_html_text(v), 2495 xs_html_text(v),
2439 xs_html_text(L(" [SENSITIVE CONTENT]")))); 2496 xs_html_text(L(" [SENSITIVE CONTENT]"))));
2440 } 2497 }
2498 else
2499 if (user &&
2500 /* muted_words is all lowercase and sorted for performance */
2501 (v = words_in_content(xs_dict_get(user->config, "muted_words"),
2502 xs_dict_get(msg, "content"))) != NULL) {
2503 snac_debug(user, 1, xs_fmt("word %s muted by user preferences: %s", v, id));
2504 snac_content = xs_html_tag("details",
2505 xs_html_tag("summary",
2506 xs_html_text(L("Muted: ")),
2507 xs_html_text(v)));
2508 }
2441 else { 2509 else {
2442 snac_content = xs_html_tag("div", NULL); 2510 snac_content = xs_html_tag("div", NULL);
2443 } 2511 }
@@ -5813,6 +5881,33 @@ int html_post_handler(const xs_dict *req, const char *q_path,
5813 5881
5814 status = HTTP_STATUS_SEE_OTHER; 5882 status = HTTP_STATUS_SEE_OTHER;
5815 } 5883 }
5884 else
5885 if (p_path && strcmp(p_path, "admin/muted-words") == 0) {
5886 const char *words = xs_dict_get(p_vars, "muted_words");
5887
5888 if (xs_is_string(words)) {
5889 xs *new_words = xs_list_new();
5890 xs *l = xs_split(words, "\n");
5891 const char *v;
5892
5893 xs_list_foreach(l, v) {
5894 xs *s1 = xs_strip_i(xs_dup(v));
5895 s1 = xs_replace_i(s1, " ", "");
5896
5897 if (*s1 == '\0')
5898 continue;
5899
5900 xs *s2 = xs_utf8_to_lower(s1);
5901
5902 new_words = xs_list_insert_sorted(new_words, s2);
5903 }
5904
5905 snac.config = xs_dict_set(snac.config, "muted_words", new_words);
5906 user_persist(&snac, 0);
5907 }
5908
5909 status = HTTP_STATUS_SEE_OTHER;
5910 }
5816 5911
5817 if (status == HTTP_STATUS_SEE_OTHER) { 5912 if (status == HTTP_STATUS_SEE_OTHER) {
5818 const char *hard_redir = xs_dict_get(p_vars, "hard-redir"); 5913 const char *hard_redir = xs_dict_get(p_vars, "hard-redir");