Hashtag stuff
FossilOrigin-Name: 7c05f6c2b012fa8cc53f82ff3697cbe2a702e198617492494259c55b5f3f8d13
This commit is contained in:
parent
bf48f29ce2
commit
42134409ee
7 changed files with 112 additions and 9 deletions
|
@ -16,9 +16,11 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
|
|
|
@ -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]));
|
||||
|
|
27
src/math.h
Normal file
27
src/math.h
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 */
|
|
@ -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),
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
<span style="font-size: %upx;" class="hashtag-item">#%s</span>
|
||||
<a href="%s/tag/%s" style="font-size: %upx;" class="hashtag-item">#%s</a>
|
||||
|
|
Loading…
Reference in a new issue