diff --git a/src/hashtag.c b/src/hashtag.c
index f60490d..1882d85 100644
--- a/src/hashtag.c
+++ b/src/hashtag.c
@@ -16,9 +16,11 @@
* along with this program. If not, see .
*/
+#include "math.h"
#include "hashtag.h"
#include "string_helpers.h"
#include "easprintf.h"
+#include "../config.h"
// Pages
#include "../static/hashtag.chtml"
@@ -27,19 +29,26 @@
#define TAG_SIZE_INITIAL 12
+static unsigned hashtag_history_daily_uses(size_t max, struct mstdnt_history* history, size_t history_len)
+{
+ unsigned total = 0;
+
+ for (int i = 0; i < history_len && i < max; ++i)
+ total += history[i].uses;
+
+ return total;
+}
+
char* construct_hashtag(struct mstdnt_tag* hashtag, int* size)
{
char* hashtag_html;
// Lol!
unsigned hash_size = TAG_SIZE_INITIAL +
- ((unsigned)(
- (hashtag->history && hashtag->history_len >= 1 ?
- hashtag->history[0].uses : 0) + 4
- /4)*2);
+ CLAMP(hashtag_history_daily_uses(7, hashtag->history, hashtag->history_len)*2, 0, 42);
size_t s = easprintf(&hashtag_html, data_hashtag_html,
- hash_size, hashtag->name);
+ config_url_prefix, hashtag->name, hash_size, hashtag->name);
if (size) *size = s;
return hashtag_html;
diff --git a/src/main.c b/src/main.c
index 15a84d8..b3864af 100644
--- a/src/main.c
+++ b/src/main.c
@@ -106,6 +106,7 @@ int main(void)
{ "/bookmarks", content_account_bookmarks },
{ "/favourites", content_account_favourites },
{ "/notifications", content_notifications },
+ { "/tag/:", content_tl_tag },
};
handle_paths(&ssn, &api, paths, sizeof(paths)/sizeof(paths[0]));
diff --git a/src/math.h b/src/math.h
new file mode 100644
index 0000000..27f8afa
--- /dev/null
+++ b/src/math.h
@@ -0,0 +1,27 @@
+/*
+ * Treebird - Lightweight frontend for Pleroma
+ * Copyright (C) 2022 Nekobit
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TREEBIRD_MATH_H
+#define TREEBIRD_MATH_H
+
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define CLAMP(v, lower, upper) ((v) > (upper) ? (upper) : \
+ ((v) > (lower) ? (v) : (lower)))
+
+#endif /* TREEBIRD_MATH_H */
diff --git a/src/test.c b/src/test.c
index 98adf7f..07a8310 100644
--- a/src/test.c
+++ b/src/test.c
@@ -30,7 +30,7 @@
enum env_tbl_index
{
- ENV_HTTP_COOKIES = 0,
+ ENV_HTTP_COOKIE = 0,
ENV_PATH_INFO,
ENV_QUERY_STRING,
ENV_REQUEST_METHOD,
@@ -45,7 +45,7 @@ enum env_tbl_index
void content_test(struct session* ssn, mastodont_t* api, char** data)
{
char* env_tbl[] = {
- getenv("HTTP_COOKIES"),
+ getenv("HTTP_COOKIE"),
getenv("PATH_INFO"),
getenv("QUERY_STRING"),
getenv("REQUEST_METHOD"),
@@ -58,7 +58,7 @@ void content_test(struct session* ssn, mastodont_t* api, char** data)
char* page;
easprintf(&page,
data_test_html,
- ENV_TBL_GET(ENV_HTTP_COOKIES),
+ ENV_TBL_GET(ENV_HTTP_COOKIE),
ENV_TBL_GET(ENV_PATH_INFO),
ENV_TBL_GET(ENV_QUERY_STRING),
ENV_TBL_GET(ENV_REQUEST_METHOD),
diff --git a/src/timeline.c b/src/timeline.c
index 937bbb7..e9acb11 100644
--- a/src/timeline.c
+++ b/src/timeline.c
@@ -31,6 +31,7 @@
#include "../static/navigation.chtml"
#include "../static/directs_page.chtml"
+#include "../static/hashtag_page.chtml"
/* TODO Clean these up and make a meta function, i'm just lazy */
@@ -299,6 +300,64 @@ void tl_list(struct session* ssn, mastodont_t* api, char* list_id)
if (navigation_box) free(navigation_box);
}
+
+void tl_tag(struct session* ssn, mastodont_t* api, char* tag_id)
+{
+ size_t status_count, statuses_html_count;
+ struct mstdnt_status* statuses = NULL;
+ struct mstdnt_storage storage = { 0 };
+ char* status_format, *navigation_box = NULL, *start_id;
+ char* output = NULL;
+
+ struct mstdnt_timeline_args args = {
+ .max_id = ssn->post.max_id,
+ .since_id = NULL,
+ .min_id = ssn->post.min_id,
+ .limit = 20,
+ };
+
+ if (mastodont_timeline_tag(api, tag_id, &args, &storage, &statuses, &status_count))
+ status_format = construct_error(storage.error, E_ERROR, 1, NULL);
+ else {
+ // Construct statuses into HTML
+ status_format = construct_statuses(api, statuses, status_count, NULL, &statuses_html_count);
+ if (!status_format)
+ status_format = construct_error("No statuses", E_ERROR, 1, NULL);
+ }
+
+ // Create post box
+ if (statuses)
+ {
+ // If not set, set it
+ start_id = ssn->post.start_id ? ssn->post.start_id : statuses[0].id;
+ navigation_box = construct_navigation_box(start_id,
+ statuses[0].id,
+ statuses[status_count-1].id,
+ NULL);
+ }
+ easprintf(&output, data_hashtag_page_html,
+ tag_id,
+ STR_NULL_EMPTY(status_format),
+ STR_NULL_EMPTY(navigation_box));
+
+ struct base_page b = {
+ .category = BASE_CAT_NONE,
+ .locale = L10N_EN_US,
+ .content = output,
+ .sidebar_left = NULL
+ };
+
+ // Output
+ render_base_page(&b, ssn, api);
+
+ // Cleanup
+ mastodont_storage_cleanup(&storage);
+ mstdnt_cleanup_statuses(statuses, status_count);
+ free(status_format);
+ if (output) free(output);
+ if (navigation_box) free(navigation_box);
+}
+
void content_tl_home(struct session* ssn, mastodont_t* api, char** data)
{
(void)data;
@@ -330,3 +389,8 @@ void content_tl_list(struct session* ssn, mastodont_t* api, char** data)
{
tl_list(ssn, api, data[0]);
}
+
+void content_tl_tag(struct session* ssn, mastodont_t* api, char** data)
+{
+ tl_tag(ssn, api, data[0]);
+}
diff --git a/src/timeline.h b/src/timeline.h
index f3af763..b040397 100644
--- a/src/timeline.h
+++ b/src/timeline.h
@@ -28,11 +28,13 @@ void tl_home(struct session* ssn, mastodont_t* api, int local);
void tl_direct(struct session* ssn, mastodont_t* api);
void tl_public(struct session* ssn, mastodont_t* api, int local, enum base_category cat);
void tl_list(struct session* ssn, mastodont_t* api, char* list_id);
+void tl_tag(struct session* ssn, mastodont_t* api, char* tag);
void content_tl_federated(struct session* ssn, mastodont_t* api, char** data);
void content_tl_home(struct session* ssn, mastodont_t* api, char** data);
void content_tl_direct(struct session* ssn, mastodont_t* api, char** data);
void content_tl_local(struct session* ssn, mastodont_t* api, char** data);
void content_tl_list(struct session* ssn, mastodont_t* api, char** data);
+void content_tl_tag(struct session* ssn, mastodont_t* api, char** data);
#endif // TIMELINE_H
diff --git a/static/hashtag.html b/static/hashtag.html
index c061630..6c29b92 100644
--- a/static/hashtag.html
+++ b/static/hashtag.html
@@ -1 +1 @@
-#%s
+#%s