From f02c8b967ec936b9dca4ce2dce010301ab8b72bf Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 1 Dec 2019 09:51:14 +0100 Subject: Add image board author name and replies --- fonts/Lato-Bold.ttf | Bin 0 -> 656544 bytes include/Body.hpp | 6 ++++- include/QuickMedia.hpp | 1 + src/Body.cpp | 31 ++++++++++++++++++++++-- src/QuickMedia.cpp | 62 ++++++++++++++++++++++++++--------------------- src/plugins/Fourchan.cpp | 10 +++++++- 6 files changed, 79 insertions(+), 31 deletions(-) create mode 100644 fonts/Lato-Bold.ttf diff --git a/fonts/Lato-Bold.ttf b/fonts/Lato-Bold.ttf new file mode 100644 index 0000000..1d23c70 Binary files /dev/null and b/fonts/Lato-Bold.ttf differ diff --git a/include/Body.hpp b/include/Body.hpp index d10b482..36ced92 100644 --- a/include/Body.hpp +++ b/include/Body.hpp @@ -29,17 +29,19 @@ namespace QuickMedia { std::string title; std::string url; std::string thumbnail_url; + std::string author; bool visible; // Used by image boards for example. The elements are indices to other body items std::vector replies; int num_lines; + std::string post_number; }; using BodyItems = std::vector>; class Body { public: - Body(Program *program, sf::Font &font); + Body(Program *program, sf::Font &font, sf::Font &bold_font); // Select previous item, ignoring invisible items void select_previous_item(); @@ -65,6 +67,8 @@ namespace QuickMedia { sf::Text title_text; sf::Text progress_text; + sf::Text author_text; + sf::Text replies_text; int selected_item; BodyItems items; std::thread thumbnail_load_thread; diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp index f4cb250..abfe270 100644 --- a/include/QuickMedia.hpp +++ b/include/QuickMedia.hpp @@ -48,6 +48,7 @@ namespace QuickMedia { sf::RenderWindow window; sf::Vector2f window_size; sf::Font font; + sf::Font bold_font; Body *body; Plugin *current_plugin; sf::Texture plugin_logo; diff --git a/src/Body.cpp b/src/Body.cpp index 2e653e5..a426afe 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -10,16 +10,20 @@ const sf::Color front_color(43, 45, 47); const sf::Color back_color(33, 35, 37); namespace QuickMedia { - Body::Body(Program *program, sf::Font &font) : + Body::Body(Program *program, sf::Font &font, sf::Font &bold_font) : program(program), title_text("", font, 14), progress_text("", font, 14), + author_text("", bold_font, 14), + replies_text("", font, 14), selected_item(0), draw_thumbnails(false), loading_thumbnail(false) { title_text.setFillColor(sf::Color::White); progress_text.setFillColor(sf::Color::White); + author_text.setFillColor(sf::Color::White); + replies_text.setFillColor(sf::Color(129, 162, 190)); } void Body::select_previous_item() { @@ -129,7 +133,7 @@ namespace QuickMedia { const float font_height = title_text.getCharacterSize() + 4.0f; const float image_max_height = 100.0f; const float spacing_y = 15.0f; - const float padding_y = 2.0f; + const float padding_y = 5.0f; const float start_y = pos.y; sf::RectangleShape image_fallback(sf::Vector2f(50, image_max_height)); @@ -163,6 +167,9 @@ namespace QuickMedia { auto &item = items[first_visible_item]; if(item->visible) { float item_height = font_height * std::max(1, item->num_lines); + if(!item->author.empty()) { + item_height += author_text.getCharacterSize() + 2.0f; + } if(draw_thumbnails && !item->thumbnail_url.empty()) { auto &item_thumbnail = item_thumbnail_textures[first_visible_item]; float image_height = image_max_height; @@ -194,6 +201,9 @@ namespace QuickMedia { continue; float item_height = font_height * std::max(1, item->num_lines); + if(!item->author.empty()) { + item_height += author_text.getCharacterSize() + 2.0f; + } if(draw_thumbnails && !item->thumbnail_url.empty()) { float image_height = image_max_height; if(item_thumbnail.texture && item_thumbnail.texture->getNativeHandle() != 0) { @@ -258,6 +268,23 @@ namespace QuickMedia { } } + if(!item->author.empty()) { + author_text.setString(item->author); + author_text.setPosition(std::floor(item_pos.x + text_offset_x + 10.0f), std::floor(item_pos.y + padding_y)); + window.draw(author_text); + + sf::Vector2f replies_text_pos = author_text.getPosition(); + replies_text_pos.x += author_text.getLocalBounds().width + 5.0f; + for(size_t reply_index : item->replies) { + BodyItem *reply_item = items[reply_index].get(); + replies_text.setString(">>" + reply_item->post_number); + replies_text.setPosition(replies_text_pos); + window.draw(replies_text); + replies_text_pos.x += replies_text.getLocalBounds().width + 5.0f; + } + + item_pos.y += author_text.getCharacterSize() + 2.0f; + } title_text.setString(item->title); title_text.setPosition(std::floor(item_pos.x + text_offset_x + 10.0f), std::floor(item_pos.y + padding_y)); window.draw(title_text); diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 55c983e..01f4529 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -49,10 +49,14 @@ namespace QuickMedia { { window.setVerticalSyncEnabled(true); if(!font.loadFromFile("../../../fonts/Lato-Regular.ttf")) { - fprintf(stderr, "Failed to load font!\n"); + fprintf(stderr, "Failed to load font: Lato-Regular.ttf\n"); abort(); } - body = new Body(this, font); + if(!bold_font.loadFromFile("../../../fonts/Lato-Bold.ttf")) { + fprintf(stderr, "Failed to load font: Lato-Bold.ttf\n"); + abort(); + } + body = new Body(this, font, bold_font); struct sigaction action; action.sa_handler = sigpipe_handler; @@ -349,7 +353,7 @@ namespace QuickMedia { std::string update_search_text; bool search_running = false; - Body history_body(this, font); + Body history_body(this, font, bold_font); const float tab_text_size = 18.0f; const float tab_height = tab_text_size + 10.0f; sf::Text all_tab_text("All", font, tab_text_size); @@ -1444,8 +1448,7 @@ namespace QuickMedia { bool redraw = true; sf::Event event; - std::stack comment_navigation_stack; - comment_navigation_stack.push(body); + std::stack comment_navigation_stack; while (current_page == Page::IMAGE_BOARD_THREAD) { while (window.pollEvent(event)) { @@ -1461,11 +1464,10 @@ namespace QuickMedia { if(event.type == sf::Event::Resized || event.type == sf::Event::GainedFocus) redraw = true; else if(event.type == sf::Event::KeyPressed) { - Body *current_body = comment_navigation_stack.top(); if(event.key.code == sf::Keyboard::Up) { - current_body->select_previous_item(); + body->select_previous_item(); } else if(event.key.code == sf::Keyboard::Down) { - current_body->select_next_item(); + body->select_next_item(); } else if(event.key.code == sf::Keyboard::Escape) { current_page = Page::IMAGE_BOARD_THREAD_LIST; body->clear_items(); @@ -1473,19 +1475,33 @@ namespace QuickMedia { search_bar->clear(); } - BodyItem *selected_item = current_body->get_selected(); - if(event.key.code == sf::Keyboard::Enter && selected_item && (comment_navigation_stack.size() == 1 || current_body->selected_item != 0) && !selected_item->replies.empty()) { - // TODO: Optimize this by making body items shared_ptr instead of unique_ptr - Body *new_body = new Body(this, font); - new_body->draw_thumbnails = true; - new_body->items.push_back(std::make_unique(*selected_item)); + BodyItem *selected_item = body->get_selected(); + if(event.key.code == sf::Keyboard::Enter && selected_item && (comment_navigation_stack.empty() || body->selected_item != comment_navigation_stack.top()) && !selected_item->replies.empty()) { + for(auto &body_item : body->items) { + body_item->visible = false; + } + selected_item->visible = true; for(size_t reply_index : selected_item->replies) { - new_body->items.push_back(std::make_unique(*body->items[reply_index])); + body->items[reply_index]->visible = true; } - comment_navigation_stack.push(new_body); - } else if(event.key.code == sf::Keyboard::BackSpace && comment_navigation_stack.size() > 1) { - delete comment_navigation_stack.top(); + comment_navigation_stack.push(body->selected_item); + } else if(event.key.code == sf::Keyboard::BackSpace && !comment_navigation_stack.empty()) { comment_navigation_stack.pop(); + if(comment_navigation_stack.empty()) { + for(auto &body_item : body->items) { + body_item->visible = true; + } + } else { + for(auto &body_item : body->items) { + body_item->visible = false; + } + body->selected_item = comment_navigation_stack.top(); + selected_item = body->items[body->selected_item].get(); + selected_item->visible = true; + for(size_t reply_index : selected_item->replies) { + body->items[reply_index]->visible = true; + } + } } } } @@ -1511,17 +1527,9 @@ namespace QuickMedia { //search_bar->update(); window.clear(back_color); - comment_navigation_stack.top()->draw(window, body_pos, body_size); + body->draw(window, body_pos, body_size); //search_bar->draw(window); window.display(); } - - // We dont delete the first item since it's a reference to the global body, which we dont want to delete - // as it's also used for other pages. - // TODO: Remove the first item as well when each page has their own body - while(comment_navigation_stack.size() > 1) { - delete comment_navigation_stack.top(); - comment_navigation_stack.pop(); - } } } \ No newline at end of file diff --git a/src/plugins/Fourchan.cpp b/src/plugins/Fourchan.cpp index dd2099b..4df77c4 100644 --- a/src/plugins/Fourchan.cpp +++ b/src/plugins/Fourchan.cpp @@ -575,8 +575,10 @@ namespace QuickMedia { if(!post_num.isNumeric()) continue; - comment_by_postno[post_num.asInt64()] = result_items.size(); + int64_t post_num_int = post_num.asInt64(); + comment_by_postno[post_num_int] = result_items.size(); result_items.push_back(std::make_unique("")); + result_items.back()->post_number = std::to_string(post_num_int); } } @@ -595,6 +597,11 @@ namespace QuickMedia { if(!post_num.isNumeric()) continue; + const Json::Value &author = post["name"]; + std::string author_str = "Anonymous"; + if(author.isString()) + author_str = author.asString(); + std::string comment_text; extract_comment_pieces(comment_begin, comment_end - comment_begin, [&comment_text, &comment_by_postno, &result_items, body_item_index](const CommentPiece &cp) { @@ -630,6 +637,7 @@ namespace QuickMedia { html_unescape_sequences(comment_text); BodyItem *body_item = result_items[body_item_index].get(); body_item->set_title(std::move(comment_text)); + body_item->author = std::move(author_str); const Json::Value &ext = post["ext"]; const Json::Value &tim = post["tim"]; -- cgit v1.2.3