aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--include/Body.hpp1
-rw-r--r--src/Body.cpp33
-rw-r--r--src/QuickMedia.cpp38
4 files changed, 44 insertions, 31 deletions
diff --git a/TODO b/TODO
index a93fc58..869062c 100644
--- a/TODO
+++ b/TODO
@@ -109,4 +109,5 @@ Update displayname/avatar in matrix when updated in /sync.
Fix inconsistent behavior when editing a message that is replied to in matrix. Right now if the replied to message already exits in the body then its used directly and when editing that message the reply message shows the edit embedded, but not if the edit is of an body item that is created because we dont already have it,
to fix this we could perhaps replace the newly created body items for replies when loading old messages and one of the old messages is also one of the embedded messages (by event id).
Add button to skip to next video. MPV has this feature when setting "next" video (can be done over IPC).
-Handle room leave in matrix and remove rooms from the list. \ No newline at end of file
+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. \ No newline at end of file
diff --git a/include/Body.hpp b/include/Body.hpp
index e430bfb..235db88 100644
--- a/include/Body.hpp
+++ b/include/Body.hpp
@@ -117,6 +117,7 @@ namespace QuickMedia {
EmbeddedItemStatus embedded_item_status = EmbeddedItemStatus::NONE;
std::shared_ptr<BodyItem> embedded_item; // Used by matrix for example to display reply message body. Note: only the first level of embedded items is rendered (not recursive, this is done on purpose)
ThumbnailMaskType thumbnail_mask_type = ThumbnailMaskType::NONE;
+ sf::Vector2i thumbnail_size;
private:
// TODO: Clean up these strings when set in text, and get_title for example should return |title_text.getString()|
std::string title;
diff --git a/src/Body.cpp b/src/Body.cpp
index 73f101f..8224087 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -9,7 +9,6 @@
static const sf::Color front_color(32, 36, 42);
static const sf::Color back_color(33, 35, 37);
-static float image_max_height = 100.0f;
static const float spacing_y = 15.0f;
static const float padding_x = 10.0f;
static const float image_padding_x = 5.0f;
@@ -279,10 +278,6 @@ namespace QuickMedia {
const sf::Int32 elapsed_time = draw_timer.getElapsedTime().asMilliseconds();
- if(thumbnail_resize_target_size.x != 0 && thumbnail_resize_target_size.y != 0) {
- image_max_height = thumbnail_resize_target_size.y;
- }
-
//item_background.setFillColor(front_color);
//item_background.setOutlineThickness(1.0f);
//item_background.setOutlineColor(sf::Color(13, 15, 17));
@@ -568,17 +563,19 @@ namespace QuickMedia {
if(item_thumbnail->loading_state == LoadingState::APPLIED_TO_TEXTURE && item_thumbnail->texture.getNativeHandle() != 0) {
image.setTexture(item_thumbnail->texture, true);
auto image_size = image.getTexture()->getSize();
- auto height_ratio = std::min(image_max_height, (float)image_size.y) / image_size.y;
- auto scale = image.getScale();
- auto image_scale_ratio = scale.x / scale.y;
- const float width_ratio = height_ratio * image_scale_ratio;
- image.setScale(width_ratio, height_ratio);
+ 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 image_scale = get_ratio(image_size_f, new_image_size);
+ image.setScale(image_scale);
image.setPosition(item_pos + sf::Vector2f(image_padding_x, padding_y));
if(thumbnail_mask_shader && item->thumbnail_mask_type == ThumbnailMaskType::CIRCLE)
window.draw(image, thumbnail_mask_shader);
else
window.draw(image);
- text_offset_x += image_padding_x + width_ratio * image_size.x;
+ text_offset_x += image_padding_x + new_image_size.x;
// 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));
} else if(!item->thumbnail_url.empty()) {
@@ -594,7 +591,10 @@ namespace QuickMedia {
image_fallback.setPosition(item_pos + sf::Vector2f(image_padding_x, padding_y));
window.draw(image_fallback);
}
- text_offset_x += image_padding_x + image_fallback.getSize().x;
+ float image_width = image_fallback.getSize().x;
+ if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0)
+ image_width = item->thumbnail_size.x;
+ text_offset_x += image_padding_x + image_width;
}
}
@@ -700,6 +700,8 @@ namespace QuickMedia {
}
if(draw_thumbnails && !item->thumbnail_url.empty()) {
float image_height = image_fallback.getSize().y;
+ if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0)
+ image_height = item->thumbnail_size.y;
std::shared_ptr<ThumbnailData> item_thumbnail;
auto item_thumbnail_it = item_thumbnail_textures.find(item->thumbnail_url);
@@ -731,7 +733,12 @@ 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();
- image_height = std::min(image_max_height, (float)image_size.y);
+ 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);
+ image_height = new_image_size.y;
}
item_height = std::max(item_height, image_height);
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index c533186..10224e2 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -2812,7 +2812,10 @@ namespace QuickMedia {
while (current_page == PageType::CHAT_LOGIN) {
while (window.pollEvent(event)) {
- if(event.type == sf::Event::Resized) {
+ if (event.type == sf::Event::Closed) {
+ current_page = PageType::EXIT;
+ window.close();
+ } else if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
@@ -2904,6 +2907,8 @@ namespace QuickMedia {
else {
body_item->thumbnail_url = message->user->avatar_url;
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
+ // if construct is not configured to use ImageMagic then it wont give thumbnails of size 32x32 even when requested and the spec says that the server SHOULD do that
+ body_item->thumbnail_size = sf::Vector2i(32, 32);
}
// TODO: Show image thumbnail inline instead of url to image and showing it as the thumbnail of the body item
body_item->url = message->url;
@@ -3346,8 +3351,17 @@ namespace QuickMedia {
// TODO: What if these never end up referencing events? clean up automatically after a while?
std::unordered_map<std::shared_ptr<RoomData>, Messages> unreferenced_event_by_room;
+ auto set_body_as_deleted = [](Message *message, BodyItem *body_item) {
+ body_item->embedded_item = nullptr;
+ body_item->embedded_item_status = EmbeddedItemStatus::NONE;
+ body_item->thumbnail_url = message->user->avatar_url;
+ body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
+ body_item->set_description_color(sf::Color::White);
+ body_item->thumbnail_size = sf::Vector2i(32, 32);
+ };
+
// TODO: Optimize with hash map?
- auto resolve_unreferenced_events_with_body_items = [&unreferenced_event_by_room, &current_room, &find_body_item_by_event_id](std::shared_ptr<BodyItem> *body_items, size_t num_body_items) {
+ auto resolve_unreferenced_events_with_body_items = [&set_body_as_deleted, &unreferenced_event_by_room, &current_room, &find_body_item_by_event_id](std::shared_ptr<BodyItem> *body_items, size_t num_body_items) {
auto &unreferenced_events = unreferenced_event_by_room[current_room];
for(auto it = unreferenced_events.begin(); it != unreferenced_events.end(); ) {
auto &message = *it;
@@ -3356,13 +3370,8 @@ namespace QuickMedia {
auto body_item = find_body_item_by_event_id(body_items, num_body_items, message->related_event_id);
if(body_item) {
body_item->set_description(message->body);
- if(message->related_event_type == RelatedEventType::REDACTION) {
- body_item->embedded_item = nullptr;
- body_item->embedded_item_status = EmbeddedItemStatus::NONE;
- body_item->thumbnail_url = message->user->avatar_url;
- body_item->thumbnail_mask_type = ThumbnailMaskType::NONE;
- body_item->set_description_color(sf::Color::White);
- }
+ if(message->related_event_type == RelatedEventType::REDACTION)
+ set_body_as_deleted(message.get(), body_item.get());
it = unreferenced_events.erase(it);
} else {
++it;
@@ -3374,7 +3383,7 @@ namespace QuickMedia {
};
// TODO: Optimize with hash map?
- auto modify_related_messages_in_current_room = [&unreferenced_event_by_room, &current_room, &find_body_item_by_event_id, &tabs](Messages &messages) {
+ auto modify_related_messages_in_current_room = [&set_body_as_deleted, &unreferenced_event_by_room, &current_room, &find_body_item_by_event_id, &tabs](Messages &messages) {
auto &unreferenced_events = unreferenced_event_by_room[current_room];
auto &body_items = tabs[MESSAGES_TAB_INDEX].body->items;
for(auto &message : messages) {
@@ -3383,13 +3392,8 @@ namespace QuickMedia {
auto body_item = find_body_item_by_event_id(body_items.data(), body_items.size(), message->related_event_id);
if(body_item) {
body_item->set_description(message->body);
- if(message->related_event_type == RelatedEventType::REDACTION) {
- body_item->embedded_item = nullptr;
- body_item->embedded_item_status = EmbeddedItemStatus::NONE;
- body_item->thumbnail_url = message->user->avatar_url;
- body_item->thumbnail_mask_type = ThumbnailMaskType::NONE;
- body_item->set_description_color(sf::Color::White);
- }
+ if(message->related_event_type == RelatedEventType::REDACTION)
+ set_body_as_deleted(message.get(), body_item.get());
} else {
unreferenced_events.push_back(message);
}