Compare commits
	
		
			4 Commits
		
	
	
		
			48dbc8e978
			...
			b0b8e5c3c9
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
								 | 
						b0b8e5c3c9 | |
| 
							
							
								
								 | 
						81c61965c4 | |
| 
							
							
								
								 | 
						727f5dd32b | |
| 
							
							
								
								 | 
						2a6130b16c | 
| 
						 | 
				
			
			@ -15,3 +15,10 @@ This list is not exhaustive, nor does it mean that these are being worked on.
 | 
			
		|||
- No search
 | 
			
		||||
- No ability to login
 | 
			
		||||
- No ability to see comments or like counts
 | 
			
		||||
 | 
			
		||||
# Miscellaneous Information
 | 
			
		||||
 | 
			
		||||
In a page containing a list of illustrations (e.g. a user's illustrations page
 | 
			
		||||
or a search results page), illustrations containing multiple images will have a
 | 
			
		||||
badge indicating the amount of images inside. Illustrations that are marked as
 | 
			
		||||
being AI-generated will have a badge with a red background.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,6 +120,7 @@ void from_json(const nlohmann::json& j, Illust& illust) {
 | 
			
		|||
    } else {
 | 
			
		||||
        illust.images = {get_illust_image(illust_details)};
 | 
			
		||||
    }
 | 
			
		||||
    illust.page_count = to_ull(illust_details.at("page_count").get_ref<const nlohmann::json::string_t&>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void from_json(const nlohmann::json& j, Illusts& illusts) {
 | 
			
		||||
| 
						 | 
				
			
			@ -167,7 +168,8 @@ void from_json(const nlohmann::json& j, SearchResults& search_results) {
 | 
			
		|||
 | 
			
		||||
            .comment = std::nullopt,
 | 
			
		||||
            .tags = std::move(tags),
 | 
			
		||||
            .images = {get_illust_image(i)}
 | 
			
		||||
            .images = {get_illust_image(i)},
 | 
			
		||||
            .page_count = i.at("pageCount").get<size_t>()
 | 
			
		||||
        };
 | 
			
		||||
        search_results.illusts.illusts.push_back(illust);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,7 @@ struct Illust {
 | 
			
		|||
    std::optional<std::string> comment;
 | 
			
		||||
    std::vector<Tag> tags;
 | 
			
		||||
    std::vector<Images> images;
 | 
			
		||||
    size_t page_count;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Illusts {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ static inline Element generate_user_link(const httplib::Request& req, const Conf
 | 
			
		|||
    std::string user_link = get_origin(req, config) + "/users/" + std::to_string(illust.user_id);
 | 
			
		||||
 | 
			
		||||
    return Element("a", {{"class", "usermetadata"}, {"href", std::move(user_link)}}, {
 | 
			
		||||
        Element("img", {{"class", "smallprofilepicture"}, {"loading", "lazy"}, {"src", std::move(profile_picture)}}, {}),
 | 
			
		||||
        Element("img", {{"class", "profilepicture small"}, {"loading", "lazy"}, {"src", std::move(profile_picture)}}, {}),
 | 
			
		||||
        Element("b", {illust.user_display_name})
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ static inline Element generate_user_link(const httplib::Request& req, const Conf
 | 
			
		|||
static inline Element generate_images(const httplib::Request& req, const Config& config, const Illust& illust) {
 | 
			
		||||
    using namespace std::string_literals;
 | 
			
		||||
 | 
			
		||||
    Element div("div", {{"class", "illust"}}, {});
 | 
			
		||||
    Element div("div", {{"class", "illustimages"}}, {});
 | 
			
		||||
    bool show_pages = illust.images.size() > 1;
 | 
			
		||||
 | 
			
		||||
    if (show_pages) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,9 @@ void css_route(const httplib::Request& req, httplib::Response& res) {
 | 
			
		|||
        --background-color: black;
 | 
			
		||||
        --text-color: white;
 | 
			
		||||
 | 
			
		||||
        --illust-badge-background-color: rgba(0, 0, 0, .5);
 | 
			
		||||
        --illust-badge-ai-background-color: rgba(255, 0, 0, .5);
 | 
			
		||||
 | 
			
		||||
        --error-background-color: rgb(100, 0, 0);
 | 
			
		||||
        --error-border-color: red;
 | 
			
		||||
        --error-text-color: white;
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +25,14 @@ void css_route(const httplib::Request& req, httplib::Response& res) {
 | 
			
		|||
        color: var(--text-color);
 | 
			
		||||
        font-family: sans-serif;
 | 
			
		||||
    }
 | 
			
		||||
    img {
 | 
			
		||||
        object-fit: cover;
 | 
			
		||||
        max-width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
    .center {
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        display: block;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    a {
 | 
			
		||||
        color: var(--accent-color);
 | 
			
		||||
| 
						 | 
				
			
			@ -32,67 +43,72 @@ void css_route(const httplib::Request& req, httplib::Response& res) {
 | 
			
		|||
        text-decoration: underline;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    img {
 | 
			
		||||
        object-fit: cover;
 | 
			
		||||
        max-width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .center {
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        display: block;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* USER PAGE (and a tiny bit for illustrations page) */
 | 
			
		||||
    .cover {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 50vh;
 | 
			
		||||
        margin-bottom: 1em;
 | 
			
		||||
    }
 | 
			
		||||
    .profilepicture, .smallprofilepicture {
 | 
			
		||||
        margin-right: .5em;
 | 
			
		||||
    }
 | 
			
		||||
    .profilepicture {
 | 
			
		||||
        width: 5em;
 | 
			
		||||
        height: 5em;
 | 
			
		||||
    }
 | 
			
		||||
    .smallprofilepicture {
 | 
			
		||||
        width: 2.5em;
 | 
			
		||||
        height: 2.5em;
 | 
			
		||||
    }
 | 
			
		||||
    .usermetadata {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        margin-left: .5em;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* USER ILLUSTRATIONS PAGE (and illustrations page) */
 | 
			
		||||
    /* ILLUSTRATIONS GRID and ILLUSTRATION PREVIEW PAGE */
 | 
			
		||||
    .grid {
 | 
			
		||||
        gap: 1em;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-wrap: wrap;
 | 
			
		||||
        gap: 1em;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
    }
 | 
			
		||||
    .grid img {
 | 
			
		||||
        width: 15em;
 | 
			
		||||
        height: 15em;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* ILLUSTRATIONS GRID (used in user illustrations page and search results page) */
 | 
			
		||||
    .grid p {
 | 
			
		||||
        width: 15em;
 | 
			
		||||
    }
 | 
			
		||||
    .illustsgriditem {
 | 
			
		||||
        position: relative;
 | 
			
		||||
    }
 | 
			
		||||
    .illustbadge {
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        top: .25em;
 | 
			
		||||
        right: .25em;
 | 
			
		||||
        padding: .25em;
 | 
			
		||||
        color: var(--text-color);
 | 
			
		||||
        background-color: var(--illust-badge-background-color);
 | 
			
		||||
        text-decoration: none !important;
 | 
			
		||||
    }
 | 
			
		||||
    .illustbadge.ai {
 | 
			
		||||
        background-color: var(--illust-badge-ai-background-color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* ILLUSTRATIONS PAGE */
 | 
			
		||||
    .profilepicture.small {
 | 
			
		||||
        width: 2.5em;
 | 
			
		||||
        height: 2.5em;
 | 
			
		||||
    }
 | 
			
		||||
    .illustimages {
 | 
			
		||||
        display: grid;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
    .illustimages .landmark {
 | 
			
		||||
        padding-top: 1em;
 | 
			
		||||
        padding-bottom: 1em;
 | 
			
		||||
    }
 | 
			
		||||
    .illusttags {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-wrap: wrap;
 | 
			
		||||
        gap: 0 1em;
 | 
			
		||||
    }
 | 
			
		||||
    .illust {
 | 
			
		||||
        display: grid;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
 | 
			
		||||
    /* USER PAGE */
 | 
			
		||||
    .profilecover {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 50vh;
 | 
			
		||||
        margin-bottom: 1em;
 | 
			
		||||
    }
 | 
			
		||||
    .illust .landmark {
 | 
			
		||||
        padding-top: 1em;
 | 
			
		||||
        padding-bottom: 1em;
 | 
			
		||||
    .profilepicture {
 | 
			
		||||
        margin-right: .5em;
 | 
			
		||||
        width: 5em;
 | 
			
		||||
        height: 5em;
 | 
			
		||||
    }
 | 
			
		||||
    .usermetadata {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        margin-left: .5em;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* SEARCH RESULTS PAGE */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,12 @@ void home_route(const httplib::Request& req, httplib::Response& res, const Confi
 | 
			
		|||
            Element("li", {"Can only search for newest and oldest illustrations"}),
 | 
			
		||||
            Element("li", {"No ability to login"}),
 | 
			
		||||
            Element("li", {"No ability to see comments or like counts"}),
 | 
			
		||||
        }),
 | 
			
		||||
        Element("h2", {"Miscellaneous Information"}),
 | 
			
		||||
        Element("p", {
 | 
			
		||||
            "In a page containing a list of illustrations (e.g. a user's illustrations page or a search results page), "
 | 
			
		||||
            "illustrations containing multiple images will have a badge indicating the amount of images inside. "
 | 
			
		||||
            "Illustrations that are marked as being AI-generated will have a badge with a red background."
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
    serve(req, res, config, "Pixwhile", std::move(body));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@ Element generate_user_header(const User& user, const Config& config) {
 | 
			
		|||
        std::string cover_original = proxy_image_url(config, user.cover_images->original_or_thumbnail());
 | 
			
		||||
        std::string cover_thumbnail = proxy_image_url(config, user.cover_images->thumbnail_or_original());
 | 
			
		||||
        header.nodes.push_back(Element("a", {{"href", std::move(cover_original)}}, {
 | 
			
		||||
            Element("img", {{"class", "cover"}, {"loading", "lazy"}, {"src", std::move(cover_thumbnail)}}, {})
 | 
			
		||||
            Element("img", {{"class", "profilecover"}, {"loading", "lazy"}, {"src", std::move(cover_thumbnail)}}, {})
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,9 @@
 | 
			
		|||
#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);
 | 
			
		||||
static inline Element generate_illusts_grid(const httplib::Request& req, const Config& config, const Illusts& illusts);
 | 
			
		||||
static inline Element generate_illusts_grid_item(const httplib::Request& req, const Config& config, const Illust& illust);
 | 
			
		||||
static inline Element generate_illust_badge(const Illust& illust, const std::string& illust_url);
 | 
			
		||||
 | 
			
		||||
void serve(const httplib::Request& req, httplib::Response& res, const Config& config, std::string title, Element element) {
 | 
			
		||||
    using namespace std::string_literals;
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +106,7 @@ Element generate_illusts_pager(const httplib::Request& req, const Config& config
 | 
			
		|||
    return Element("div", {{"id", id}}, {
 | 
			
		||||
        generate_pager(illusts, page, id),
 | 
			
		||||
        Element("br"),
 | 
			
		||||
        generate_content(req, config, illusts),
 | 
			
		||||
        generate_illusts_grid(req, config, illusts),
 | 
			
		||||
        generate_pager(illusts, page, id)
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -132,19 +134,45 @@ static Element generate_pager(const Illusts& illusts, size_t page, const char* i
 | 
			
		|||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline Element generate_content(const httplib::Request& req, const Config& config, const Illusts& illusts) {
 | 
			
		||||
static inline Element generate_illusts_grid(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})
 | 
			
		||||
        }));
 | 
			
		||||
        div.nodes.push_back(generate_illusts_grid_item(req, config, i));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return div;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline Element generate_illusts_grid_item(const httplib::Request& req, const Config& config, const Illust& illust) {
 | 
			
		||||
    std::string illust_url = get_origin(req, config) + "/artworks/" + std::to_string(illust.illust_id);
 | 
			
		||||
    std::string image_url = proxy_image_url(config, illust.images[0].thumbnail_or_original(1));
 | 
			
		||||
 | 
			
		||||
    Element div("div", {{"class", "illustsgriditem"}}, {
 | 
			
		||||
        Element("a", {{"href", illust_url}}, {
 | 
			
		||||
            Element("img", {{"loading", "lazy"}, {"src", std::move(image_url)}}, {}),
 | 
			
		||||
            Element("p", {illust.title})
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (illust.page_count > 1 || illust.ai_generated) {
 | 
			
		||||
        div.nodes.push_back(generate_illust_badge(illust, std::move(illust_url)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return div;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline Element generate_illust_badge(const Illust& illust, const std::string& illust_url) {
 | 
			
		||||
    const char* css_class = !illust.ai_generated ? "illustbadge" : "illustbadge ai";
 | 
			
		||||
 | 
			
		||||
    if (illust.page_count > 1) {
 | 
			
		||||
        return Element("a", {{"class", css_class}, {"href", illust_url + "?preview=1"}}, {
 | 
			
		||||
            std::to_string(illust.page_count), " pages"
 | 
			
		||||
        });
 | 
			
		||||
    } else {
 | 
			
		||||
        return Element("span", {{"class", css_class}}, {
 | 
			
		||||
            "AI"
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue