summaryrefslogtreecommitdiff
path: root/html.c
diff options
context:
space:
mode:
Diffstat (limited to 'html.c')
-rw-r--r--html.c212
1 files changed, 156 insertions, 56 deletions
diff --git a/html.c b/html.c
index 46ef735..a251e21 100644
--- a/html.c
+++ b/html.c
@@ -113,9 +113,13 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date,
xs *name = actor_name(actor);
/* get the avatar */
- if ((v = xs_dict_get(actor, "icon")) != NULL &&
- (v = xs_dict_get(v, "url")) != NULL) {
- avatar = xs_dup(v);
+ if ((v = xs_dict_get(actor, "icon")) != NULL) {
+ /* if it's a list (Peertube), get the first one */
+ if (xs_type(v) == XSTYPE_LIST)
+ v = xs_list_get(v, 0);
+
+ if ((v = xs_dict_get(v, "url")) != NULL)
+ avatar = xs_dup(v);
}
if (avatar == NULL)
@@ -245,7 +249,7 @@ xs_html *html_msg_icon(snac *user, char *actor_id, const xs_dict *msg)
xs *actor = NULL;
xs_html *actor_icon = NULL;
- if (actor_id && valid_status(actor_get(actor_id, &actor))) {
+ if (actor_id && valid_status(actor_get_refresh(user, actor_id, &actor))) {
char *date = NULL;
char *udate = NULL;
char *url = NULL;
@@ -273,7 +277,8 @@ xs_html *html_note(snac *user, char *summary,
char *edit_id, char *actor_id,
xs_val *cw_yn, char *cw_text,
xs_val *mnt_only, char *redir,
- char *in_reply_to, int poll)
+ char *in_reply_to, int poll,
+ char *att_file, char *att_alt_text)
{
xs *action = xs_fmt("%s/admin/note", user->actor);
@@ -359,19 +364,37 @@ xs_html *html_note(snac *user, char *summary,
xs_html_attr("name", "edit_id"),
xs_html_attr("value", edit_id)));
+ /* attachment controls */
+ xs_html *att;
+
xs_html_add(form,
xs_html_tag("p", NULL),
- xs_html_tag("details",
+ att = xs_html_tag("details",
xs_html_tag("summary",
xs_html_text(L("Attachment..."))),
- xs_html_tag("p", NULL),
- xs_html_sctag("input",
- xs_html_attr("type", "file"),
- xs_html_attr("name", "attach")),
- xs_html_sctag("input",
- xs_html_attr("type", "text"),
- xs_html_attr("name", "alt_text"),
- xs_html_attr("placeholder", L("Attachment description")))));
+ xs_html_tag("p", NULL)));
+
+ if (att_file && *att_file)
+ xs_html_add(att,
+ xs_html_text(L("File:")),
+ xs_html_sctag("input",
+ xs_html_attr("type", "text"),
+ xs_html_attr("name", "attach_url"),
+ xs_html_attr("title", L("Clear this field to delete the attachment")),
+ xs_html_attr("value", att_file)));
+ else
+ xs_html_add(att,
+ xs_html_sctag("input",
+ xs_html_attr("type", "file"),
+ xs_html_attr("name", "attach")));
+
+ xs_html_add(att,
+ xs_html_text(" "),
+ xs_html_sctag("input",
+ xs_html_attr("type", "text"),
+ xs_html_attr("name", "alt_text"),
+ xs_html_attr("value", att_alt_text),
+ xs_html_attr("placeholder", L("Attachment description"))));
/* add poll controls */
if (poll) {
@@ -551,7 +574,7 @@ static xs_html *html_instance_body(char *tag)
}
-xs_html *html_user_head(snac *user, char *desc)
+xs_html *html_user_head(snac *user, char *desc, char *url)
{
xs_html *head = html_base_head();
@@ -641,6 +664,13 @@ xs_html *html_user_head(snac *user, char *desc)
xs_html_attr("title", "RSS"),
xs_html_attr("href", rss_url)));
+ /* ActivityPub alternate link (actor id) */
+ xs_html_add(head,
+ xs_html_sctag("link",
+ xs_html_attr("rel", "alternate"),
+ xs_html_attr("type", "application/activity+json"),
+ xs_html_attr("href", url ? url : user->actor)));
+
return head;
}
@@ -756,7 +786,7 @@ static xs_html *html_user_body(snac *user, int read_only)
if (read_only) {
xs *es1 = encode_html(xs_dict_get(user->config, "bio"));
- xs *bio1 = not_really_markdown(es1, NULL);
+ xs *bio1 = not_really_markdown(es1, NULL, NULL);
xs *tags = xs_list_new();
xs *bio2 = process_tags(user, bio1, &tags);
@@ -774,7 +804,7 @@ static xs_html *html_user_body(snac *user, int read_only)
xs_dict *val_links = user->links;
if (xs_is_null(val_links))
- val_links = xs_stock_dict;
+ val_links = xs_stock(XSTYPE_DICT);
xs_html *snac_metadata = xs_html_tag("div",
xs_html_attr("class", "snac-metadata"));
@@ -852,9 +882,9 @@ xs_html *html_top_controls(snac *snac)
"new_post_div", "new_post_form",
L("What's on your mind?"), "",
NULL, NULL,
- xs_stock_false, "",
- xs_stock_false, NULL,
- NULL, 1),
+ xs_stock(XSTYPE_FALSE), "",
+ xs_stock(XSTYPE_FALSE), NULL,
+ NULL, 1, "", ""),
/** operations **/
xs_html_tag("details",
@@ -1219,6 +1249,11 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const
xs_html_add(form,
html_button("like", L("Like"), L("Say you like this post")));
}
+ else {
+ /* not like it anymore */
+ xs_html_add(form,
+ html_button("unlike", L("Unlike"), L("Nah don't like it that much")));
+ }
}
else {
if (is_pinned(snac, id))
@@ -1235,6 +1270,11 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const
xs_html_add(form,
html_button("boost", L("Boost"), L("Announce this post to your followers")));
}
+ else {
+ /* already boosted; add button to regret */
+ xs_html_add(form,
+ html_button("unboost", L("Unboost"), L("I regret I boosted this")));
+ }
}
if (strcmp(actor, snac->actor) != 0) {
@@ -1278,6 +1318,20 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const
xs *form_id = xs_fmt("%s_edit_form", md5);
xs *redir = xs_fmt("%s_entry", md5);
+ char *att_file = "";
+ char *att_alt_text = "";
+ xs_list *att_list = xs_dict_get(msg, "attachment");
+
+ /* does it have an attachment? */
+ if (xs_type(att_list) == XSTYPE_LIST && xs_list_len(att_list)) {
+ xs_dict *d = xs_list_get(att_list, 0);
+
+ if (xs_type(d) == XSTYPE_DICT) {
+ att_file = xs_dict_get_def(d, "url", "");
+ att_alt_text = xs_dict_get_def(d, "name", "");
+ }
+ }
+
xs_html_add(controls, xs_html_tag("div",
xs_html_tag("p", NULL),
html_note(snac, L("Edit..."),
@@ -1285,8 +1339,8 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const
"", prev_src,
id, NULL,
xs_dict_get(msg, "sensitive"), xs_dict_get(msg, "summary"),
- xs_stock_false, redir,
- NULL, 0)),
+ xs_stock(XSTYPE_FALSE), redir,
+ NULL, 0, att_file, att_alt_text)),
xs_html_tag("p", NULL));
}
@@ -1304,8 +1358,8 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const
"", ct,
NULL, NULL,
xs_dict_get(msg, "sensitive"), xs_dict_get(msg, "summary"),
- xs_stock_false, redir,
- id, 0)),
+ xs_stock(XSTYPE_FALSE), redir,
+ id, 0, "", "")),
xs_html_tag("p", NULL));
}
@@ -1858,6 +1912,9 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
xs_list *p = children;
char *cmd5;
+ int cnt = 0;
+ int o_cnt = 0;
+
while (xs_list_iter(&p, &cmd5)) {
xs *chd = NULL;
@@ -1866,23 +1923,40 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
else
object_get_by_md5(cmd5, &chd);
- if (chd != NULL && xs_is_null(xs_dict_get(chd, "name"))) {
- xs_html *che = html_entry(user, chd, read_only, level + 1, cmd5, hide_children);
+ if (chd != NULL) {
+ if (xs_is_null(xs_dict_get(chd, "name"))) {
+ xs_html *che = html_entry(user, chd, read_only,
+ level + 1, cmd5, hide_children);
+
+ if (che != NULL) {
+ if (left > 3) {
+ xs_html_add(ch_older,
+ che);
+
+ o_cnt++;
+ }
+ else
+ xs_html_add(ch_container,
+ che);
- if (che != NULL) {
- if (left > 3)
- xs_html_add(ch_older,
- che);
- else
- xs_html_add(ch_container,
- che);
+ cnt++;
+ }
}
+
+ left--;
}
else
srv_debug(2, xs_fmt("cannot read child %s", cmd5));
-
- left--;
}
+
+ /* if no children were finally added, hide the details */
+ if (cnt == 0)
+ xs_html_add(ch_details,
+ xs_html_attr("style", "display: none"));
+
+ if (o_cnt == 0 && ch_older)
+ xs_html_add(ch_older,
+ xs_html_attr("style", "display: none"));
}
}
@@ -1917,6 +1991,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
double t = ftime();
xs *desc = NULL;
+ xs *alternate = NULL;
if (xs_list_len(list) == 1) {
/* only one element? pick the description from the source */
@@ -1925,13 +2000,15 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
object_get_by_md5(id, &d);
if (d && (v = xs_dict_get(d, "sourceContent")) != NULL)
desc = xs_dup(v);
+
+ alternate = xs_dup(xs_dict_get(d, "id"));
}
xs_html *head;
xs_html *body;
if (user) {
- head = html_user_head(user, desc);
+ head = html_user_head(user, desc, alternate);
body = html_user_body(user, read_only);
}
else {
@@ -1977,9 +2054,16 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
if (user != NULL && !is_msg_public(msg)) {
char *irt = xs_dict_get(msg, "inReplyTo");
+ /* is it a reply to something not in the storage? */
if (!xs_is_null(irt) && !object_here(irt)) {
- snac_debug(user, 1, xs_fmt("skipping non-public reply to an unknown post %s", v));
- continue;
+ /* is it for me? */
+ xs_list *to = xs_dict_get_def(msg, "to", xs_stock(XSTYPE_LIST));
+ xs_list *cc = xs_dict_get_def(msg, "cc", xs_stock(XSTYPE_LIST));
+
+ if (xs_list_in(to, user->actor) == -1 && xs_list_in(cc, user->actor) == -1) {
+ snac_debug(user, 1, xs_fmt("skipping non-public reply to an unknown post %s", v));
+ continue;
+ }
}
}
@@ -2077,9 +2161,7 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t)
snac_posts = xs_html_tag("details",
xs_html_attr("open", NULL),
xs_html_tag("summary",
- xs_html_text("...")),
- xs_html_tag("div",
- xs_html_attr("class", "snac-posts"))));
+ xs_html_text("..."))));
xs_list *p = list;
char *actor_id;
@@ -2181,9 +2263,9 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t)
dm_div_id, dm_form_id,
"", "",
NULL, actor_id,
- xs_stock_false, "",
- xs_stock_false, NULL,
- NULL, 0),
+ xs_stock(XSTYPE_FALSE), "",
+ xs_stock(XSTYPE_FALSE), NULL,
+ NULL, 0, "", ""),
xs_html_tag("p", NULL));
xs_html_add(snac_post, snac_controls);
@@ -2202,10 +2284,12 @@ xs_str *html_people(snac *user)
xs *wers = follower_list(user);
xs_html *html = xs_html_tag("html",
- html_user_head(user, NULL),
+ html_user_head(user, NULL, NULL),
xs_html_add(html_user_body(user, 0),
- html_people_list(user, wing, L("People you follow"), "i"),
- html_people_list(user, wers, L("People that follow you"), "e"),
+ xs_html_tag("div",
+ xs_html_attr("class", "snac-posts"),
+ html_people_list(user, wing, L("People you follow"), "i"),
+ html_people_list(user, wers, L("People that follow you"), "e")),
html_footer()));
return xs_html_render_s(html, "<!DOCTYPE html>\n");
@@ -2220,7 +2304,7 @@ xs_str *html_notifications(snac *user, int skip, int show)
xs_html *body = html_user_body(user, 0);
xs_html *html = xs_html_tag("html",
- html_user_head(user, NULL),
+ html_user_head(user, NULL, NULL),
body);
xs *clear_all_action = xs_fmt("%s/admin/clear-notifications", user->actor);
@@ -2604,7 +2688,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
return 403;
xs *elems = timeline_simple_list(&snac, "public", 0, 20);
- xs *bio = not_really_markdown(xs_dict_get(snac.config, "bio"), NULL);
+ xs *bio = not_really_markdown(xs_dict_get(snac.config, "bio"), NULL, NULL);
xs *rss_title = xs_fmt("%s (@%s@%s)",
xs_dict_get(snac.config, "name"),
@@ -2802,7 +2886,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
msg = msg_note(&snac, content_2, to, in_reply_to, attach_list, priv);
if (sensitive != NULL) {
- msg = xs_dict_set(msg, "sensitive", xs_stock_true);
+ msg = xs_dict_set(msg, "sensitive", xs_stock(XSTYPE_TRUE));
msg = xs_dict_set(msg, "summary", xs_is_null(summary) ? "..." : summary);
}
@@ -2881,6 +2965,22 @@ int html_post_handler(const xs_dict *req, const char *q_path,
}
}
else
+ if (strcmp(action, L("Unlike")) == 0) { /** **/
+ xs *msg = msg_repulsion(&snac, id, "Like");
+
+ if (msg != NULL) {
+ enqueue_message(&snac, msg);
+ }
+ }
+ else
+ if (strcmp(action, L("Unboost")) == 0) { /** **/
+ xs *msg = msg_repulsion(&snac, id, "Announce");
+
+ if (msg != NULL) {
+ enqueue_message(&snac, msg);
+ }
+ }
+ else
if (strcmp(action, L("MUTE")) == 0) { /** **/
mute(&snac, actor);
}
@@ -3036,17 +3136,17 @@ int html_post_handler(const xs_dict *req, const char *q_path,
snac.config = xs_dict_set(snac.config, "purge_days", days);
}
if ((v = xs_dict_get(p_vars, "drop_dm_from_unknown")) != NULL && strcmp(v, "on") == 0)
- snac.config = xs_dict_set(snac.config, "drop_dm_from_unknown", xs_stock_true);
+ snac.config = xs_dict_set(snac.config, "drop_dm_from_unknown", xs_stock(XSTYPE_TRUE));
else
- snac.config = xs_dict_set(snac.config, "drop_dm_from_unknown", xs_stock_false);
+ snac.config = xs_dict_set(snac.config, "drop_dm_from_unknown", xs_stock(XSTYPE_FALSE));
if ((v = xs_dict_get(p_vars, "bot")) != NULL && strcmp(v, "on") == 0)
- snac.config = xs_dict_set(snac.config, "bot", xs_stock_true);
+ snac.config = xs_dict_set(snac.config, "bot", xs_stock(XSTYPE_TRUE));
else
- snac.config = xs_dict_set(snac.config, "bot", xs_stock_false);
+ snac.config = xs_dict_set(snac.config, "bot", xs_stock(XSTYPE_FALSE));
if ((v = xs_dict_get(p_vars, "private")) != NULL && strcmp(v, "on") == 0)
- snac.config = xs_dict_set(snac.config, "private", xs_stock_true);
+ snac.config = xs_dict_set(snac.config, "private", xs_stock(XSTYPE_TRUE));
else
- snac.config = xs_dict_set(snac.config, "private", xs_stock_false);
+ snac.config = xs_dict_set(snac.config, "private", xs_stock(XSTYPE_FALSE));
if ((v = xs_dict_get(p_vars, "metadata")) != NULL) {
/* split the metadata and store it as a dict */
xs_dict *md = xs_dict_new();