commit 5de52cb

default  ·  2025-02-07 08:26:54 +0000 UTC
parent 3099d17
Added support for multiple attachments in the same post.
1 files changed,  +109, -59
M html.c
M html.c
+109, -59
  1@@ -327,7 +327,7 @@ xs_html *html_note(snac *user, const char *summary,
  2                    const xs_val *cw_yn, const char *cw_text,
  3                    const xs_val *mnt_only, const char *redir,
  4                    const char *in_reply_to, int poll,
  5-                   const char *att_file, const char *att_alt_text,
  6+                   const xs_list *att_files, const xs_list *att_alt_texts,
  7                    int is_draft)
  8 /* Yes, this is a FUCKTON of arguments and I'm a bit embarrased */
  9 {
 10@@ -432,30 +432,71 @@ xs_html *html_note(snac *user, const char *summary,
 11         xs_html_tag("p", NULL),
 12         att = xs_html_tag("details",
 13             xs_html_tag("summary",
 14-                xs_html_text(L("Attachment..."))),
 15+                xs_html_text(L("Attachments..."))),
 16             xs_html_tag("p", NULL)));
 17 
 18-    if (att_file && *att_file)
 19+    int max_attachments = xs_number_get(xs_dict_get_def(srv_config, "max_attachments", "4"));
 20+    int att_n = 0;
 21+
 22+    /* fields for the currently existing attachments */
 23+    if (xs_is_list(att_files) && xs_is_list(att_alt_texts)) {
 24+        while (att_n < max_attachments) {
 25+            const char *att_file = xs_list_get(att_files, att_n);
 26+            const char *att_alt_text = xs_list_get(att_alt_texts, att_n);
 27+
 28+            if (!xs_is_string(att_file) || !xs_is_string(att_alt_text))
 29+                break;
 30+
 31+            xs *att_lbl = xs_fmt("attach_url_%d", att_n);
 32+            xs *alt_lbl = xs_fmt("alt_text_%d", att_n);
 33+
 34+            if (att_n)
 35+                xs_html_add(att,
 36+                    xs_html_sctag("br", NULL));
 37+
 38+            xs_html_add(att,
 39+                xs_html_text(L("File:")),
 40+                xs_html_sctag("input",
 41+                    xs_html_attr("type", "text"),
 42+                    xs_html_attr("name", att_lbl),
 43+                    xs_html_attr("title", L("Clear this field to delete the attachment")),
 44+                    xs_html_attr("value", att_file)));
 45+
 46+            xs_html_add(att,
 47+                xs_html_text(" "),
 48+                xs_html_sctag("input",
 49+                    xs_html_attr("type",    "text"),
 50+                    xs_html_attr("name",    alt_lbl),
 51+                    xs_html_attr("value",   att_alt_text),
 52+                    xs_html_attr("placeholder", L("Attachment description"))));
 53+
 54+            att_n++;
 55+        }
 56+    }
 57+
 58+    /* the rest of possible attachments */
 59+    while (att_n < max_attachments) {
 60+        xs *att_lbl = xs_fmt("attach_%d", att_n);
 61+        xs *alt_lbl = xs_fmt("alt_text_%d", att_n);
 62+
 63+        if (att_n)
 64+            xs_html_add(att,
 65+                xs_html_sctag("br", NULL));
 66+
 67         xs_html_add(att,
 68-            xs_html_text(L("File:")),
 69             xs_html_sctag("input",
 70-                xs_html_attr("type", "text"),
 71-                xs_html_attr("name", "attach_url"),
 72-                xs_html_attr("title", L("Clear this field to delete the attachment")),
 73-                xs_html_attr("value", att_file)));
 74-    else
 75+                xs_html_attr("type",    "file"),
 76+                xs_html_attr("name",    att_lbl)));
 77+
 78         xs_html_add(att,
 79+            xs_html_text(" "),
 80             xs_html_sctag("input",
 81-                xs_html_attr("type",    "file"),
 82-                xs_html_attr("name",    "attach")));
 83+                xs_html_attr("type",    "text"),
 84+                xs_html_attr("name",    alt_lbl),
 85+                xs_html_attr("placeholder", L("Attachment description"))));
 86 
 87-    xs_html_add(att,
 88-        xs_html_text(" "),
 89-        xs_html_sctag("input",
 90-            xs_html_attr("type",    "text"),
 91-            xs_html_attr("name",    "alt_text"),
 92-            xs_html_attr("value",   att_alt_text),
 93-            xs_html_attr("placeholder", L("Attachment description"))));
 94+        att_n++;
 95+    }
 96 
 97     /* add poll controls */
 98     if (poll) {
 99@@ -1059,7 +1100,7 @@ xs_html *html_top_controls(snac *snac)
100             NULL, NULL,
101             xs_stock(XSTYPE_FALSE), "",
102             xs_stock(XSTYPE_FALSE), NULL,
103-            NULL, 1, "", "", 0),
104+            NULL, 1, NULL, NULL, 0),
105 
106         /** operations **/
107         xs_html_tag("details",
108@@ -1631,17 +1672,22 @@ xs_html *html_entry_controls(snac *snac, const char *actor,
109         xs *form_id = xs_fmt("%s_edit_form", md5);
110         xs *redir   = xs_fmt("%s_entry", md5);
111 
112-        const char *att_file = "";
113-        const char *att_alt_text = "";
114+        xs *att_files = xs_list_new();
115+        xs *att_alt_texts = xs_list_new();
116+
117         const xs_list *att_list = xs_dict_get(msg, "attachment");
118 
119-        /* does it have an attachment? */
120-        if (xs_type(att_list) == XSTYPE_LIST && xs_list_len(att_list)) {
121-            const xs_dict *d = xs_list_get(att_list, 0);
122+        if (xs_is_list(att_list)) {
123+            const xs_dict *d;
124 
125-            if (xs_type(d) == XSTYPE_DICT) {
126-                att_file = xs_dict_get_def(d, "url", "");
127-                att_alt_text = xs_dict_get_def(d, "name", "");
128+            xs_list_foreach(att_list, d) {
129+                const char *att_file = xs_dict_get(d, "url");
130+                const char *att_alt_text = xs_dict_get(d, "name");
131+
132+                if (xs_is_string(att_file) && xs_is_string(att_alt_text)) {
133+                    att_files = xs_list_append(att_files, att_file);
134+                    att_alt_texts = xs_list_append(att_alt_texts, att_alt_text);
135+                }
136             }
137         }
138 
139@@ -1653,7 +1699,7 @@ xs_html *html_entry_controls(snac *snac, const char *actor,
140                 id, NULL,
141                 xs_dict_get(msg, "sensitive"), xs_dict_get(msg, "summary"),
142                 xs_stock(is_msg_public(msg) ? XSTYPE_FALSE : XSTYPE_TRUE), redir,
143-                NULL, 0, att_file, att_alt_text, is_draft(snac, id))),
144+                NULL, 0, att_files, att_alt_texts, is_draft(snac, id))),
145             xs_html_tag("p", NULL));
146     }
147 
148@@ -1672,7 +1718,7 @@ xs_html *html_entry_controls(snac *snac, const char *actor,
149                 NULL, NULL,
150                 xs_dict_get(msg, "sensitive"), xs_dict_get(msg, "summary"),
151                 xs_stock(is_msg_public(msg) ? XSTYPE_FALSE : XSTYPE_TRUE), redir,
152-                id, 0, "", "", 0)),
153+                id, 0, NULL, NULL, 0)),
154             xs_html_tag("p", NULL));
155     }
156 
157@@ -2938,7 +2984,7 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t, cons
158                     NULL, actor_id,
159                     xs_stock(XSTYPE_FALSE), "",
160                     xs_stock(XSTYPE_FALSE), NULL,
161-                    NULL, 0, "", "", 0),
162+                    NULL, 0, NULL, NULL, 0),
163                 xs_html_tag("p", NULL));
164 
165             xs_html_add(snac_post, snac_controls);
166@@ -3966,52 +4012,56 @@ int html_post_handler(const xs_dict *req, const char *q_path,
167         /* post note */
168         const xs_str *content      = xs_dict_get(p_vars, "content");
169         const xs_str *in_reply_to  = xs_dict_get(p_vars, "in_reply_to");
170-        const xs_str *attach_url   = xs_dict_get(p_vars, "attach_url");
171-        const xs_list *attach_file = xs_dict_get(p_vars, "attach");
172         const xs_str *to           = xs_dict_get(p_vars, "to");
173         const xs_str *sensitive    = xs_dict_get(p_vars, "sensitive");
174         const xs_str *summary      = xs_dict_get(p_vars, "summary");
175         const xs_str *edit_id      = xs_dict_get(p_vars, "edit_id");
176-        const xs_str *alt_text     = xs_dict_get(p_vars, "alt_text");
177         int priv             = !xs_is_null(xs_dict_get(p_vars, "mentioned_only"));
178         int store_as_draft   = !xs_is_null(xs_dict_get(p_vars, "is_draft"));
179         xs *attach_list      = xs_list_new();
180 
181-        /* default alt text */
182-        if (xs_is_null(alt_text))
183-            alt_text = "";
184+        /* iterate the attachments */
185+        int max_attachments = xs_number_get(xs_dict_get_def(srv_config, "max_attachments", "4"));
186 
187-        /* is attach_url set? */
188-        if (!xs_is_null(attach_url) && *attach_url != '\0') {
189-            xs *l = xs_list_new();
190+        for (int att_n = 0; att_n < max_attachments; att_n++) {
191+            xs *url_lbl = xs_fmt("attach_url_%d", att_n);
192+            xs *att_lbl = xs_fmt("attach_%d", att_n);
193+            xs *alt_lbl = xs_fmt("alt_text_%d", att_n);
194 
195-            l = xs_list_append(l, attach_url);
196-            l = xs_list_append(l, alt_text);
197+            const char *attach_url     = xs_dict_get(p_vars, url_lbl);
198+            const xs_list *attach_file = xs_dict_get(p_vars, att_lbl);
199+            const char *alt_text       = xs_dict_get_def(p_vars, alt_lbl, "");
200 
201-            attach_list = xs_list_append(attach_list, l);
202-        }
203+            if (xs_is_string(attach_url) && *attach_url != '\0') {
204+                xs *l = xs_list_new();
205 
206-        /* is attach_file set? */
207-        if (!xs_is_null(attach_file) && xs_type(attach_file) == XSTYPE_LIST) {
208-            const char *fn = xs_list_get(attach_file, 0);
209+                l = xs_list_append(l, attach_url);
210+                l = xs_list_append(l, alt_text);
211 
212-            if (*fn != '\0') {
213-                char *ext = strrchr(fn, '.');
214-                xs *hash  = xs_md5_hex(fn, strlen(fn));
215-                xs *id    = xs_fmt("%s%s", hash, ext);
216-                xs *url   = xs_fmt("%s/s/%s", snac.actor, id);
217-                int fo    = xs_number_get(xs_list_get(attach_file, 1));
218-                int fs    = xs_number_get(xs_list_get(attach_file, 2));
219+                attach_list = xs_list_append(attach_list, l);
220+            }
221+            else
222+            if (xs_is_list(attach_file)) {
223+                const char *fn = xs_list_get(attach_file, 0);
224 
225-                /* store */
226-                static_put(&snac, id, payload + fo, fs);
227+                if (xs_is_string(fn) && *fn != '\0') {
228+                    char *ext = strrchr(fn, '.');
229+                    xs *hash  = xs_md5_hex(fn, strlen(fn));
230+                    xs *id    = xs_fmt("%s%s", hash, ext);
231+                    xs *url   = xs_fmt("%s/s/%s", snac.actor, id);
232+                    int fo    = xs_number_get(xs_list_get(attach_file, 1));
233+                    int fs    = xs_number_get(xs_list_get(attach_file, 2));
234 
235-                xs *l = xs_list_new();
236+                    /* store */
237+                    static_put(&snac, id, payload + fo, fs);
238 
239-                l = xs_list_append(l, url);
240-                l = xs_list_append(l, alt_text);
241+                    xs *l = xs_list_new();
242 
243-                attach_list = xs_list_append(attach_list, l);
244+                    l = xs_list_append(l, url);
245+                    l = xs_list_append(l, alt_text);
246+
247+                    attach_list = xs_list_append(attach_list, l);
248+                }
249             }
250         }
251