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