commit c17a225
Merge branch 'master' into style-tweaks-on-2.52
5 files changed,
+89,
-38
M
data.c
+32,
-5
1@@ -1829,6 +1829,19 @@ xs_val *list_maint(snac *user, const char *list, int op)
2 }
3 }
4
5+ break;
6+
7+ case 3: /** get list name **/
8+ if (xs_is_hex(list)) {
9+ FILE *f;
10+ xs *fn = xs_fmt("%s/list/%s.id", user->basedir, list);
11+
12+ if ((f = fopen(fn, "r")) != NULL) {
13+ l = xs_strip_i(xs_readline(f));
14+ fclose(f);
15+ }
16+ }
17+
18 break;
19 }
20
21@@ -1836,6 +1849,23 @@ xs_val *list_maint(snac *user, const char *list, int op)
22 }
23
24
25+xs_list *list_timeline(snac *user, const char *list, int skip, int show)
26+/* returns the timeline of a list */
27+{
28+ xs_list *l = NULL;
29+
30+ if (!xs_is_hex(list))
31+ return NULL;
32+
33+ xs *fn = xs_fmt("%s/list/%s.idx", user->basedir, list);
34+
35+ if (mtime(fn) > 0.0)
36+ l = index_list_desc(fn, skip, show);
37+
38+ return l;
39+}
40+
41+
42 xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op)
43 /* list content management */
44 {
45@@ -1869,11 +1899,8 @@ xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op
46
47 break;
48
49- case 3: /** list timeline **/
50- fn = xs_replace_i(fn, ".lst", ".idx");
51-
52- l = index_list_desc(fn, 0, 2048);
53-
54+ default:
55+ srv_log(xs_fmt("ERROR: list_content: bad op %d", op));
56 break;
57 }
58
M
html.c
+47,
-28
1@@ -509,7 +509,7 @@ xs_html *html_instance_head(void)
2 }
3
4
5-static xs_html *html_instance_body(char *tag)
6+static xs_html *html_instance_body(void)
7 {
8 char *host = xs_dict_get(srv_config, "host");
9 char *sdesc = xs_dict_get(srv_config, "short_description");
10@@ -560,16 +560,6 @@ static xs_html *html_instance_body(char *tag)
11 xs_html_text(handle)))));
12 }
13
14- {
15- xs *l = tag ? xs_fmt(L("Search results for #%s"), tag) :
16- xs_dup(L("Recent posts by users in this instance"));
17-
18- xs_html_add(body,
19- xs_html_tag("h2",
20- xs_html_attr("class", "snac-header"),
21- xs_html_text(l)));
22- }
23-
24 return body;
25 }
26
27@@ -1265,8 +1255,8 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const
28 }
29
30 if (is_msg_public(msg)) {
31- if (strcmp(actor, snac->actor) == 0 || xs_list_in(boosts, snac->md5) == -1) {
32- /* not already boosted or us; add button */
33+ if (xs_list_in(boosts, snac->md5) == -1) {
34+ /* not already boosted; add button */
35 xs_html_add(form,
36 html_button("boost", L("Boost"), L("Announce this post to your followers")));
37 }
38@@ -1996,7 +1986,7 @@ xs_html *html_footer(void)
39
40 xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
41 int skip, int show, int show_more,
42- char *tag, char *page, int utl)
43+ char *title, char *page, int utl)
44 /* returns the HTML for the timeline */
45 {
46 xs_list *p = (xs_list *)list;
47@@ -2026,7 +2016,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
48 }
49 else {
50 head = html_instance_head();
51- body = html_instance_body(tag);
52+ body = html_instance_body();
53 }
54
55 xs_html *html = xs_html_tag("html",
56@@ -2037,6 +2027,13 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
57 xs_html_add(body,
58 html_top_controls(user));
59
60+ if (title) {
61+ xs_html_add(body,
62+ xs_html_tag("h2",
63+ xs_html_attr("class", "snac-header"),
64+ xs_html_text(title)));
65+ }
66+
67 xs_html_add(body,
68 xs_html_tag("a",
69 xs_html_attr("name", "snac-posts")));
70@@ -2126,25 +2123,22 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
71 }
72
73 if (show_more) {
74- xs *t = NULL;
75 xs *m = NULL;
76 xs *ss = xs_fmt("skip=%d&show=%d", skip + show, show);
77
78- xs *url = page == NULL || user == NULL ?
79- xs_dup(srv_baseurl) : xs_fmt("%s%s", user->actor, page);
80+ xs *url = xs_dup(user == NULL ? srv_baseurl : user->actor);
81
82- if (tag) {
83- t = xs_fmt("%s?t=%s", url, tag);
84- m = xs_fmt("%s&%s", t, ss);
85- }
86- else {
87- t = xs_dup(url);
88- m = xs_fmt("%s?%s", t, ss);
89- }
90+ if (page != NULL)
91+ url = xs_str_cat(url, page);
92+
93+ if (xs_str_in(url, "?") != -1)
94+ m = xs_fmt("%s&%s", url, ss);
95+ else
96+ m = xs_fmt("%s?%s", url, ss);
97
98 xs_html *more_links = xs_html_tag("p",
99 xs_html_tag("a",
100- xs_html_attr("href", t),
101+ xs_html_attr("href", url),
102 xs_html_attr("name", "snac-more"),
103 xs_html_text(L("Back to top"))),
104 xs_html_text(" - "),
105@@ -2652,12 +2646,37 @@ int html_get_handler(const xs_dict *req, const char *q_path,
106 xs *next = timeline_instance_list(skip + show, 1);
107
108 *body = html_timeline(&snac, list, 0, skip, show,
109- xs_list_len(next), NULL, "/instance", 0);
110+ xs_list_len(next), L("Showing instance timeline"), "/instance", 0);
111 *b_size = strlen(*body);
112 status = 200;
113 }
114 }
115 else
116+ if (xs_startswith(p_path, "list/")) { /** list timelines **/
117+ if (!login(&snac, req)) {
118+ *body = xs_dup(uid);
119+ status = 401;
120+ }
121+ else {
122+ xs *l = xs_split(p_path, "/");
123+ char *lid = xs_list_get(l, -1);
124+
125+ xs *list = list_timeline(&snac, lid, skip, show);
126+ xs *next = list_timeline(&snac, lid, skip + show, 1);
127+
128+ if (list != NULL) {
129+ xs *base = xs_fmt("/list/%s", lid);
130+ xs *name = list_maint(&snac, lid, 3);
131+ xs *title = xs_fmt(L("Showing timeline for list %s"), name);
132+
133+ *body = html_timeline(&snac, list, 0, skip, show,
134+ xs_list_len(next), title, base, 1);
135+ *b_size = strlen(*body);
136+ status = 200;
137+ }
138+ }
139+ }
140+ else
141 if (xs_startswith(p_path, "p/")) { /** a timeline with just one entry **/
142 if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE)
143 return 403;
M
httpd.c
+7,
-3
1@@ -200,14 +200,18 @@ int server_get_handler(xs_dict *req, const char *q_path,
2 *body = timeline_to_rss(NULL, tl, link, link, link);
3 *ctype = "application/rss+xml; charset=utf-8";
4 }
5- else
6- *body = html_timeline(NULL, tl, 0, skip, show, more, t, NULL, 0);
7+ else {
8+ xs *page = xs_fmt("?t=%s", t);
9+ xs *title = xs_fmt(L("Search results for #%s"), t);
10+ *body = html_timeline(NULL, tl, 0, skip, show, more, title, page, 0);
11+ }
12 }
13 else
14 if (xs_type(xs_dict_get(srv_config, "show_instance_timeline")) == XSTYPE_TRUE) {
15 /** instance timeline **/
16 xs *tl = timeline_instance_list(0, 30);
17- *body = html_timeline(NULL, tl, 0, 0, 0, 0, NULL, NULL, 0);
18+ *body = html_timeline(NULL, tl, 0, 0, 0, 0,
19+ L("Recent posts by users in this instance"), NULL, 0);
20 }
21 else
22 *body = greeting_html();
+1,
-1
1@@ -1669,7 +1669,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
2 xs *l = xs_split(cmd, "/");
3 char *list = xs_list_get(l, -1);
4
5- xs *timeline = list_content(&snac1, list, NULL, 3);
6+ xs *timeline = list_timeline(&snac1, list, 0, 2048);
7 xs *out = xs_list_new();
8 int c = 0;
9 char *md5;
M
snac.h
+2,
-1
1@@ -175,6 +175,7 @@ void tag_index(const char *id, const xs_dict *obj);
2 xs_list *tag_search(char *tag, int skip, int show);
3
4 xs_val *list_maint(snac *user, const char *list, int op);
5+xs_list *list_timeline(snac *user, const char *list, int skip, int show);
6 xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op);
7 void list_distribute(snac *user, const char *who, const xs_dict *post);
8
9@@ -317,7 +318,7 @@ xs_str *encode_html(const char *str);
10
11 xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
12 int skip, int show, int show_more,
13- char *tag, char *page, int utl);
14+ char *title, char *page, int utl);
15
16 int html_get_handler(const xs_dict *req, const char *q_path,
17 char **body, int *b_size, char **ctype, xs_str **etag);