Add pinned posts support
This commit is contained in:
parent
aa0c7806cb
commit
e861ab7ba6
16
client.cpp
16
client.cpp
|
@ -102,6 +102,22 @@ std::optional<Post> MastodonClient::get_post(const std::string& host, const std:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Post> MastodonClient::get_pinned_posts(const std::string& host, const std::string& account_id) {
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
std::string resp = this->_send_request("https://"s + host + "/api/v1/accounts/" + account_id + "/statuses?pinned=true");
|
||||||
|
std::vector<Post> posts = nlohmann::json::parse(std::move(resp));
|
||||||
|
|
||||||
|
for (Post& post : posts) {
|
||||||
|
post.account.same_server = host == post.account.server;
|
||||||
|
if (post.reblog) {
|
||||||
|
post.reblog->account.same_server = host == post.reblog->account.server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return posts;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Post> MastodonClient::get_posts(const std::string& host, const std::string& account_id, PostSortingMethod sorting_method, std::optional<std::string> max_id) {
|
std::vector<Post> MastodonClient::get_posts(const std::string& host, const std::string& account_id, PostSortingMethod sorting_method, std::optional<std::string> max_id) {
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
|
1
client.h
1
client.h
|
@ -51,6 +51,7 @@ public:
|
||||||
|
|
||||||
std::optional<Account> get_account_by_username(const std::string& host, const std::string& username);
|
std::optional<Account> get_account_by_username(const std::string& host, const std::string& username);
|
||||||
std::optional<Post> get_post(const std::string& host, const std::string& id);
|
std::optional<Post> get_post(const std::string& host, const std::string& id);
|
||||||
|
std::vector<Post> get_pinned_posts(const std::string& host, const std::string& account_id);
|
||||||
std::vector<Post> get_posts(const std::string& host, const std::string& account_id, PostSortingMethod sorting_method, std::optional<std::string> max_id);
|
std::vector<Post> get_posts(const std::string& host, const std::string& account_id, PostSortingMethod sorting_method, std::optional<std::string> max_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -8,3 +8,4 @@
|
||||||
|
|
||||||
const char fa_retweet[] = R"EOF(<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. --><path d="M272 416c17.7 0 32-14.3 32-32s-14.3-32-32-32H160c-17.7 0-32-14.3-32-32V192h32c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-64-64c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8l32 0 0 128c0 53 43 96 96 96H272zM304 96c-17.7 0-32 14.3-32 32s14.3 32 32 32l112 0c17.7 0 32 14.3 32 32l0 128H416c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8l-32 0V192c0-53-43-96-96-96L304 96z"/></svg>)EOF";
|
const char fa_retweet[] = R"EOF(<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. --><path d="M272 416c17.7 0 32-14.3 32-32s-14.3-32-32-32H160c-17.7 0-32-14.3-32-32V192h32c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-64-64c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8l32 0 0 128c0 53 43 96 96 96H272zM304 96c-17.7 0-32 14.3-32 32s14.3 32 32 32l112 0c17.7 0 32 14.3 32 32l0 128H416c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8l-32 0V192c0-53-43-96-96-96L304 96z"/></svg>)EOF";
|
||||||
const char fa_reply[] = R"EOF(<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. --><path d="M205 34.8c11.5 5.1 19 16.6 19 29.2v64H336c97.2 0 176 78.8 176 176c0 113.3-81.5 163.9-100.2 174.1c-2.5 1.4-5.3 1.9-8.1 1.9c-10.9 0-19.7-8.9-19.7-19.7c0-7.5 4.3-14.4 9.8-19.5c9.4-8.8 22.2-26.4 22.2-56.7c0-53-43-96-96-96H224v64c0 12.6-7.4 24.1-19 29.2s-25 3-34.4-5.4l-160-144C3.9 225.7 0 217.1 0 208s3.9-17.7 10.6-23.8l160-144c9.4-8.5 22.9-10.6 34.4-5.4z"/></svg>)EOF";
|
const char fa_reply[] = R"EOF(<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. --><path d="M205 34.8c11.5 5.1 19 16.6 19 29.2v64H336c97.2 0 176 78.8 176 176c0 113.3-81.5 163.9-100.2 174.1c-2.5 1.4-5.3 1.9-8.1 1.9c-10.9 0-19.7-8.9-19.7-19.7c0-7.5 4.3-14.4 9.8-19.5c9.4-8.8 22.2-26.4 22.2-56.7c0-53-43-96-96-96H224v64c0 12.6-7.4 24.1-19 29.2s-25 3-34.4-5.4l-160-144C3.9 225.7 0 217.1 0 208s3.9-17.7 10.6-23.8l160-144c9.4-8.5 22.9-10.6 34.4-5.4z"/></svg>)EOF";
|
||||||
|
const char fa_thumbtack[] = R"EOF(<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. --><path d="M32 32C32 14.3 46.3 0 64 0H320c17.7 0 32 14.3 32 32s-14.3 32-32 32H290.5l11.4 148.2c36.7 19.9 65.7 53.2 79.5 94.7l1 3c3.3 9.8 1.6 20.5-4.4 28.8s-15.7 13.3-26 13.3H32c-10.3 0-19.9-4.9-26-13.3s-7.7-19.1-4.4-28.8l1-3c13.8-41.5 42.8-74.8 79.5-94.7L93.5 64H64C46.3 64 32 49.7 32 32zM160 384h64v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384z"/></svg>)EOF";
|
||||||
|
|
|
@ -30,11 +30,14 @@ void user_route(const httplib::Request& req, httplib::Response& res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Account> account;
|
std::optional<Account> account;
|
||||||
std::vector<Post> posts;
|
std::vector<Post> pinned_posts, posts;
|
||||||
try {
|
try {
|
||||||
account = mastodon_client.get_account_by_username(server, username);
|
account = mastodon_client.get_account_by_username(server, username);
|
||||||
if (account) {
|
if (account) {
|
||||||
posts = mastodon_client.get_posts(server, account->id, sorting_method, std::move(max_id));
|
if (sorting_method == PostSortingMethod::Posts && !max_id) {
|
||||||
|
pinned_posts = mastodon_client.get_pinned_posts(server, account->id);
|
||||||
|
}
|
||||||
|
posts = mastodon_client.get_posts(server, account->id, sorting_method, max_id);
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
res.status = 500;
|
res.status = 500;
|
||||||
|
@ -51,14 +54,20 @@ void user_route(const httplib::Request& req, httplib::Response& res) {
|
||||||
Element body("body", {
|
Element body("body", {
|
||||||
user_header(req, server, *account, sorting_method),
|
user_header(req, server, *account, sorting_method),
|
||||||
});
|
});
|
||||||
body.nodes.reserve(body.nodes.size() + 2 * posts.size() + 1);
|
body.nodes.reserve(body.nodes.size() + 2 * (pinned_posts.size() + posts.size()) + 1);
|
||||||
|
|
||||||
|
for (const Post& post : pinned_posts) {
|
||||||
|
body.nodes.push_back(serialize_post(req, server, post, true));
|
||||||
|
body.nodes.push_back(Element("hr"));
|
||||||
|
}
|
||||||
for (const Post& post : posts) {
|
for (const Post& post : posts) {
|
||||||
body.nodes.push_back(serialize_post(req, server, post));
|
body.nodes.push_back(serialize_post(req, server, post));
|
||||||
body.nodes.push_back(Element("hr"));
|
body.nodes.push_back(Element("hr"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!posts.empty()) {
|
if (!posts.empty()) {
|
||||||
body.nodes.push_back(Element("a", {{"class", "user_page-more_posts"}, {"href", "?max_id="s + posts[posts.size() - 1].id + "#user_posts_nav"}}, {"See more"}));
|
body.nodes.push_back(Element("a", {{"class", "user_page-more_posts"}, {"href", "?max_id="s + posts[posts.size() - 1].id + "#user_posts_nav"}}, {"See more"}));
|
||||||
} else {
|
} else if (max_id) {
|
||||||
body.nodes.push_back(Element("p", {{"class", "user_page-more_posts"}}, {"There are no more posts"}));
|
body.nodes.push_back(Element("p", {{"class", "user_page-more_posts"}}, {"There are no more posts"}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ bool should_send_304(const httplib::Request& req, uint64_t hash) {
|
||||||
return pos != std::string::npos && (pos == 0 || header[pos - 1] != '/');
|
return pos != std::string::npos && (pos == 0 || header[pos - 1] != '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
Element serialize_post(const httplib::Request& req, const std::string& server, const Post& post) {
|
Element serialize_post(const httplib::Request& req, const std::string& server, const Post& post, bool pinned) {
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
if (post.reblog) {
|
if (post.reblog) {
|
||||||
|
@ -181,6 +181,12 @@ Element serialize_post(const httplib::Request& req, const std::string& server, c
|
||||||
preprocess_html(req, post.account.emojis, post.account.display_name + " boosted"),
|
preprocess_html(req, post.account.emojis, post.account.display_name + " boosted"),
|
||||||
};
|
};
|
||||||
return serialize_post(req, server, *post.reblog, post_status);
|
return serialize_post(req, server, *post.reblog, post_status);
|
||||||
|
} else if (pinned) {
|
||||||
|
PostStatus post_status = {
|
||||||
|
fa_thumbtack,
|
||||||
|
blankie::html::HTMLString("Pinned post"),
|
||||||
|
};
|
||||||
|
return serialize_post(req, server, post, post_status);
|
||||||
} else if (post.in_reply_to_id && post.in_reply_to_account_id && post.account.id == *post.in_reply_to_account_id) {
|
} else if (post.in_reply_to_id && post.in_reply_to_account_id && post.account.id == *post.in_reply_to_account_id) {
|
||||||
PostStatus post_status = {
|
PostStatus post_status = {
|
||||||
fa_reply,
|
fa_reply,
|
||||||
|
|
|
@ -20,7 +20,7 @@ std::string get_origin(const httplib::Request& req);
|
||||||
std::string proxy_mastodon_url(const httplib::Request& req, const std::string& url_str);
|
std::string proxy_mastodon_url(const httplib::Request& req, const std::string& url_str);
|
||||||
bool should_send_304(const httplib::Request& req, uint64_t hash);
|
bool should_send_304(const httplib::Request& req, uint64_t hash);
|
||||||
|
|
||||||
Element serialize_post(const httplib::Request& req, const std::string& server, const Post& post);
|
Element serialize_post(const httplib::Request& req, const std::string& server, const Post& post, bool pinned = false);
|
||||||
|
|
||||||
blankie::html::HTMLString preprocess_html(const httplib::Request& req, const std::string& domain_name, const std::vector<Emoji>& emojis, const blankie::html::HTMLString& str);
|
blankie::html::HTMLString preprocess_html(const httplib::Request& req, const std::string& domain_name, const std::vector<Emoji>& emojis, const blankie::html::HTMLString& str);
|
||||||
blankie::html::HTMLString preprocess_html(const httplib::Request& req, const std::vector<Emoji>& emojis, const std::string& str);
|
blankie::html::HTMLString preprocess_html(const httplib::Request& req, const std::vector<Emoji>& emojis, const std::string& str);
|
||||||
|
|
Loading…
Reference in New Issue