From 398eeeca691a14dd883c33fde16de55fe1ed6a4f Mon Sep 17 00:00:00 2001
From: dec05eba <dec05eba@protonmail.com>
Date: Sat, 22 May 2021 13:37:07 +0200
Subject: Fix 4chan and other html plugins for ubuntu, make movement smooth
 with 60fps as well, readd updateGeometry

---
 TODO                     |   2 +-
 depends/html-search      |   2 +-
 include/Body.hpp         |   9 ++-
 src/Body.cpp             | 143 +++++++++--------------------------------------
 src/plugins/Fourchan.cpp |   2 +-
 5 files changed, 36 insertions(+), 122 deletions(-)

diff --git a/TODO b/TODO
index 96646ee..2d03656 100644
--- a/TODO
+++ b/TODO
@@ -130,4 +130,4 @@ Youtube now requires signing in to view age restricted content. For such videos
 Notification race condition when fetching the first notifications page and receiving a notification immediately after the first sync? we might end up with a duplicate notification.
 Submit on notifications item in matrix should jump to the message in the room.
 Notifications should load their replied-to-message.
-Readd updateGeometry in Body.cpp. They were commented out because they caused a crash in Text.cpp
\ No newline at end of file
+Readd copying of Text in Body copy constructor. Find out why we need to make the text dirty on copy.
\ No newline at end of file
diff --git a/depends/html-search b/depends/html-search
index 7edc6c0..fdcdf3e 160000
--- a/depends/html-search
+++ b/depends/html-search
@@ -1 +1 @@
-Subproject commit 7edc6c0d896088cb981ea7bf60d929d62c7bb7e7
+Subproject commit fdcdf3e62230b8bf14d9ee22bb067040d173ea70
diff --git a/include/Body.hpp b/include/Body.hpp
index e74d459..2d18bdd 100644
--- a/include/Body.hpp
+++ b/include/Body.hpp
@@ -280,8 +280,6 @@ namespace QuickMedia {
         int get_previous_visible_item(int start_index);
         // Returns -1 if not found
         int get_next_visible_item(int start_index);
-        float get_offset_to_first_visible_item(sf::Vector2f body_size);
-        float get_offset_to_last_visible_item(sf::Vector2f body_size);
     private:
         enum class DirtyState {
             FALSE,
@@ -289,6 +287,12 @@ namespace QuickMedia {
             FORCE_TRUE
         };
 
+        enum class TargetSetState {
+            NOT_SET,
+            SET,
+            APPLIED
+        };
+
         Program *program;
         int selected_item;
         int prev_selected_item;
@@ -338,6 +342,7 @@ namespace QuickMedia {
         bool render_selected_item_bg = true;
         float item_background_target_pos_y = 0.0f;
         float item_background_target_height = 0.0f;
+        TargetSetState target_y_set = TargetSetState::NOT_SET;
         // TODO: Instead of using this, add functions for modifying |items| and apply the filter on those new items
         DirtyState items_dirty = DirtyState::FALSE;
         std::string current_filter;
diff --git a/src/Body.cpp b/src/Body.cpp
index 3ebd715..6d06061 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -49,27 +49,15 @@ namespace QuickMedia {
         url = other.url;
         thumbnail_url = other.thumbnail_url;
         visible = other.visible;
-        dirty = other.dirty;
-        dirty_description = other.dirty_description;
-        dirty_author = other.dirty_author;
-        dirty_timestamp = other.dirty_timestamp;
+        dirty = !other.title.empty();
+        dirty_description = !other.description.empty();
+        dirty_author = !other.author.empty();
+        dirty_timestamp = other.timestamp != 0;
         thumbnail_is_local = other.thumbnail_is_local;
-        if(other.title_text)
-            title_text = std::make_unique<Text>(*other.title_text);
-        else
-            title_text = nullptr;
-        if(other.description_text)
-            description_text = std::make_unique<Text>(*other.description_text);
-        else
-            description_text = nullptr;
-        if(other.author_text)
-            author_text = std::make_unique<Text>(*other.author_text);
-        else
-            author_text = nullptr;
-        if(other.timestamp_text)
-            timestamp_text = std::make_unique<sf::Text>(*other.timestamp_text);
-        else
-            timestamp_text = nullptr;
+        title_text.reset();
+        description_text.reset();
+        author_text.reset();
+        timestamp_text.reset();
         replies_to = other.replies_to;
         replies = other.replies;
         post_number = other.post_number;
@@ -80,7 +68,7 @@ namespace QuickMedia {
             embedded_item.reset(new BodyItem(""));
             *embedded_item = *other.embedded_item;
         } else {
-            embedded_item = nullptr;
+            embedded_item.reset();
         }
         thumbnail_mask_type = other.thumbnail_mask_type;
         thumbnail_size = other.thumbnail_size;
@@ -494,6 +482,7 @@ namespace QuickMedia {
             items_dirty = DirtyState::FALSE;
         }
 
+        body_pos = pos;
         const float scissor_y = pos.y;
         pos.y = 0.0f;
 
@@ -512,7 +501,6 @@ namespace QuickMedia {
             prev_selected_item = selected_item;
         }
 
-        body_pos = pos;
         bool body_size_changed = std::abs(size.x - body_size.x) > 0.1f || std::abs(size.y - body_size.y) > 0.1f;
         if(body_size_changed) {
             body_size = size;
@@ -811,14 +799,20 @@ namespace QuickMedia {
         window.setView(new_view);
 
         if(prev_num_visible_items > 0) {
+            bool instant_move = false;
+            if(target_y_set == TargetSetState::SET) {
+                target_y_set = TargetSetState::APPLIED;
+                instant_move = true;
+            }
+
             const float item_background_prev_pos_y = item_background.get_position().y;
             const float item_background_pos_diff = item_background_target_pos_y - item_background_prev_pos_y;
-            const float item_background_move_speed = 50.0f;
+            float item_background_move_speed = instant_move ? 1000.0f : 50.0f;
             item_background.set_position(sf::Vector2f(pos.x, item_background_prev_pos_y + (item_background_pos_diff * std::min(1.0f, frame_time * item_background_move_speed))));
 
             const float item_background_prev_height = item_background.get_size().y;
             const float item_background_height_diff = item_background_target_height - item_background_prev_height;
-            const float item_background_height_speed = 50.0f;
+            const float item_background_height_speed = instant_move ? 1000.0f : 50.0f;
             item_background.set_size(sf::Vector2f(size.x, item_background_prev_height + (item_background_height_diff * std::min(1.0f, frame_time * item_background_height_speed))));
 
             if(render_selected_item_bg)
@@ -978,7 +972,7 @@ namespace QuickMedia {
             else
                 body_item->title_text = std::make_unique<Text>(std::move(str), false, std::floor(16 * get_ui_scale()), width, title_mark_urls);
             body_item->title_text->setFillColor(body_item->get_title_color());
-            //body_item->title_text->updateGeometry();
+            body_item->title_text->updateGeometry();
         }
 
         if(body_item->dirty_description) {
@@ -989,7 +983,7 @@ namespace QuickMedia {
             else
                 body_item->description_text = std::make_unique<Text>(std::move(str), false, std::floor(14 * get_ui_scale()), width, true);
             body_item->description_text->setFillColor(body_item->get_description_color());
-            //body_item->description_text->updateGeometry();
+            body_item->description_text->updateGeometry();
         }
 
         if(body_item->dirty_author) {
@@ -1000,7 +994,7 @@ namespace QuickMedia {
             else
                 body_item->author_text = std::make_unique<Text>(std::move(str), true, std::floor(14 * get_ui_scale()), width);
             body_item->author_text->setFillColor(body_item->get_author_color());
-            //body_item->author_text->updateGeometry();
+            body_item->author_text->updateGeometry();
         }
 
         if(body_item->dirty_timestamp) {
@@ -1082,93 +1076,6 @@ namespace QuickMedia {
         return -1;
     }
 
-    // TODO: Remove
-    float Body::get_offset_to_first_visible_item(sf::Vector2f body_size) {
-        float start_pos = page_scroll;
-        float pos = start_pos;
-        for(int i = selected_item - 1; i >= 0;) {
-            auto &item = items[i];
-
-            // TODO: Find a better solution?
-            if(!item->visible) {
-                --i;
-                continue;
-            }
-
-            int prev_body_item_index = get_previous_visible_item(i);
-            const bool merge_with_previous = body_item_merge_handler && body_item_merge_handler(prev_body_item_index == -1 ? nullptr : items[prev_body_item_index].get(), item.get());
-
-            float item_height = get_item_height(item.get(), body_size.x, true, true, merge_with_previous, i);
-            float item_height_with_merge = item_height + spacing_y;
-            pos -= item_height_with_merge;
-
-            if(start_pos - (pos + item_height_with_merge) >= body_size.y) {
-                pos = start_pos - body_pos.y;
-                break;
-                //return body_pos.y;
-            }
-
-            if(merge_with_previous)
-                pos += spacing_y;
-
-            i = prev_body_item_index;
-        }
-
-        //int prev_body_item_index = get_previous_visible_item(selected_item);
-        //const bool merge_with_previous = body_item_merge_handler && body_item_merge_handler(prev_body_item_index == -1 ? nullptr : items[prev_body_item_index].get(), items[selected_item].get());
-//
-        //pos -= selected_item_height;
-        //if(merge_with_previous)
-        //    pos += spacing_y*2.0f;
-//
-        //int next_body_item_index = get_next_visible_item(selected_item);
-        //const bool merge_with_next = next_body_item_index != -1 && body_item_merge_handler && body_item_merge_handler(items[selected_item].get(), items[next_body_item_index].get());
-        //if(!merge_with_previous && merge_with_next)
-        //    pos += spacing_y;
-
-        return start_pos - pos;
-    }
-
-    // TODO: Remove
-    float Body::get_offset_to_last_visible_item(sf::Vector2f body_size) {
-        const int prev_body_item_index = get_previous_visible_item(selected_item);
-        BodyItem *prev_body_item = prev_body_item_index == -1 ? nullptr : items[prev_body_item_index].get();
-
-        float start_pos = page_scroll;
-        float pos = start_pos;
-        const int num_items = (int)items.size();
-        for(int i = selected_item; i < num_items;) {
-            auto &item = items[i];
-
-            // TODO: Find a better solution?
-            if(!item->visible) {
-                ++i;
-                continue;
-            }
-
-            bool merge_with_previous = body_item_merge_handler && body_item_merge_handler(prev_body_item, item.get());
-            if(merge_with_previous)
-                pos -= spacing_y;
-
-            if(pos - start_pos >= body_size.y)
-                return body_size.y;
-
-            float item_height = get_item_height(item.get(), body_size.x, true, true, merge_with_previous, i);
-            pos += item_height + spacing_y;
-            ++num_visible_items;
-            last_visible_item = i;
-
-            int next_body_item_index = get_next_visible_item(i);
-
-            prev_body_item = items[i].get();
-
-            i = next_body_item_index;
-            if(i == -1)
-                break;
-        }
-        return pos - start_pos;
-    }
-
     static sf::Vector2f to_vec2f(const sf::Vector2i &vec) {
         return sf::Vector2f(vec.x, vec.y);
     }
@@ -1211,7 +1118,7 @@ namespace QuickMedia {
         item_pos.y = std::floor(pos.y);
 
         if(body_item_select_callback && mouse_left_clicked && !clicked_body_item) {
-            sf::FloatRect item_box(pos, sf::Vector2f(size.x, item_height));
+            sf::FloatRect item_box(pos + body_pos, sf::Vector2f(size.x, item_height));
             // TODO: Scale mouse_press_pixels_moved_abs with monitor PPI instead of using get_ui_scale()
             if(item_box.contains(mouse_click_pos) && item_box.contains(mouse_release_pos) && mouse_press_pixels_moved_abs <= 50.0 * get_ui_scale()) {
                 clicked_body_item = items[item_index];
@@ -1226,6 +1133,8 @@ namespace QuickMedia {
         if(item_index == selected_item) {
             item_background_target_pos_y = item_pos.y;
             item_background_target_height = item_height;
+            if(target_y_set == TargetSetState::NOT_SET)
+                target_y_set = TargetSetState::SET;
         }
 
         float text_offset_x = padding_x;
@@ -1349,7 +1258,7 @@ namespace QuickMedia {
             for(int i = 0; i < item->reactions.size(); ++i) {
                 auto &reaction = item->reactions[i];
                 reaction.text->setMaxWidth(size.x - text_offset_x - image_padding_x);
-                //reaction.text->updateGeometry();
+                reaction.text->updateGeometry();
                 reaction_max_height = std::max(reaction_max_height, reaction.text->getHeight());
                 reaction.text->setPosition(std::floor(item_pos.x + text_offset_x + reaction_offset_x + reaction_background_padding_x), std::floor(item_pos.y + padding_y - 4.0f + reaction_background_padding_y));
                 reaction_background.set_position(sf::Vector2f(std::floor(item_pos.x + text_offset_x + reaction_offset_x), std::floor(item_pos.y + padding_y)));
@@ -1451,7 +1360,7 @@ namespace QuickMedia {
             for(int i = 0; i < item->reactions.size(); ++i) {
                 auto &reaction = item->reactions[i];
                 reaction.text->setMaxWidth(width - text_offset_x - image_padding_x);
-                //reaction.text->updateGeometry();
+                reaction.text->updateGeometry();
                 reaction_max_height = std::max(reaction_max_height, reaction.text->getHeight());
                 reaction_offset_x += reaction.text->getWidth() + reaction_background_padding_x * 2.0f + reaction_spacing_x;
                 if(text_offset_x + reaction_offset_x + reaction.text->getWidth() + reaction_background_padding_x * 2.0f > width && i < (int)item->reactions.size() - 1) {
diff --git a/src/plugins/Fourchan.cpp b/src/plugins/Fourchan.cpp
index 2b31e70..07b5425 100644
--- a/src/plugins/Fourchan.cpp
+++ b/src/plugins/Fourchan.cpp
@@ -152,7 +152,7 @@ namespace QuickMedia {
     static void extract_comment_pieces(const char *html_source, size_t size, CommentPieceCallback callback) {
         TidyDoc doc = tidyCreate();
         tidyOptSetBool(doc, TidyShowWarnings, no);
-        tidyOptSetBool(doc, TidyUseCustomTags, yes);
+        tidyOptSetInt(doc, TidyUseCustomTags, 1);
         tidyOptSetInt(doc, TidyWrapLen, 0);
         if(tidyParseString(doc, html_source) < 0) {
             CommentPiece comment_piece;
-- 
cgit v1.2.3-70-g09d2