diff options
Diffstat (limited to 'html.c')
| -rw-r--r-- | html.c | 153 |
1 files changed, 144 insertions, 9 deletions
| @@ -1688,7 +1688,7 @@ xs_html *html_top_controls(snac *user) | |||
| 1688 | xs_html_text(L("Languages you usually post in:")), | 1688 | xs_html_text(L("Languages you usually post in:")), |
| 1689 | xs_html_sctag("br", NULL), | 1689 | xs_html_sctag("br", NULL), |
| 1690 | xs_html_sctag("input", | 1690 | xs_html_sctag("input", |
| 1691 | xs_html_attr("type", "next"), | 1691 | xs_html_attr("type", "text"), |
| 1692 | xs_html_attr("name", "post_langs"), | 1692 | xs_html_attr("name", "post_langs"), |
| 1693 | xs_html_attr("value", post_langs), | 1693 | xs_html_attr("value", post_langs), |
| 1694 | xs_html_attr("placeholder", L("en fr es de_AT")))), | 1694 | xs_html_attr("placeholder", L("en fr es de_AT")))), |
| @@ -1891,7 +1891,7 @@ xs_html *html_entry_controls(snac *user, const char *actor, | |||
| 1891 | xs_html_attr("name", "redir"), | 1891 | xs_html_attr("name", "redir"), |
| 1892 | xs_html_attr("value", redir)))); | 1892 | xs_html_attr("value", redir)))); |
| 1893 | 1893 | ||
| 1894 | if (!xs_startswith(id, user->actor)) { | 1894 | if (!is_msg_mine(user, id)) { |
| 1895 | if (xs_list_in(likes, user->md5) == -1) { | 1895 | if (xs_list_in(likes, user->md5) == -1) { |
| 1896 | /* not already liked; add button */ | 1896 | /* not already liked; add button */ |
| 1897 | xs_html_add(form, | 1897 | xs_html_add(form, |
| @@ -2387,6 +2387,23 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, | |||
| 2387 | /* c contains sanitized HTML */ | 2387 | /* c contains sanitized HTML */ |
| 2388 | xs_html_add(snac_content, | 2388 | xs_html_add(snac_content, |
| 2389 | xs_html_raw(c)); | 2389 | xs_html_raw(c)); |
| 2390 | |||
| 2391 | /* quoted post */ | ||
| 2392 | const char *quoted_id = xs_or(xs_dict_get(msg, "quoteUri"), xs_dict_get(msg, "quoteUrl")); | ||
| 2393 | |||
| 2394 | if (xs_is_string(quoted_id) && xs_match(quoted_id, "https://*|http://*")) { /** **/ | ||
| 2395 | xs *quoted_post = NULL; | ||
| 2396 | |||
| 2397 | if (valid_status(object_get(quoted_id, "ed_post))) { | ||
| 2398 | xs_html_add(snac_content, | ||
| 2399 | xs_html_tag("blockquote", | ||
| 2400 | xs_html_attr("class", "snac-quoted-post"), | ||
| 2401 | html_entry(user, quoted_post, 1, 1, NULL, 1))); | ||
| 2402 | } | ||
| 2403 | else | ||
| 2404 | if (user) | ||
| 2405 | enqueue_object_request(user, quoted_id, 0); | ||
| 2406 | } | ||
| 2390 | } | 2407 | } |
| 2391 | 2408 | ||
| 2392 | if (strcmp(type, "Question") == 0) { /** question content **/ | 2409 | if (strcmp(type, "Question") == 0) { /** question content **/ |
| @@ -2402,7 +2419,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, | |||
| 2402 | if (read_only) | 2419 | if (read_only) |
| 2403 | closed = 1; /* non-identified page; show as closed */ | 2420 | closed = 1; /* non-identified page; show as closed */ |
| 2404 | else | 2421 | else |
| 2405 | if (user && xs_startswith(id, user->actor)) | 2422 | if (user && is_msg_mine(user, id)) |
| 2406 | closed = 1; /* we questioned; closed for us */ | 2423 | closed = 1; /* we questioned; closed for us */ |
| 2407 | else | 2424 | else |
| 2408 | if (user && was_question_voted(user, id)) | 2425 | if (user && was_question_voted(user, id)) |
| @@ -2610,7 +2627,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, | |||
| 2610 | xs_html_attr("title", name)))); | 2627 | xs_html_attr("title", name)))); |
| 2611 | } | 2628 | } |
| 2612 | else | 2629 | else |
| 2613 | if (xs_startswith(type, "video/")) { | 2630 | if (xs_startswith(type, "video/") || strcmp(type, "Video") == 0) { |
| 2614 | xs_html_add(content_attachments, | 2631 | xs_html_add(content_attachments, |
| 2615 | xs_html_tag("video", | 2632 | xs_html_tag("video", |
| 2616 | xs_html_attr("preload", "none"), | 2633 | xs_html_attr("preload", "none"), |
| @@ -3214,7 +3231,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, | |||
| 3214 | continue; | 3231 | continue; |
| 3215 | } | 3232 | } |
| 3216 | /* hide non-public posts viewed from outside */ | 3233 | /* hide non-public posts viewed from outside */ |
| 3217 | if (read_only && scope != SCOPE_PUBLIC){ | 3234 | if (read_only && (scope != SCOPE_PUBLIC && scope != SCOPE_UNLISTED)) { |
| 3218 | continue; | 3235 | continue; |
| 3219 | } | 3236 | } |
| 3220 | 3237 | ||
| @@ -3331,10 +3348,11 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c | |||
| 3331 | 3348 | ||
| 3332 | /* content (user bio) */ | 3349 | /* content (user bio) */ |
| 3333 | const char *c = xs_dict_get(actor, "summary"); | 3350 | const char *c = xs_dict_get(actor, "summary"); |
| 3351 | const xs_val *tag = xs_dict_get(actor, "tag"); | ||
| 3334 | 3352 | ||
| 3335 | if (!xs_is_null(c)) { | 3353 | if (!xs_is_null(c)) { |
| 3336 | xs *sc = sanitize(c); | 3354 | xs *sc = sanitize(c); |
| 3337 | sc = replace_shortnames(sc, xs_dict_get(actor, "tag"), 2, proxy); | 3355 | sc = replace_shortnames(sc, tag, 2, proxy); |
| 3338 | 3356 | ||
| 3339 | xs_html *snac_content = xs_html_tag("div", | 3357 | xs_html *snac_content = xs_html_tag("div", |
| 3340 | xs_html_attr("class", "snac-content")); | 3358 | xs_html_attr("class", "snac-content")); |
| @@ -3350,6 +3368,93 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c | |||
| 3350 | xs_html_add(snac_post, snac_content); | 3368 | xs_html_add(snac_post, snac_content); |
| 3351 | } | 3369 | } |
| 3352 | 3370 | ||
| 3371 | /* add user metadata */ | ||
| 3372 | xs_html *snac_metadata = xs_html_tag("div", | ||
| 3373 | xs_html_attr("class", "snac-metadata")); | ||
| 3374 | |||
| 3375 | int count = 0; | ||
| 3376 | const xs_val *address = xs_dict_get(actor, "vcard:Address"); | ||
| 3377 | if (xs_is_string(address)) { | ||
| 3378 | xs_html_add(snac_metadata, | ||
| 3379 | xs_html_tag("span", | ||
| 3380 | xs_html_attr("class", "snac-property-name"), | ||
| 3381 | xs_html_raw("📍 Location")), | ||
| 3382 | xs_html_text(":"), | ||
| 3383 | xs_html_raw(" "), | ||
| 3384 | xs_html_tag("span", | ||
| 3385 | xs_html_attr("class", "snac-property-value p-adr"), | ||
| 3386 | xs_html_text(address)), | ||
| 3387 | xs_html_sctag("br", NULL)); | ||
| 3388 | |||
| 3389 | count++; | ||
| 3390 | } | ||
| 3391 | |||
| 3392 | const xs_val *birthday = xs_dict_get(actor, "vcard:bday"); | ||
| 3393 | if (xs_is_string(birthday)) { | ||
| 3394 | xs_html_add(snac_metadata, | ||
| 3395 | xs_html_tag("span", | ||
| 3396 | xs_html_attr("class", "snac-property-name"), | ||
| 3397 | xs_html_raw("🎂 Birthday")), | ||
| 3398 | xs_html_text(":"), | ||
| 3399 | xs_html_raw(" "), | ||
| 3400 | xs_html_tag("time", | ||
| 3401 | xs_html_attr("class", "snac-property-value dt-bday"), | ||
| 3402 | xs_html_text(birthday)), | ||
| 3403 | xs_html_sctag("br", NULL)); | ||
| 3404 | |||
| 3405 | count++; | ||
| 3406 | } | ||
| 3407 | |||
| 3408 | const xs_list *attachment = xs_dict_get(actor, "attachment"); | ||
| 3409 | if (count > 0 && xs_list_len(attachment) > 0) { | ||
| 3410 | xs_html_add(snac_metadata, | ||
| 3411 | xs_html_sctag("hr", | ||
| 3412 | xs_html_attr("class", "snac-property-divider"))); | ||
| 3413 | } | ||
| 3414 | |||
| 3415 | const xs_val *v; | ||
| 3416 | xs_list_foreach(attachment, v) { | ||
| 3417 | const char *type = xs_dict_get(v, "type"); | ||
| 3418 | const char *name = xs_dict_get(v, "name"); | ||
| 3419 | const char *value = xs_dict_get(v, "value"); | ||
| 3420 | |||
| 3421 | if (!xs_is_null(type) && !xs_is_null(name) && | ||
| 3422 | !xs_is_null(value) && strcmp(type, "PropertyValue") == 0) { | ||
| 3423 | /* both the name and the value can contain emoji */ | ||
| 3424 | xs *nam = sanitize(name); | ||
| 3425 | nam = replace_shortnames(nam, tag, 1, proxy); | ||
| 3426 | |||
| 3427 | /* todo: sometimes the value is transmitted as markdown and not html ._. */ | ||
| 3428 | xs *val = sanitize(value); | ||
| 3429 | val = replace_shortnames(val, tag, 1, proxy); | ||
| 3430 | |||
| 3431 | /* delete <p> tags, because some software sends them */ | ||
| 3432 | val = xs_replace_i(val, "<p>", ""); | ||
| 3433 | val = xs_replace_i(val, "</p>", ""); | ||
| 3434 | |||
| 3435 | xs_html_add(snac_metadata, | ||
| 3436 | xs_html_tag("span", | ||
| 3437 | xs_html_attr("class", "snac-property-name"), | ||
| 3438 | xs_html_raw(nam)), | ||
| 3439 | xs_html_text(":"), | ||
| 3440 | xs_html_raw(" "), | ||
| 3441 | xs_html_tag("span", | ||
| 3442 | xs_html_attr("class", "snac-property-value"), | ||
| 3443 | xs_html_raw(val)), | ||
| 3444 | xs_html_sctag("br", NULL)); | ||
| 3445 | |||
| 3446 | count++; | ||
| 3447 | } | ||
| 3448 | } | ||
| 3449 | |||
| 3450 | if (count > 0) { | ||
| 3451 | xs_html_add(snac_post, snac_metadata); | ||
| 3452 | } | ||
| 3453 | else { | ||
| 3454 | /* free the html, by rendering it... */ | ||
| 3455 | xs_free(xs_html_render(snac_metadata)); | ||
| 3456 | } | ||
| 3457 | |||
| 3353 | /* buttons */ | 3458 | /* buttons */ |
| 3354 | xs *btn_form_action = xs_fmt("%s/admin/action", user->actor); | 3459 | xs *btn_form_action = xs_fmt("%s/admin/action", user->actor); |
| 3355 | 3460 | ||
| @@ -3555,9 +3660,13 @@ xs_str *html_notifications(snac *user, int skip, int show) | |||
| 3555 | 3660 | ||
| 3556 | if (valid_status(actor_get(actor_id, &actor))) | 3661 | if (valid_status(actor_get(actor_id, &actor))) |
| 3557 | a_name = actor_name(actor, proxy); | 3662 | a_name = actor_name(actor, proxy); |
| 3558 | else | 3663 | else { |
| 3559 | a_name = xs_dup(actor_id); | 3664 | a_name = xs_dup(actor_id); |
| 3560 | 3665 | ||
| 3666 | /* actor not here: request it */ | ||
| 3667 | enqueue_actor_refresh(user, actor_id, 0); | ||
| 3668 | } | ||
| 3669 | |||
| 3561 | xs *label_sanitized = sanitize(type); | 3670 | xs *label_sanitized = sanitize(type); |
| 3562 | const char *label = label_sanitized; | 3671 | const char *label = label_sanitized; |
| 3563 | 3672 | ||
| @@ -3630,7 +3739,7 @@ xs_str *html_notifications(snac *user, int skip, int show) | |||
| 3630 | xs_html_attr("class", "snac-post-with-desc"), | 3739 | xs_html_attr("class", "snac-post-with-desc"), |
| 3631 | html_label); | 3740 | html_label); |
| 3632 | 3741 | ||
| 3633 | if (strcmp(type, "Follow") == 0 || strcmp(utype, "Follow") == 0 || strcmp(type, "Block") == 0) { | 3742 | if (strcmp(type, "Block") == 0) { |
| 3634 | if (actor) | 3743 | if (actor) |
| 3635 | xs_html_add(entry, | 3744 | xs_html_add(entry, |
| 3636 | xs_html_tag("div", | 3745 | xs_html_tag("div", |
| @@ -3638,6 +3747,32 @@ xs_str *html_notifications(snac *user, int skip, int show) | |||
| 3638 | html_actor_icon(user, actor, NULL, NULL, NULL, -1, 0, proxy, NULL, NULL))); | 3747 | html_actor_icon(user, actor, NULL, NULL, NULL, -1, 0, proxy, NULL, NULL))); |
| 3639 | } | 3748 | } |
| 3640 | else | 3749 | else |
| 3750 | if (strcmp(type, "Follow") == 0 || strcmp(utype, "Follow") == 0) { | ||
| 3751 | if (actor) { | ||
| 3752 | xs *action = xs_fmt("%s/admin/action", user->actor); | ||
| 3753 | xs_html *button = NULL; | ||
| 3754 | |||
| 3755 | if (following_check(user, actor_id)) | ||
| 3756 | button = html_button("unfollow", L("Unfollow"), L("Stop following this user's activity")); | ||
| 3757 | else | ||
| 3758 | button = html_button("follow", L("Follow"), L("Start following this user's activity")); | ||
| 3759 | |||
| 3760 | xs_html_add(entry, | ||
| 3761 | xs_html_tag("div", | ||
| 3762 | xs_html_attr("class", "snac-post"), | ||
| 3763 | html_actor_icon(user, actor, NULL, NULL, NULL, -1, 0, proxy, NULL, NULL), | ||
| 3764 | xs_html_tag("form", | ||
| 3765 | xs_html_attr("method", "post"), | ||
| 3766 | xs_html_attr("action", action), | ||
| 3767 | xs_html_sctag("input", | ||
| 3768 | xs_html_attr("type", "hidden"), | ||
| 3769 | xs_html_attr("name", "actor"), | ||
| 3770 | xs_html_attr("value", actor_id)), | ||
| 3771 | button, | ||
| 3772 | xs_html_sctag("br", NULL)))); | ||
| 3773 | } | ||
| 3774 | } | ||
| 3775 | else | ||
| 3641 | if (strcmp(type, "Move") == 0) { | 3776 | if (strcmp(type, "Move") == 0) { |
| 3642 | const xs_dict *o_msg = xs_dict_get(noti, "msg"); | 3777 | const xs_dict *o_msg = xs_dict_get(noti, "msg"); |
| 3643 | const char *target; | 3778 | const char *target; |
| @@ -4880,7 +5015,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, | |||
| 4880 | } | 5015 | } |
| 4881 | else { | 5016 | else { |
| 4882 | /* delete an entry */ | 5017 | /* delete an entry */ |
| 4883 | if (xs_startswith(id, snac.actor) && !is_draft(&snac, id)) { | 5018 | if (is_msg_mine(&snac, id) && !is_draft(&snac, id)) { |
| 4884 | /* it's a post by us: generate a delete */ | 5019 | /* it's a post by us: generate a delete */ |
| 4885 | xs *msg = msg_delete(&snac, id); | 5020 | xs *msg = msg_delete(&snac, id); |
| 4886 | 5021 | ||