aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-10-21 03:12:35 +0200
committerdec05eba <dec05eba@protonmail.com>2020-10-21 03:12:35 +0200
commitea6f1b425a6aa9b7145a00d81473ef9508279eec (patch)
tree61f3d59aa277b889ed149cf6ccd5fc9dc2b836c8
parentf126659965425ee5f5a3851fbe83ae532e48c478 (diff)
Fix thumbnail fallback size being incorrect, incorrect read marker for matrix
-rw-r--r--TODO4
-rw-r--r--include/Body.hpp1
-rw-r--r--include/Scale.hpp42
-rw-r--r--plugins/Mangadex.hpp1
-rw-r--r--plugins/Manganelo.hpp1
-rw-r--r--plugins/Mangatown.hpp1
-rw-r--r--plugins/Page.hpp2
-rw-r--r--src/Body.cpp43
-rw-r--r--src/QuickMedia.cpp54
-rw-r--r--src/Scale.cpp38
-rw-r--r--src/plugins/Youtube.cpp2
11 files changed, 97 insertions, 92 deletions
diff --git a/TODO b/TODO
index c77dc2c..907ef97 100644
--- a/TODO
+++ b/TODO
@@ -105,4 +105,6 @@ Handle room leave in matrix and remove rooms from the list.
Use a custom allocator that replaces malloc/realloc/free/new/delete to release memory properly, using munmap in free/delete. The C allocator doesn't do that! memory usage remains high after one large allocation. The C allocator only marks it as free.
Ignore timestamp ordering for messages in matrix? element seems to do that (or only for new messages???), and also we need the latest message to be last I guess to set read markers properly?
Merge |Page::search| and |Page::get_page|. get_page with page 0 should be the same as search.
-Disable posting in 4chan thread if closed (thread json contains "closed" field for OP). \ No newline at end of file
+Disable posting in 4chan thread if closed (thread json contains "closed" field for OP).
+Remove calls to get the original message of an edit in edits and replies in matrix if possible. These calls take additional time, and with a slow homeserver or high ping this could make messages to be delayed by an annoying amount of time.
+Read image exif into to apply image rotation. This is common in images taken on phones. If not done, the width and height will also be mixed and thumbnail fallback size will be incorrectly calculated (for example in matrix). \ No newline at end of file
diff --git a/include/Body.hpp b/include/Body.hpp
index ce61811..7bf89e2 100644
--- a/include/Body.hpp
+++ b/include/Body.hpp
@@ -217,6 +217,7 @@ namespace QuickMedia {
void draw_item(sf::RenderWindow &window, BodyItem *item, const sf::Vector2f &pos, const sf::Vector2f &size, const float item_height, const int item_index, const Json::Value &content_progress, bool include_embedded_item = true);
void update_dirty_state(BodyItem *body_item, sf::Vector2f size);
void clear_body_item_cache(BodyItem *body_item);
+ sf::Vector2i get_item_thumbnail_size(BodyItem *item) const;
private:
Program *program;
std::unordered_map<std::string, std::shared_ptr<ThumbnailData>> item_thumbnail_textures;
diff --git a/include/Scale.hpp b/include/Scale.hpp
index 4ab2882..e7e1b27 100644
--- a/include/Scale.hpp
+++ b/include/Scale.hpp
@@ -3,7 +3,43 @@
#include <SFML/System/Vector2.hpp>
namespace QuickMedia {
- sf::Vector2f wrap_to_size(const sf::Vector2f &size, const sf::Vector2f &clamp_size);
- sf::Vector2f clamp_to_size(const sf::Vector2f &size, const sf::Vector2f &clamp_size);
- sf::Vector2f get_ratio(const sf::Vector2f &original_size, const sf::Vector2f &new_size);
+ template<typename T>
+ static T wrap_to_size_x(const T &size, const T &clamp_size) {
+ T new_size;
+ float size_ratio = (float)size.y / (float)size.x;
+ new_size.x = clamp_size.x;
+ new_size.y = new_size.x * size_ratio;
+ return new_size;
+ }
+
+ template<typename T>
+ static T wrap_to_size_y(const T &size, const T &clamp_size) {
+ T new_size;
+ float size_ratio = (float)size.x / (float)size.y;
+ new_size.y = clamp_size.y;
+ new_size.x = new_size.y * size_ratio;
+ return new_size;
+ }
+
+ template<typename T>
+ static T wrap_to_size(const T &size, const T &clamp_size) {
+ T new_size;
+ new_size = wrap_to_size_x(size, clamp_size);
+ if(new_size.y > clamp_size.y)
+ new_size = wrap_to_size_y(size, clamp_size);
+ return new_size;
+ }
+
+ template<typename T>
+ static T clamp_to_size(const T &size, const T &clamp_size) {
+ T new_size = size;
+ if(size.x > clamp_size.x || size.y > clamp_size.y)
+ new_size = wrap_to_size(new_size, clamp_size);
+ return new_size;
+ }
+
+ template<typename T>
+ static sf::Vector2f get_ratio(const T &original_size, const T &new_size) {
+ return sf::Vector2f((float)new_size.x / (float)original_size.x, (float)new_size.y / (float)original_size.y);
+ }
} \ No newline at end of file
diff --git a/plugins/Mangadex.hpp b/plugins/Mangadex.hpp
index ba43498..9990792 100644
--- a/plugins/Mangadex.hpp
+++ b/plugins/Mangadex.hpp
@@ -11,6 +11,7 @@ namespace QuickMedia {
bool search_is_filter() override { return false; }
SearchResult search(const std::string &str, BodyItems &result_items) override;
PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
+ sf::Vector2i get_max_thumbnail_size() override { return sf::Vector2i(101, 141); };
private:
bool get_rememberme_token(std::string &rememberme_token);
std::optional<std::string> rememberme_token;
diff --git a/plugins/Manganelo.hpp b/plugins/Manganelo.hpp
index d79f814..b82476c 100644
--- a/plugins/Manganelo.hpp
+++ b/plugins/Manganelo.hpp
@@ -11,6 +11,7 @@ namespace QuickMedia {
bool search_is_filter() override { return false; }
SearchResult search(const std::string &str, BodyItems &result_items) override;
PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
+ sf::Vector2i get_max_thumbnail_size() override { return sf::Vector2i(101, 141); };
private:
bool extract_id_from_url(const std::string &url, std::string &manga_id) const;
};
diff --git a/plugins/Mangatown.hpp b/plugins/Mangatown.hpp
index 151b4c2..0062d51 100644
--- a/plugins/Mangatown.hpp
+++ b/plugins/Mangatown.hpp
@@ -12,6 +12,7 @@ namespace QuickMedia {
SearchResult search(const std::string &str, BodyItems &result_items) override;
PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
+ sf::Vector2i get_max_thumbnail_size() override { return sf::Vector2i(101, 141); };
private:
bool extract_id_from_url(const std::string &url, std::string &manga_id) const;
};
diff --git a/plugins/Page.hpp b/plugins/Page.hpp
index 2adce85..fb828fb 100644
--- a/plugins/Page.hpp
+++ b/plugins/Page.hpp
@@ -40,6 +40,8 @@ namespace QuickMedia {
std::unique_ptr<SearchBar> create_search_bar(const std::string &placeholder_text, int search_delay);
bool load_manga_content_storage(const char *service_name, const std::string &manga_title, const std::string &manga_id);
+
+ virtual sf::Vector2i get_max_thumbnail_size() { return sf::Vector2i(480, 360); };
Program *program;
};
diff --git a/src/Body.cpp b/src/Body.cpp
index 1d06559..a7d772b 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -59,8 +59,8 @@ namespace QuickMedia {
{
progress_text.setFillColor(sf::Color::White);
replies_text.setFillColor(sf::Color(129, 162, 190));
- thumbnail_resize_target_size.x = 120;
- thumbnail_resize_target_size.y = 120;
+ thumbnail_resize_target_size.x = 250;
+ thumbnail_resize_target_size.y = 141;
item_background.setFillColor(sf::Color(55, 60, 68));
sf::Vector2f loading_icon_size(loading_icon.getTexture()->getSize().x, loading_icon.getTexture()->getSize().y);
loading_icon.setOrigin(loading_icon_size.x * 0.5f, loading_icon_size.y * 0.5f);
@@ -381,8 +381,10 @@ namespace QuickMedia {
if(!item->visible)
continue;
- if(after_pos.y - start_y >= size.y)
+ if(after_pos.y - start_y >= size.y) {
+ last_item_fully_visible = false;
break;
+ }
update_dirty_state(item.get(), size);
float item_height = get_item_height(item.get());
@@ -504,6 +506,19 @@ namespace QuickMedia {
}
}
+ sf::Vector2i Body::get_item_thumbnail_size(BodyItem *item) const {
+ sf::Vector2i content_size;
+ if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0)
+ content_size = clamp_to_size(item->thumbnail_size, thumbnail_resize_target_size);
+ else
+ content_size = thumbnail_resize_target_size;
+ return content_size;
+ }
+
+ static sf::Vector2f to_vec2f(const sf::Vector2i &vec) {
+ return sf::Vector2f(vec.x, vec.y);
+ }
+
void Body::draw_item(sf::RenderWindow &window, BodyItem *item, sf::Vector2f pos, sf::Vector2f size, bool include_embedded_item) {
update_dirty_state(item, size);
item->last_drawn_time = draw_timer.getElapsedTime().asMilliseconds();
@@ -579,9 +594,7 @@ namespace QuickMedia {
image.setTexture(item_thumbnail->texture, true);
auto image_size = image.getTexture()->getSize();
sf::Vector2f image_size_f(image_size.x, image_size.y);
- sf::Vector2f content_size(thumbnail_resize_target_size.x, thumbnail_resize_target_size.y);
- if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0)
- content_size = sf::Vector2f(item->thumbnail_size.x, item->thumbnail_size.y);
+ sf::Vector2f content_size = to_vec2f(get_item_thumbnail_size(item));
auto new_image_size = clamp_to_size(image_size_f, content_size);
auto image_scale = get_ratio(image_size_f, new_image_size);
image.setColor(sf::Color(255, 255, 255, thumbnail_fade_progress * 255));
@@ -595,12 +608,8 @@ namespace QuickMedia {
has_thumbnail_texture = true;
// We want the next image fallback to have the same size as the successful image rendering, because its likely the image fallback will have the same size (for example thumbnails on youtube)
//image_fallback.setSize(sf::Vector2f(width_ratio * image_size.x, height_ratio * image_size.y));
- }
-
- if(!item->thumbnail_url.empty() && !only_show_thumbnail) {
- sf::Vector2f content_size(thumbnail_resize_target_size.x, thumbnail_resize_target_size.y);
- if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0)
- content_size = sf::Vector2f(item->thumbnail_size.x, item->thumbnail_size.y);
+ } else if(!item->thumbnail_url.empty() && !only_show_thumbnail) {
+ sf::Vector2f content_size = to_vec2f(get_item_thumbnail_size(item));
sf::Uint8 fallback_fade_alpha = (1.0 - thumbnail_fade_progress) * 255;
sf::Color fallback_color(52, 58, 70, fallback_fade_alpha);
@@ -733,9 +742,8 @@ namespace QuickMedia {
item_height += item->description_text->getHeight() - 2.0f;
}
if(draw_thumbnails && !item->thumbnail_url.empty()) {
- float image_height = thumbnail_resize_target_size.y;
- if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0)
- image_height = item->thumbnail_size.y;
+ sf::Vector2i content_size = get_item_thumbnail_size(item);
+ float image_height = content_size.y;
std::shared_ptr<ThumbnailData> item_thumbnail;
auto item_thumbnail_it = item_thumbnail_textures.find(item->thumbnail_url);
@@ -772,10 +780,7 @@ namespace QuickMedia {
if(item_thumbnail && item_thumbnail->loading_state == LoadingState::APPLIED_TO_TEXTURE && item_thumbnail->texture.getNativeHandle() != 0) {
auto image_size = item_thumbnail->texture.getSize();
sf::Vector2f image_size_f(image_size.x, image_size.y);
- sf::Vector2f content_size(thumbnail_resize_target_size.x, thumbnail_resize_target_size.y);
- if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0)
- content_size = sf::Vector2f(item->thumbnail_size.x, item->thumbnail_size.y);
- auto new_image_size = clamp_to_size(image_size_f, content_size);
+ auto new_image_size = clamp_to_size(image_size_f, to_vec2f(content_size));
image_height = new_image_size.y;
}
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index cde8cdb..90abfcc 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -284,7 +284,7 @@ namespace QuickMedia {
auto body_item = BodyItem::create(recommended_title_json.asString());
body_item->url = "https://www.youtube.com/watch?v=" + recommended_item_id;
body_item->thumbnail_url = "https://img.youtube.com/vi/" + recommended_item_id + "/hqdefault.jpg";
- body_item->thumbnail_size = sf::Vector2i(158, 119);
+ body_item->thumbnail_size = sf::Vector2i(175, 131);
body_items.push_back(std::move(body_item));
// We dont want more than 150 recommendations
@@ -746,7 +746,7 @@ namespace QuickMedia {
body_item->url = "https://www.youtube.com/watch?v=" + video_id_str;
body_item->thumbnail_url = "https://img.youtube.com/vi/" + video_id_str + "/hqdefault.jpg";
body_item->set_description(timestamp_to_relative_time_str(std::max(0l, time_now - timestamp.asInt64())));
- body_item->thumbnail_size = sf::Vector2i(158, 119);
+ body_item->thumbnail_size = sf::Vector2i(175, 131);
body_items.push_back(std::move(body_item));
}
@@ -925,6 +925,10 @@ namespace QuickMedia {
return;
}
+ for(Tab &tab : tabs) {
+ tab.body->thumbnail_resize_target_size = tab.page->get_max_thumbnail_size();
+ }
+
const Json::Value *json_chapters = &Json::Value::nullSingleton();
if(content_storage_json.isObject()) {
const Json::Value &chapters_json = content_storage_json["chapters"];
@@ -2886,14 +2890,6 @@ namespace QuickMedia {
return str;
}
- static sf::Vector2f to_vec2f(const sf::Vector2i &vec) {
- return sf::Vector2f(vec.x, vec.y);
- }
-
- static sf::Vector2i to_vec2i(const sf::Vector2f &vec) {
- return sf::Vector2i(vec.x, vec.y);
- }
-
static const sf::Vector2i CHAT_MESSAGE_THUMBNAIL_MAX_SIZE(600, 337);
static std::shared_ptr<BodyItem> message_to_body_item(Message *message, UserInfo *me) {
@@ -2906,9 +2902,10 @@ namespace QuickMedia {
body_item->set_timestamp(message->timestamp);
if(!message->thumbnail_url.empty()) {
body_item->thumbnail_url = message->thumbnail_url;
- body_item->thumbnail_size = to_vec2i(clamp_to_size(to_vec2f(message->thumbnail_size), to_vec2f(CHAT_MESSAGE_THUMBNAIL_MAX_SIZE)));
+ body_item->thumbnail_size = message->thumbnail_size;
} else if(!message->url.empty() && message->type == MessageType::IMAGE) {
body_item->thumbnail_url = message->url;
+ body_item->thumbnail_size = message->thumbnail_size;
} else {
body_item->thumbnail_url = message->user->avatar_url;
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
@@ -2970,8 +2967,7 @@ namespace QuickMedia {
RoomData *current_room = nullptr;
bool is_window_focused = window.hasFocus();
- auto process_new_room_messages = [this, &tabs, &current_room, &is_window_focused](RoomSyncMessages &room_sync_messages, bool is_first_sync) mutable {
- size_t room_swap_index = 0;
+ auto process_new_room_messages = [this, &selected_tab, &current_room, &is_window_focused](RoomSyncMessages &room_sync_messages, bool is_first_sync) mutable {
for(auto &[room, messages] : room_sync_messages) {
if(messages.empty())
continue;
@@ -2983,7 +2979,7 @@ namespace QuickMedia {
room->has_unread_mention = true;
//message->mentions_me = false;
// TODO: What if the message or username begins with "-"? also make the notification image be the avatar of the user
- if(!is_window_focused || room != current_room || is_first_sync)
+ if(!is_window_focused || room != current_room || is_first_sync || selected_tab == ROOMS_TAB_INDEX)
show_notification("QuickMedia matrix - " + matrix->message_get_author_displayname(message.get()) + " (" + room->name + ")", message->body);
}
}
@@ -3967,23 +3963,21 @@ namespace QuickMedia {
tabs[MESSAGES_TAB_INDEX].body->draw_item(window, currently_operating_on_item.get(), body_item_pos, body_item_size);
}
- if(tabs[selected_tab].type == ChatTabType::MESSAGES && current_room && current_room->userdata) {
+ if(tabs[selected_tab].type == ChatTabType::MESSAGES && current_room && current_room->userdata && !current_room->last_message_read) {
if(tabs[selected_tab].body->is_last_item_fully_visible()) {
- if(!current_room->last_message_read) {
- BodyItem *current_room_body_item = static_cast<BodyItem*>(current_room->userdata);
- std::string room_desc = current_room_body_item->get_description();
- if(strncmp(room_desc.c_str(), "Unread: ", 8) == 0)
- room_desc = room_desc.substr(8);
- if(room_desc.size() >= 25 && strncmp(room_desc.c_str() + room_desc.size() - 25, "\n** You were mentioned **", 25) == 0)
- room_desc = room_desc.substr(0, room_desc.size() - 25);
- current_room_body_item->set_description(std::move(room_desc));
- // TODO: Show a line like nheko instead for unread messages, or something else
- current_room_body_item->set_title_color(sf::Color::White);
- current_room->last_message_read = true;
- // TODO: Maybe set this instead when the mention is visible on the screen?
- current_room->has_unread_mention = false;
- }
- } else if(!current_room->last_message_read) {
+ BodyItem *current_room_body_item = static_cast<BodyItem*>(current_room->userdata);
+ std::string room_desc = current_room_body_item->get_description();
+ if(strncmp(room_desc.c_str(), "Unread: ", 8) == 0)
+ room_desc = room_desc.substr(8);
+ if(room_desc.size() >= 25 && strncmp(room_desc.c_str() + room_desc.size() - 25, "\n** You were mentioned **", 25) == 0)
+ room_desc = room_desc.substr(0, room_desc.size() - 25);
+ current_room_body_item->set_description(std::move(room_desc));
+ // TODO: Show a line like nheko instead for unread messages, or something else
+ current_room_body_item->set_title_color(sf::Color::White);
+ current_room->last_message_read = true;
+ // TODO: Maybe set this instead when the mention is visible on the screen?
+ current_room->has_unread_mention = false;
+ } else {
window.draw(more_messages_below_rect);
}
}
diff --git a/src/Scale.cpp b/src/Scale.cpp
deleted file mode 100644
index ab7ea2e..0000000
--- a/src/Scale.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "../include/Scale.hpp"
-
-namespace QuickMedia {
- static sf::Vector2f wrap_to_size_x(const sf::Vector2f &size, const sf::Vector2f &clamp_size) {
- sf::Vector2f new_size;
- auto size_ratio = size.y / size.x;
- new_size.x = clamp_size.x;
- new_size.y = new_size.x * size_ratio;
- return new_size;
- }
-
- static sf::Vector2f wrap_to_size_y(const sf::Vector2f &size, const sf::Vector2f &clamp_size) {
- sf::Vector2f new_size;
- auto size_ratio = size.x / size.y;
- new_size.y = clamp_size.y;
- new_size.x = new_size.y * size_ratio;
- return new_size;
- }
-
- sf::Vector2f wrap_to_size(const sf::Vector2f &size, const sf::Vector2f &clamp_size) {
- sf::Vector2f new_size;
- new_size = wrap_to_size_x(size, clamp_size);
- if(new_size.y > clamp_size.y)
- new_size = wrap_to_size_y(size, clamp_size);
- return new_size;
- }
-
- sf::Vector2f clamp_to_size(const sf::Vector2f &size, const sf::Vector2f &clamp_size) {
- sf::Vector2f new_size = size;
- if(size.x > clamp_size.x || size.y > clamp_size.y)
- new_size = wrap_to_size(new_size, clamp_size);
- return new_size;
- }
-
- sf::Vector2f get_ratio(const sf::Vector2f &original_size, const sf::Vector2f &new_size) {
- return sf::Vector2f(new_size.x / original_size.x, new_size.y / original_size.y);
- }
-} \ No newline at end of file
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index 54b020f..12c156a 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -98,7 +98,7 @@ namespace QuickMedia {
body_item->set_description(std::move(desc));
body_item->url = "https://www.youtube.com/watch?v=" + video_id_str;
body_item->thumbnail_url = std::move(thumbnail_url);
- body_item->thumbnail_size = sf::Vector2i(158, 119);
+ body_item->thumbnail_size = sf::Vector2i(175, 131);
added_videos.insert(video_id_str);
return body_item;
}