aboutsummaryrefslogtreecommitdiff
path: root/src/QuickMedia.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-10-21 21:32:51 +0200
committerdec05eba <dec05eba@protonmail.com>2020-10-21 22:31:36 +0200
commit0d8293a5647c2bb10228658f0910515b38ff0d64 (patch)
treee97c10442c73e330672277940aaf0b38d2fc63eb /src/QuickMedia.cpp
parent87fb6e5c0cce6e6aba8f646329af6f8070d27c63 (diff)
Workaround sfml image loading thread race condition
See: https://github.com/SFML/SFML/issues/1711 Also some other smaller changes
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r--src/QuickMedia.cpp67
1 files changed, 49 insertions, 18 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index f944e7d..48ef01b 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -19,6 +19,7 @@
#include "../include/base64_url.hpp"
#include "../include/Entry.hpp"
#include "../include/NetUtils.hpp"
+#include "../include/SfmlFixes.hpp"
#include <assert.h>
#include <cmath>
@@ -926,7 +927,7 @@ namespace QuickMedia {
}
for(Tab &tab : tabs) {
- tab.body->thumbnail_resize_target_size = tab.page->get_max_thumbnail_size();
+ tab.body->thumbnail_max_size = tab.page->get_thumbnail_max_size();
}
const Json::Value *json_chapters = &Json::Value::nullSingleton();
@@ -1837,7 +1838,7 @@ namespace QuickMedia {
if(get_file_type(image_path) == FileType::REGULAR && upscaled_ok) {
sf::Image image;
- if(image.loadFromFile(image_path.data)) {
+ if(load_image_from_file(image, image_path.data)) {
if(image_texture.loadFromImage(image)) {
image_texture.setSmooth(true);
image_texture.generateMipmap();
@@ -2346,7 +2347,8 @@ namespace QuickMedia {
DownloadResult download_image_result = download_to_string(challenge_info.payload_url, payload_image_data, {}, is_tor_enabled());
if(download_image_result == DownloadResult::OK) {
std::lock_guard<std::mutex> lock(captcha_image_mutex);
- if(captcha_texture.loadFromMemory(payload_image_data.data(), payload_image_data.size())) {
+ sf::Image captcha_image;
+ if(load_image_from_memory(captcha_image, payload_image_data.data(), payload_image_data.size()) && captcha_texture.loadFromImage(captcha_image)) {
captcha_texture.setSmooth(true);
captcha_sprite.setTexture(captcha_texture, true);
challenge_description_text.setString(challenge_info.description);
@@ -2704,7 +2706,8 @@ namespace QuickMedia {
downloading_image = false;
image_data = load_image_future.get();
- if(attached_image_texture->loadFromMemory(image_data.data(), image_data.size())) {
+ sf::Image attached_image;
+ if(load_image_from_memory(attached_image, image_data.data(), image_data.size()) && attached_image_texture->loadFromImage(attached_image)) {
attached_image_texture->setSmooth(true);
//attached_image_texture->generateMipmap();
attached_image_sprite.setTexture(*attached_image_texture, true);
@@ -2943,7 +2946,7 @@ namespace QuickMedia {
messages_tab.type = ChatTabType::MESSAGES;
messages_tab.body = std::make_unique<Body>(this, font.get(), bold_font.get(), cjk_font.get(), loading_icon);
messages_tab.body->draw_thumbnails = true;
- messages_tab.body->thumbnail_resize_target_size = CHAT_MESSAGE_THUMBNAIL_MAX_SIZE;
+ messages_tab.body->thumbnail_max_size = CHAT_MESSAGE_THUMBNAIL_MAX_SIZE;
messages_tab.body->thumbnail_mask_shader = &circle_mask_shader;
//messages_tab.body->line_separator_color = sf::Color::Transparent;
messages_tab.text = sf::Text("Messages", *font, tab_text_size);
@@ -2967,8 +2970,28 @@ namespace QuickMedia {
RoomData *current_room = nullptr;
bool is_window_focused = window.hasFocus();
+ // Returns -1 if no rooms or no unread rooms
+ auto find_top_body_position_for_unread_room = [&tabs](BodyItem *item_to_swap, int start_index) {
+ for(int i = start_index; i < (int)tabs[ROOMS_TAB_INDEX].body->items.size(); ++i) {
+ const auto &body_item = tabs[ROOMS_TAB_INDEX].body->items[i];
+ if(static_cast<RoomData*>(body_item->userdata)->last_message_read || body_item.get() == item_to_swap)
+ return i;
+ }
+ return -1;
+ };
+
+ // Returns -1 if no rooms or all rooms have unread mentions
+ auto find_top_body_position_for_mentioned_room = [&tabs](BodyItem *item_to_swap, int start_index) {
+ for(int i = start_index; i < (int)tabs[ROOMS_TAB_INDEX].body->items.size(); ++i) {
+ const auto &body_item = tabs[ROOMS_TAB_INDEX].body->items[i];
+ if(!static_cast<RoomData*>(body_item->userdata)->has_unread_mention || body_item.get() == item_to_swap)
+ return i;
+ }
+ return -1;
+ };
+
auto process_new_room_messages =
- [this, &selected_tab, &current_room, &is_window_focused, &tabs]
+ [this, &selected_tab, &current_room, &is_window_focused, &tabs, &find_top_body_position_for_unread_room, &find_top_body_position_for_mentioned_room]
(RoomSyncMessages &room_sync_messages, bool is_first_sync) mutable
{
for(auto &[room, messages] : room_sync_messages) {
@@ -2982,7 +3005,6 @@ namespace QuickMedia {
}
}
- bool has_unread_messages = false;
for(auto &[room, messages] : room_sync_messages) {
if(messages.empty())
continue;
@@ -3010,13 +3032,32 @@ namespace QuickMedia {
assert(room_body_item);
if(last_unread_message) {
- has_unread_messages = true;
std::string room_desc = "Unread: " + matrix->message_get_author_displayname(last_unread_message) + ": " + extract_first_line(last_unread_message->body, 150);
if(room->has_unread_mention)
room_desc += "\n** You were mentioned **"; // TODO: Better notification?
room_body_item->set_description(std::move(room_desc));
room_body_item->set_title_color(sf::Color(255, 100, 100));
room->last_message_read = false;
+
+ // Swap order of rooms in body list to put rooms with mentions at the top and then unread messages and then all the other rooms
+ // TODO: Optimize with hash map instead of linear search? or cache the index
+ Body *rooms_body = tabs[ROOMS_TAB_INDEX].body.get();
+ int room_body_index = rooms_body->get_index_by_body_item(room_body_item);
+ if(room_body_index != -1) {
+ std::shared_ptr<BodyItem> body_item = rooms_body->items[room_body_index];
+ int body_swap_index = -1;
+ if(room->has_unread_mention)
+ body_swap_index = find_top_body_position_for_mentioned_room(body_item.get(), 0);
+ else if(!room->last_message_read)
+ body_swap_index = find_top_body_position_for_unread_room(body_item.get(), 0);
+ if(body_swap_index != -1 && body_swap_index != room_body_index) {
+ rooms_body->items.erase(rooms_body->items.begin() + room_body_index);
+ if(body_swap_index < room_body_index)
+ rooms_body->items.insert(rooms_body->items.begin() + body_swap_index, std::move(body_item));
+ else
+ rooms_body->items.insert(rooms_body->items.begin() + (body_swap_index - 1), std::move(body_item));
+ }
+ }
} else if(is_first_sync) {
Message *last_unread_message = nullptr;
for(auto it = messages.rbegin(), end = messages.rend(); it != end; ++it) {
@@ -3029,16 +3070,6 @@ namespace QuickMedia {
room_body_item->set_description(matrix->message_get_author_displayname(last_unread_message) + ": " + extract_first_line(last_unread_message->body, 150));
}
}
-
- if(has_unread_messages) {
- std::sort(tabs[ROOMS_TAB_INDEX].body->items.begin(), tabs[ROOMS_TAB_INDEX].body->items.end(), [](std::shared_ptr<BodyItem> &item1, std::shared_ptr<BodyItem> &item2) {
- RoomData *item1_room = static_cast<RoomData*>(item1->userdata);
- RoomData *item2_room = static_cast<RoomData*>(item2->userdata);
- int item1_presence_sum = (int)!item1_room->last_message_read + (int)item1_room->has_unread_mention;
- int item2_presence_sum = (int)!item2_room->last_message_read + (int)item2_room->has_unread_mention;
- return item1_presence_sum > item2_presence_sum;
- });
- }
};
enum class ChatState {