diff options
| author | 2023-07-05 09:51:45 +0200 | |
|---|---|---|
| committer | 2023-07-05 09:51:45 +0200 | |
| commit | 8faa06652d8fd1bbbd1139170b7892b6d81d0927 (patch) | |
| tree | ee656804e6d3c04b48a9f3bffa8c425701aeac57 | |
| parent | Backport from xs. (diff) | |
| parent | Also call process_tags() when in the public timeline's bio. (diff) | |
| download | snac2-8faa06652d8fd1bbbd1139170b7892b6d81d0927.tar.gz snac2-8faa06652d8fd1bbbd1139170b7892b6d81d0927.tar.xz snac2-8faa06652d8fd1bbbd1139170b7892b6d81d0927.zip | |
Merge branch 'master' of triptico.com:git/snac2
| -rw-r--r-- | RELEASE_NOTES.md | 4 | ||||
| -rw-r--r-- | TODO.md | 13 | ||||
| -rw-r--r-- | activitypub.c | 17 | ||||
| -rw-r--r-- | data.c | 17 | ||||
| -rw-r--r-- | html.c | 43 | ||||
| -rw-r--r-- | snac.h | 2 |
6 files changed, 71 insertions, 25 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 4fbe71b..d6ce13c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | Added proper HTTP caching when serving static files (attached images, avatars, etc.) | 5 | Added proper HTTP caching when serving static files (attached images, avatars, etc.) |
| 6 | 6 | ||
| 7 | Sensitive content messages can now have a summary (i.e. no longer limited to ...) | ||
| 8 | |||
| 7 | Added a way to block full instances (from the command-line tool, as I consider this to be an administration priviledge). | 9 | Added a way to block full instances (from the command-line tool, as I consider this to be an administration priviledge). |
| 8 | 10 | ||
| 9 | If the user style.css does not exist, the server-wide one if served instead. | 11 | If the user style.css does not exist, the server-wide one if served instead. |
| @@ -18,6 +20,8 @@ For polls, show the time left before it closes. | |||
| 18 | 20 | ||
| 19 | Added some support for post pinning. | 21 | Added some support for post pinning. |
| 20 | 22 | ||
| 23 | Fixed a bug that prevented unfollows to be shown in the notification area. | ||
| 24 | |||
| 21 | ## 2.35 | 25 | ## 2.35 |
| 22 | 26 | ||
| 23 | Fixed broken URL links with the # symbol on them. | 27 | Fixed broken URL links with the # symbol on them. |
| @@ -12,8 +12,6 @@ Mastodon API: fix whatever the fuck is making the official app and Megalodon to | |||
| 12 | 12 | ||
| 13 | Improve support for audio attachments. | 13 | Improve support for audio attachments. |
| 14 | 14 | ||
| 15 | Add a quick way to block complete domains / instances. | ||
| 16 | |||
| 17 | Add support for pinning posts. | 15 | Add support for pinning posts. |
| 18 | 16 | ||
| 19 | Important: deleting a follower should do more that just delete the object, see https://codeberg.org/grunfink/snac2/issues/43#issuecomment-956721 | 17 | Important: deleting a follower should do more that just delete the object, see https://codeberg.org/grunfink/snac2/issues/43#issuecomment-956721 |
| @@ -33,7 +31,8 @@ Implement bulleted lists. Mastodon is crap and won't show them, but other implem | |||
| 33 | User request: "will it be possible to click on a link and instead of opening the original instance, we'll be able only to see a list of the posts of this person here in comam?. Something like Mastodon does." | 31 | User request: "will it be possible to click on a link and instead of opening the original instance, we'll be able only to see a list of the posts of this person here in comam?. Something like Mastodon does." |
| 34 | 32 | ||
| 35 | Test all the possible XSS vulnerabilities in https://raw.githubusercontent.com/danielmiessler/SecLists/master/Fuzzing/big-list-of-naughty-strings.txt | 33 | Test all the possible XSS vulnerabilities in https://raw.githubusercontent.com/danielmiessler/SecLists/master/Fuzzing/big-list-of-naughty-strings.txt |
| 36 | Minor data storage housekeeping: index_list() and index_list_desc() should not return deleted (i.e. dash prefixed) entries; _object_user_cache() should call index_del() (?). | 34 | |
| 35 | index_list() and index_list_desc() should not return deleted (i.e. dash prefixed) entries. | ||
| 37 | 36 | ||
| 38 | ## Closed | 37 | ## Closed |
| 39 | 38 | ||
| @@ -260,3 +259,11 @@ Replace weird, vestigial 'touch-by-append-spaces' in actor_get() with a more pro | |||
| 260 | With this new disk layout, hidden posts (and their children) can be directly skipped when rendering the HTML timeline (are there any other implications?) (2023-06-23T06:48:51+0200). | 259 | With this new disk layout, hidden posts (and their children) can be directly skipped when rendering the HTML timeline (are there any other implications?) (2023-06-23T06:48:51+0200). |
| 261 | 260 | ||
| 262 | Implement HTTP caches (If-None-Match / ETag) (2023-07-02T11:11:20+0200). | 261 | Implement HTTP caches (If-None-Match / ETag) (2023-07-02T11:11:20+0200). |
| 262 | |||
| 263 | Add a quick way to block complete domains / instances (2023-07-04T14:35:44+0200). | ||
| 264 | |||
| 265 | _object_user_cache() should call index_del() (2023-07-04T14:36:37+0200). | ||
| 266 | |||
| 267 | Add a content warning description (2023-07-04T15:02:19+0200). | ||
| 268 | |||
| 269 | Propagate the CW status and description from the replied message (2023-07-04T15:02:19+0200). | ||
diff --git a/activitypub.c b/activitypub.c index ce72f3f..fa592e7 100644 --- a/activitypub.c +++ b/activitypub.c | |||
| @@ -449,7 +449,7 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg) | |||
| 449 | } | 449 | } |
| 450 | 450 | ||
| 451 | 451 | ||
| 452 | void process_tags(snac *snac, const char *content, xs_str **n_content, xs_list **tag) | 452 | xs_str *process_tags(snac *snac, const char *content, xs_list **tag) |
| 453 | /* parses mentions and tags from content */ | 453 | /* parses mentions and tags from content */ |
| 454 | { | 454 | { |
| 455 | xs_str *nc = xs_str_new(NULL); | 455 | xs_str *nc = xs_str_new(NULL); |
| @@ -559,8 +559,9 @@ void process_tags(snac *snac, const char *content, xs_str **n_content, xs_list * | |||
| 559 | n++; | 559 | n++; |
| 560 | } | 560 | } |
| 561 | 561 | ||
| 562 | *n_content = nc; | 562 | *tag = tl; |
| 563 | *tag = tl; | 563 | |
| 564 | return nc; | ||
| 564 | } | 565 | } |
| 565 | 566 | ||
| 566 | 567 | ||
| @@ -688,6 +689,9 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor, | |||
| 688 | /* finally, store it in the notification folder */ | 689 | /* finally, store it in the notification folder */ |
| 689 | if (strcmp(type, "Follow") == 0) | 690 | if (strcmp(type, "Follow") == 0) |
| 690 | objid = id; | 691 | objid = id; |
| 692 | else | ||
| 693 | if (strcmp(utype, "Follow") == 0) | ||
| 694 | objid = actor; | ||
| 691 | 695 | ||
| 692 | notify_add(snac, type, utype, actor, objid != NULL ? objid : id); | 696 | notify_add(snac, type, utype, actor, objid != NULL ? objid : id); |
| 693 | } | 697 | } |
| @@ -836,6 +840,7 @@ xs_dict *msg_actor(snac *snac) | |||
| 836 | xs *ctxt = xs_list_new(); | 840 | xs *ctxt = xs_list_new(); |
| 837 | xs *icon = xs_dict_new(); | 841 | xs *icon = xs_dict_new(); |
| 838 | xs *keys = xs_dict_new(); | 842 | xs *keys = xs_dict_new(); |
| 843 | xs *tags = xs_list_new(); | ||
| 839 | xs *avtr = NULL; | 844 | xs *avtr = NULL; |
| 840 | xs *kid = NULL; | 845 | xs *kid = NULL; |
| 841 | xs *f_bio = NULL; | 846 | xs *f_bio = NULL; |
| @@ -853,8 +858,10 @@ xs_dict *msg_actor(snac *snac) | |||
| 853 | msg = xs_dict_set(msg, "preferredUsername", snac->uid); | 858 | msg = xs_dict_set(msg, "preferredUsername", snac->uid); |
| 854 | msg = xs_dict_set(msg, "published", xs_dict_get(snac->config, "published")); | 859 | msg = xs_dict_set(msg, "published", xs_dict_get(snac->config, "published")); |
| 855 | 860 | ||
| 856 | f_bio = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL); | 861 | xs *f_bio_2 = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL); |
| 862 | f_bio = process_tags(snac, f_bio_2, &tags); | ||
| 857 | msg = xs_dict_set(msg, "summary", f_bio); | 863 | msg = xs_dict_set(msg, "summary", f_bio); |
| 864 | msg = xs_dict_set(msg, "tag", tags); | ||
| 858 | 865 | ||
| 859 | char *folders[] = { "inbox", "outbox", "followers", "following", NULL }; | 866 | char *folders[] = { "inbox", "outbox", "followers", "following", NULL }; |
| 860 | for (n = 0; folders[n]; n++) { | 867 | for (n = 0; folders[n]; n++) { |
| @@ -1053,7 +1060,7 @@ xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts, | |||
| 1053 | irt = xs_val_new(XSTYPE_NULL); | 1060 | irt = xs_val_new(XSTYPE_NULL); |
| 1054 | 1061 | ||
| 1055 | /* extract the mentions and hashtags and convert the content */ | 1062 | /* extract the mentions and hashtags and convert the content */ |
| 1056 | process_tags(snac, fc2, &fc1, &tag); | 1063 | fc1 = process_tags(snac, fc2, &tag); |
| 1057 | 1064 | ||
| 1058 | /* create the attachment list, if there are any */ | 1065 | /* create the attachment list, if there are any */ |
| 1059 | if (!xs_is_null(attach)) { | 1066 | if (!xs_is_null(attach)) { |
| @@ -496,9 +496,11 @@ xs_list *index_list(const char *fn, int max) | |||
| 496 | list = xs_list_new(); | 496 | list = xs_list_new(); |
| 497 | 497 | ||
| 498 | while (n < max && fgets(line, sizeof(line), f) != NULL) { | 498 | while (n < max && fgets(line, sizeof(line), f) != NULL) { |
| 499 | line[32] = '\0'; | 499 | if (line[0] != '-') { |
| 500 | list = xs_list_append(list, line); | 500 | line[32] = '\0'; |
| 501 | n++; | 501 | list = xs_list_append(list, line); |
| 502 | n++; | ||
| 503 | } | ||
| 502 | } | 504 | } |
| 503 | 505 | ||
| 504 | fclose(f); | 506 | fclose(f); |
| @@ -524,9 +526,11 @@ xs_list *index_list_desc(const char *fn, int skip, int show) | |||
| 524 | /* move to the end minus one entry (or more, if skipping entries) */ | 526 | /* move to the end minus one entry (or more, if skipping entries) */ |
| 525 | if (!fseek(f, 0, SEEK_END) && !fseek(f, (skip + 1) * -33, SEEK_CUR)) { | 527 | if (!fseek(f, 0, SEEK_END) && !fseek(f, (skip + 1) * -33, SEEK_CUR)) { |
| 526 | while (n < show && fgets(line, sizeof(line), f) != NULL) { | 528 | while (n < show && fgets(line, sizeof(line), f) != NULL) { |
| 527 | line[32] = '\0'; | 529 | if (line[0] != '-') { |
| 528 | list = xs_list_append(list, line); | 530 | line[32] = '\0'; |
| 529 | n++; | 531 | list = xs_list_append(list, line); |
| 532 | n++; | ||
| 533 | } | ||
| 530 | 534 | ||
| 531 | /* move backwards 2 entries */ | 535 | /* move backwards 2 entries */ |
| 532 | if (fseek(f, -66, SEEK_CUR) == -1) | 536 | if (fseek(f, -66, SEEK_CUR) == -1) |
| @@ -862,6 +866,7 @@ int _object_user_cache(snac *snac, const char *id, const char *cachedir, int del | |||
| 862 | 866 | ||
| 863 | if (del) { | 867 | if (del) { |
| 864 | ret = unlink(cfn); | 868 | ret = unlink(cfn); |
| 869 | index_del(idx, id); | ||
| 865 | } | 870 | } |
| 866 | else { | 871 | else { |
| 867 | if ((ret = link(ofn, cfn)) != -1) | 872 | if ((ret = link(ofn, cfn)) != -1) |
| @@ -362,8 +362,10 @@ d_char *html_user_header(snac *snac, d_char *s, int local) | |||
| 362 | s = xs_str_cat(s, s1); | 362 | s = xs_str_cat(s, s1); |
| 363 | 363 | ||
| 364 | if (local) { | 364 | if (local) { |
| 365 | xs *bio = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL); | 365 | xs *bio1 = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL); |
| 366 | xs *s1 = xs_fmt("<div class=\"p-note snac-top-user-bio\">%s</div>\n", bio); | 366 | xs *tags = xs_list_new(); |
| 367 | xs *bio2 = process_tags(snac, bio1, &tags); | ||
| 368 | xs *s1 = xs_fmt("<div class=\"p-note snac-top-user-bio\">%s</div>\n", bio2); | ||
| 367 | 369 | ||
| 368 | s = xs_str_cat(s, s1); | 370 | s = xs_str_cat(s, s1); |
| 369 | } | 371 | } |
| @@ -387,7 +389,8 @@ d_char *html_top_controls(snac *snac, d_char *s) | |||
| 387 | "<textarea class=\"snac-textarea\" name=\"content\" " | 389 | "<textarea class=\"snac-textarea\" name=\"content\" " |
| 388 | "rows=\"8\" wrap=\"virtual\" required=\"required\"></textarea>\n" | 390 | "rows=\"8\" wrap=\"virtual\" required=\"required\"></textarea>\n" |
| 389 | "<input type=\"hidden\" name=\"in_reply_to\" value=\"\">\n" | 391 | "<input type=\"hidden\" name=\"in_reply_to\" value=\"\">\n" |
| 390 | "<p>%s: <input type=\"checkbox\" name=\"sensitive\">\n" | 392 | "<p>%s: <input type=\"checkbox\" name=\"sensitive\"> " |
| 393 | "<input type=\"text\" name=\"summary\" placeholder=\"%s\">\n" | ||
| 391 | "<p>%s: <input type=\"checkbox\" name=\"mentioned_only\">\n" | 394 | "<p>%s: <input type=\"checkbox\" name=\"mentioned_only\">\n" |
| 392 | 395 | ||
| 393 | "<details><summary>%s</summary>\n" /** attach **/ | 396 | "<details><summary>%s</summary>\n" /** attach **/ |
| @@ -512,6 +515,7 @@ d_char *html_top_controls(snac *snac, d_char *s) | |||
| 512 | xs *s1 = xs_fmt(_tmpl, | 515 | xs *s1 = xs_fmt(_tmpl, |
| 513 | snac->actor, | 516 | snac->actor, |
| 514 | L("Sensitive content"), | 517 | L("Sensitive content"), |
| 518 | L("Sensitive content description"), | ||
| 515 | L("Only for mentioned people"), | 519 | L("Only for mentioned people"), |
| 516 | 520 | ||
| 517 | L("Attach..."), | 521 | L("Attach..."), |
| @@ -684,8 +688,10 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch | |||
| 684 | 688 | ||
| 685 | const char *prev_src1 = xs_dict_get(msg, "sourceContent"); | 689 | const char *prev_src1 = xs_dict_get(msg, "sourceContent"); |
| 686 | 690 | ||
| 687 | if (!xs_is_null(prev_src1) && strcmp(actor, snac->actor) == 0) { | 691 | if (!xs_is_null(prev_src1) && strcmp(actor, snac->actor) == 0) { /** edit **/ |
| 688 | xs *prev_src = xs_replace(prev_src1, "<", "<"); | 692 | xs *prev_src = xs_replace(prev_src1, "<", "<"); |
| 693 | const xs_val *sensitive = xs_dict_get(msg, "sensitive"); | ||
| 694 | const char *summary = xs_dict_get(msg, "summary"); | ||
| 689 | 695 | ||
| 690 | /* post can be edited */ | 696 | /* post can be edited */ |
| 691 | xs *s1 = xs_fmt( | 697 | xs *s1 = xs_fmt( |
| @@ -697,7 +703,8 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch | |||
| 697 | "rows=\"4\" wrap=\"virtual\" required=\"required\">%s</textarea>\n" | 703 | "rows=\"4\" wrap=\"virtual\" required=\"required\">%s</textarea>\n" |
| 698 | "<input type=\"hidden\" name=\"edit_id\" value=\"%s\">\n" | 704 | "<input type=\"hidden\" name=\"edit_id\" value=\"%s\">\n" |
| 699 | 705 | ||
| 700 | "<p>%s: <input type=\"checkbox\" name=\"sensitive\">\n" | 706 | "<p>%s: <input type=\"checkbox\" name=\"sensitive\" %s> " |
| 707 | "<input type=\"text\" name=\"summary\" placeholder=\"%s\" value=\"%s\">\n" | ||
| 701 | "<p>%s: <input type=\"checkbox\" name=\"mentioned_only\">\n" | 708 | "<p>%s: <input type=\"checkbox\" name=\"mentioned_only\">\n" |
| 702 | 709 | ||
| 703 | "<details><summary>%s</summary>\n" | 710 | "<details><summary>%s</summary>\n" |
| @@ -717,6 +724,9 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch | |||
| 717 | prev_src, | 724 | prev_src, |
| 718 | id, | 725 | id, |
| 719 | L("Sensitive content"), | 726 | L("Sensitive content"), |
| 727 | xs_type(sensitive) == XSTYPE_TRUE ? "checked" : "", | ||
| 728 | L("Sensitive content description"), | ||
| 729 | xs_is_null(summary) ? "" : summary, | ||
| 720 | L("Only for mentioned people"), | 730 | L("Only for mentioned people"), |
| 721 | L("Attach..."), | 731 | L("Attach..."), |
| 722 | L("File"), | 732 | L("File"), |
| @@ -728,10 +738,13 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch | |||
| 728 | s = xs_str_cat(s, s1); | 738 | s = xs_str_cat(s, s1); |
| 729 | } | 739 | } |
| 730 | 740 | ||
| 731 | { | 741 | { /** reply **/ |
| 732 | /* the post textarea */ | 742 | /* the post textarea */ |
| 733 | xs *ct = build_mentions(snac, msg); | 743 | xs *ct = build_mentions(snac, msg); |
| 734 | 744 | ||
| 745 | const xs_val *sensitive = xs_dict_get(msg, "sensitive"); | ||
| 746 | const char *summary = xs_dict_get(msg, "summary"); | ||
| 747 | |||
| 735 | xs *s1 = xs_fmt( | 748 | xs *s1 = xs_fmt( |
| 736 | "<p><details><summary>%s</summary>\n" | 749 | "<p><details><summary>%s</summary>\n" |
| 737 | "<p><div class=\"snac-note\" id=\"%s_reply\">\n" | 750 | "<p><div class=\"snac-note\" id=\"%s_reply\">\n" |
| @@ -741,7 +754,8 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch | |||
| 741 | "rows=\"4\" wrap=\"virtual\" required=\"required\">%s</textarea>\n" | 754 | "rows=\"4\" wrap=\"virtual\" required=\"required\">%s</textarea>\n" |
| 742 | "<input type=\"hidden\" name=\"in_reply_to\" value=\"%s\">\n" | 755 | "<input type=\"hidden\" name=\"in_reply_to\" value=\"%s\">\n" |
| 743 | 756 | ||
| 744 | "<p>%s: <input type=\"checkbox\" name=\"sensitive\">\n" | 757 | "<p>%s: <input type=\"checkbox\" name=\"sensitive\" %s> " |
| 758 | "<input type=\"text\" name=\"summary\" placeholder=\"%s\" value=\"%s\">\n" | ||
| 745 | "<p>%s: <input type=\"checkbox\" name=\"mentioned_only\">\n" | 759 | "<p>%s: <input type=\"checkbox\" name=\"mentioned_only\">\n" |
| 746 | 760 | ||
| 747 | "<details><summary>%s</summary>\n" | 761 | "<details><summary>%s</summary>\n" |
| @@ -761,6 +775,9 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch | |||
| 761 | ct, | 775 | ct, |
| 762 | id, | 776 | id, |
| 763 | L("Sensitive content"), | 777 | L("Sensitive content"), |
| 778 | xs_type(sensitive) == XSTYPE_TRUE ? "checked" : "", | ||
| 779 | L("Sensitive content description"), | ||
| 780 | xs_is_null(summary) ? "" : summary, | ||
| 764 | L("Only for mentioned people"), | 781 | L("Only for mentioned people"), |
| 765 | L("Attach..."), | 782 | L("Attach..."), |
| 766 | L("File"), | 783 | L("File"), |
| @@ -1437,7 +1454,7 @@ xs_str *html_notifications(snac *snac) | |||
| 1437 | "<form autocomplete=\"off\" " | 1454 | "<form autocomplete=\"off\" " |
| 1438 | "method=\"post\" action=\"%s/admin/clear-notifications\" id=\"clear\">\n" | 1455 | "method=\"post\" action=\"%s/admin/clear-notifications\" id=\"clear\">\n" |
| 1439 | "<input type=\"submit\" class=\"snac-btn-like\" value=\"%s\">\n" | 1456 | "<input type=\"submit\" class=\"snac-btn-like\" value=\"%s\">\n" |
| 1440 | "</form><p>", snac->actor, L("Clear all")); | 1457 | "</form><p>\n", snac->actor, L("Clear all")); |
| 1441 | s = xs_str_cat(s, s1); | 1458 | s = xs_str_cat(s, s1); |
| 1442 | 1459 | ||
| 1443 | while (xs_list_iter(&p, &v)) { | 1460 | while (xs_list_iter(&p, &v)) { |
| @@ -1498,16 +1515,19 @@ xs_str *html_notifications(snac *snac) | |||
| 1498 | else | 1515 | else |
| 1499 | if (strcmp(type, "Update") == 0 && strcmp(utype, "Question") == 0) | 1516 | if (strcmp(type, "Update") == 0 && strcmp(utype, "Question") == 0) |
| 1500 | label = L("Finished poll"); | 1517 | label = L("Finished poll"); |
| 1518 | else | ||
| 1519 | if (strcmp(type, "Undo") == 0 && strcmp(utype, "Follow") == 0) | ||
| 1520 | label = L("Unfollow"); | ||
| 1501 | 1521 | ||
| 1502 | xs *s1 = xs_fmt("<div class=\"snac-post-with-desc\">\n" | 1522 | xs *s1 = xs_fmt("<div class=\"snac-post-with-desc\">\n" |
| 1503 | "<p><b>%s by <a href=\"%s\">%s</a></b>:</p>\n", | 1523 | "<p><b>%s by <a href=\"%s\">%s</a></b>:</p>\n", |
| 1504 | label, actor_id, a_name); | 1524 | label, actor_id, a_name); |
| 1505 | s = xs_str_cat(s, s1); | 1525 | s = xs_str_cat(s, s1); |
| 1506 | 1526 | ||
| 1507 | if (strcmp(type, "Follow") == 0) { | 1527 | if (strcmp(type, "Follow") == 0 || strcmp(utype, "Follow") == 0) { |
| 1508 | s = xs_str_cat(s, "<div class=\"snac-post\">\n"); | 1528 | s = xs_str_cat(s, "<div class=\"snac-post\">\n"); |
| 1509 | 1529 | ||
| 1510 | s = html_msg_icon(snac, s, obj); | 1530 | s = html_actor_icon(s, actor, NULL, NULL, NULL, 0); |
| 1511 | 1531 | ||
| 1512 | s = xs_str_cat(s, "</div>\n"); | 1532 | s = xs_str_cat(s, "</div>\n"); |
| 1513 | } | 1533 | } |
| @@ -1843,6 +1863,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, | |||
| 1843 | xs_list *attach_file = xs_dict_get(p_vars, "attach"); | 1863 | xs_list *attach_file = xs_dict_get(p_vars, "attach"); |
| 1844 | xs_str *to = xs_dict_get(p_vars, "to"); | 1864 | xs_str *to = xs_dict_get(p_vars, "to"); |
| 1845 | xs_str *sensitive = xs_dict_get(p_vars, "sensitive"); | 1865 | xs_str *sensitive = xs_dict_get(p_vars, "sensitive"); |
| 1866 | xs_str *summary = xs_dict_get(p_vars, "summary"); | ||
| 1846 | xs_str *edit_id = xs_dict_get(p_vars, "edit_id"); | 1867 | xs_str *edit_id = xs_dict_get(p_vars, "edit_id"); |
| 1847 | xs_str *alt_text = xs_dict_get(p_vars, "alt_text"); | 1868 | xs_str *alt_text = xs_dict_get(p_vars, "alt_text"); |
| 1848 | int priv = !xs_is_null(xs_dict_get(p_vars, "mentioned_only")); | 1869 | int priv = !xs_is_null(xs_dict_get(p_vars, "mentioned_only")); |
| @@ -1921,7 +1942,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, | |||
| 1921 | 1942 | ||
| 1922 | if (sensitive != NULL) { | 1943 | if (sensitive != NULL) { |
| 1923 | msg = xs_dict_set(msg, "sensitive", xs_stock_true); | 1944 | msg = xs_dict_set(msg, "sensitive", xs_stock_true); |
| 1924 | msg = xs_dict_set(msg, "summary", "..."); | 1945 | msg = xs_dict_set(msg, "summary", xs_is_null(summary) ? "..." : summary); |
| 1925 | } | 1946 | } |
| 1926 | 1947 | ||
| 1927 | if (xs_is_null(edit_id)) { | 1948 | if (xs_is_null(edit_id)) { |
| @@ -207,6 +207,8 @@ int webfinger_get_handler(xs_dict *req, char *q_path, | |||
| 207 | 207 | ||
| 208 | const char *default_avatar_base64(void); | 208 | const char *default_avatar_base64(void); |
| 209 | 209 | ||
| 210 | xs_str *process_tags(snac *snac, const char *content, xs_list **tag); | ||
| 211 | |||
| 210 | xs_dict *msg_admiration(snac *snac, char *object, char *type); | 212 | xs_dict *msg_admiration(snac *snac, char *object, char *type); |
| 211 | xs_dict *msg_create(snac *snac, const xs_dict *object); | 213 | xs_dict *msg_create(snac *snac, const xs_dict *object); |
| 212 | xs_dict *msg_follow(snac *snac, const char *actor); | 214 | xs_dict *msg_follow(snac *snac, const char *actor); |