Create a generic illusts pager

This commit is contained in:
blankie 2023-04-28 16:00:21 +07:00
parent 36a750762b
commit a448dd9b6e
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
3 changed files with 62 additions and 52 deletions

View File

@ -6,9 +6,6 @@
#include "../../pixivclient.h" #include "../../pixivclient.h"
#include "common.h" #include "common.h"
static Element generate_pager(const Illusts& illusts, size_t page, bool first_selector);
static inline Element generate_content(const httplib::Request& req, const Config& config, const Illusts& illusts);
void user_illustrations_route(const httplib::Request& req, httplib::Response& res, const Config& config, PixivClient& pixiv_client) { void user_illustrations_route(const httplib::Request& req, httplib::Response& res, const Config& config, PixivClient& pixiv_client) {
uint64_t user_id = to_ull(req.matches[1].str()); uint64_t user_id = to_ull(req.matches[1].str());
uint64_t page = req.has_param("p") ? to_ull(req.get_param_value("p")) - 1 : 0; uint64_t page = req.has_param("p") ? to_ull(req.get_param_value("p")) - 1 : 0;
@ -35,55 +32,7 @@ void user_illustrations_route(const httplib::Request& req, httplib::Response& re
Element body("body", { Element body("body", {
generate_user_header(std::move(user), config), generate_user_header(std::move(user), config),
generate_pager(illusts, page, true), generate_illusts_pager(req, config, illusts, page, "illusts")
Element("br"),
generate_content(req, config, illusts),
generate_pager(illusts, page, false)
}); });
serve(req, res, config, user.display_name + "'s illustrations", std::move(body)); serve(req, res, config, user.display_name + "'s illustrations", std::move(body));
} }
static Element generate_pager(const Illusts& illusts, size_t page, bool first_selector) {
auto link = [](size_t new_page, const char* text, bool add_link) {
using namespace std::string_literals;
Element b("b");
std::string href = "?p="s + std::to_string(new_page) + "#pageselector";
if (add_link) {
b.nodes.push_back(Element("a", {{"href", std::move(href)}}, {text}));
} else {
b.nodes.push_back(text);
}
return b;
};
Element div("div", {{"class", "center"}}, {
link(1, "First", page != 0), " ",
link(page, "Prev", page != 0), " ",
std::to_string(page + 1), "/", std::to_string(illusts.total_pages), " ",
link(page + 2, "Next", page + 1 < illusts.total_pages), " ",
link(illusts.total_pages, "Last", page + 1 < illusts.total_pages)
});
if (first_selector) {
div.attributes.push_back({"id", "pageselector"});
}
return div;
}
static inline Element generate_content(const httplib::Request& req, const Config& config, const Illusts& illusts) {
Element div("div", {{"class", "grid"}}, {});
div.nodes.reserve(illusts.illusts.size());
for (const Illust& i : illusts.illusts) {
std::string illust_url = get_origin(req, config) + "/artworks/" + std::to_string(i.illust_id);
std::string image_url = proxy_image_url(config, i.images[0].thumbnail_or_original(1));
div.nodes.push_back(Element("a", {{"href", {std::move(illust_url)}}}, {
Element("img", {{"loading", "lazy"}, {"src", std::move(image_url)}}, {}),
Element("p", {i.title})
}));
}
return div;
}

View File

@ -1,8 +1,12 @@
#include <regex> #include <regex>
#include "config.h" #include "config.h"
#include "pixivmodels.h"
#include "servehelper.h" #include "servehelper.h"
static Element generate_pager(const Illusts& illusts, size_t page, const char* id);
static inline Element generate_content(const httplib::Request& req, const Config& config, const Illusts& illusts);
void serve(const httplib::Request& req, httplib::Response& res, const Config& config, std::string title, Element element) { void serve(const httplib::Request& req, httplib::Response& res, const Config& config, std::string title, Element element) {
using namespace std::string_literals; using namespace std::string_literals;
@ -55,6 +59,8 @@ void serve_redirect(const httplib::Request& req, httplib::Response& res, const C
serve(req, res, config, "Redirecting to "s + std::move(url) + "", std::move(body)); serve(req, res, config, "Redirecting to "s + std::move(url) + "", std::move(body));
} }
std::string get_origin(const httplib::Request& req, const Config& config) { std::string get_origin(const httplib::Request& req, const Config& config) {
if (req.has_header("X-Canonical-Origin")) { if (req.has_header("X-Canonical-Origin")) {
return req.get_header_value("X-Canonical-Origin"); return req.get_header_value("X-Canonical-Origin");
@ -91,3 +97,54 @@ std::string proxy_image_url(const Config& config, blankie::murl::Url url) {
} }
return proxy_url(config.image_proxy_url, std::move(url)); return proxy_url(config.image_proxy_url, std::move(url));
} }
Element generate_illusts_pager(const httplib::Request& req, const Config& config, const Illusts& illusts, size_t page, const char* id) {
return Element("div", {{"id", id}}, {
generate_pager(illusts, page, id),
Element("br"),
generate_content(req, config, illusts),
generate_pager(illusts, page, id)
});
}
static Element generate_pager(const Illusts& illusts, size_t page, const char* id) {
auto link = [&](size_t new_page, const char* text, bool add_link) {
using namespace std::string_literals;
Element b("b");
if (add_link) {
std::string href = "?p="s + std::to_string(new_page) + '#' + id;
b.nodes.push_back(Element("a", {{"href", std::move(href)}}, {text}));
} else {
b.nodes.push_back(text);
}
return b;
};
return Element("div", {{"class", "center"}}, {
link(1, "First", page != 0), " ",
link(page, "Prev", page != 0), " ",
std::to_string(page + 1), "/", std::to_string(illusts.total_pages), " ",
link(page + 2, "Next", page + 1 < illusts.total_pages), " ",
link(illusts.total_pages, "Last", page + 1 < illusts.total_pages)
});
}
static inline Element generate_content(const httplib::Request& req, const Config& config, const Illusts& illusts) {
Element div("div", {{"class", "grid"}}, {});
div.nodes.reserve(illusts.illusts.size());
for (const Illust& i : illusts.illusts) {
std::string illust_url = get_origin(req, config) + "/artworks/" + std::to_string(i.illust_id);
std::string image_url = proxy_image_url(config, i.images[0].thumbnail_or_original(1));
div.nodes.push_back(Element("a", {{"href", {std::move(illust_url)}}}, {
Element("img", {{"loading", "lazy"}, {"src", std::move(image_url)}}, {}),
Element("p", {i.title})
}));
}
return div;
}

View File

@ -7,12 +7,16 @@
#include "blankie/serializer.h" #include "blankie/serializer.h"
struct Config; // forward declaration from config.h struct Config; // forward declaration from config.h
struct Illusts; // forward declaration from pixivmodels.h
using Element = blankie::html::Element; using Element = blankie::html::Element;
void serve(const httplib::Request& req, httplib::Response& res, const Config& config, std::string title, Element element); void serve(const httplib::Request& req, httplib::Response& res, const Config& config, std::string title, Element element);
void serve_error(const httplib::Request& req, httplib::Response& res, const Config& config, void serve_error(const httplib::Request& req, httplib::Response& res, const Config& config,
std::string title, std::optional<std::string> subtitle = std::nullopt, std::optional<std::string> info = std::nullopt); std::string title, std::optional<std::string> subtitle = std::nullopt, std::optional<std::string> info = std::nullopt);
void serve_redirect(const httplib::Request& req, httplib::Response& res, const Config& config, std::string url); void serve_redirect(const httplib::Request& req, httplib::Response& res, const Config& config, std::string url);
std::string get_origin(const httplib::Request& req, const Config& config); std::string get_origin(const httplib::Request& req, const Config& config);
std::string proxy_url(blankie::murl::Url base, blankie::murl::Url url); std::string proxy_url(blankie::murl::Url base, blankie::murl::Url url);
std::string proxy_image_url(const Config& config, blankie::murl::Url url); std::string proxy_image_url(const Config& config, blankie::murl::Url url);
Element generate_illusts_pager(const httplib::Request& req, const Config& config, const Illusts& illusts, size_t page, const char* id);