aboutsummaryrefslogtreecommitdiff
path: root/src/QuickMedia.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-09-25 04:15:17 +0200
committerdec05eba <dec05eba@protonmail.com>2020-09-25 04:15:17 +0200
commiteac2ace1c14c1ae0564d757b26a359c6bd4b754a (patch)
tree855b98a19b6a302663a2d26e3ed6ca69110d1ce0 /src/QuickMedia.cpp
parent6cb237cfba67e1a15d475dccfb706bcc179afe71 (diff)
Matrix: fetch previous messages when reaching the top
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r--src/QuickMedia.cpp75
1 files changed, 49 insertions, 26 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index e367ae0..c701c14 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -3188,12 +3188,13 @@ namespace QuickMedia {
std::vector<ChatTab> tabs;
int selected_tab = 0;
- size_t room_message_index = 0;
ChatTab messages_tab;
messages_tab.type = ChatTabType::MESSAGES;
messages_tab.body = std::make_unique<Body>(this, font.get(), bold_font.get(), cjk_font.get());
messages_tab.body->draw_thumbnails = true;
+ messages_tab.body->thumbnail_resize_target_size.x = 600;
+ messages_tab.body->thumbnail_resize_target_size.y = 337;
//messages_tab.body->line_seperator_color = sf::Color::Transparent;
messages_tab.text = sf::Text("Messages", *font, tab_text_size);
tabs.push_back(std::move(messages_tab));
@@ -3216,6 +3217,8 @@ namespace QuickMedia {
fprintf(stderr, "Loaded matrix sync from cache, num items: %zu\n", tabs[MESSAGES_TAB_INDEX].body->items.size());
}
*/
+ // This is needed to get initial data, with joined rooms etc. TODO: Remove this once its cached
+ // and allow asynchronous update of rooms
if(matrix->sync() != PluginResult::OK) {
show_notification("QuickMedia", "Intial matrix sync failed", Urgency::CRITICAL);
current_page = Page::EXIT;
@@ -3234,9 +3237,11 @@ namespace QuickMedia {
if(!tabs[ROOMS_TAB_INDEX].body->items.empty())
current_room_id = tabs[ROOMS_TAB_INDEX].body->items[0]->url;
- // TODO: Allow empty initial room (if the user hasn't joined any room yet)
+ // TODO: Allow empty initial room (if the user hasn't joined any room yet).
assert(!current_room_id.empty());
+ // get_all_room_messages is not needed here because its done in the loop, where the initial timeout is 0ms
+
{
std::string plugin_logo_path = resources_root + "images/matrix_logo.png";
if(!plugin_logo.loadFromFile(plugin_logo_path)) {
@@ -3249,13 +3254,16 @@ namespace QuickMedia {
SearchBar chat_input(*font, &plugin_logo, "Send a message...");
chat_input.set_background_color(sf::Color::Transparent);
+ chat_input.padding_vertical = 10.0f;
+
+ // TODO: Scroll to bottom when receiving new messages, but only if we are already at the bottom?
// TODO: Filer for rooms and settings
chat_input.onTextUpdateCallback = nullptr;
// TODO: Show post message immediately, instead of waiting for sync. Otherwise it can take a while until we receive the message,
// which happens when uploading an image.
- chat_input.onTextSubmitCallback = [this, matrix, &tabs, &selected_tab, &room_message_index, &current_room_id](const std::string &text) -> bool {
+ chat_input.onTextSubmitCallback = [this, matrix, &tabs, &selected_tab, &current_room_id](const std::string &text) -> bool {
if(tabs[selected_tab].type == ChatTabType::MESSAGES) {
if(text.empty())
return false;
@@ -3299,17 +3307,12 @@ namespace QuickMedia {
if(selected_item) {
current_room_id = selected_item->url;
selected_tab = MESSAGES_TAB_INDEX;
- room_message_index = 0;
tabs[MESSAGES_TAB_INDEX].body->clear_items();
- size_t num_new_messages = 0;
BodyItems new_items;
// TODO: Make asynchronous
- if(matrix->get_room_messages(current_room_id, 0, new_items, num_new_messages) == PluginResult::OK) {
- room_message_index += num_new_messages;
+ if(matrix->get_all_synced_room_messages(current_room_id, new_items) == PluginResult::OK) {
tabs[MESSAGES_TAB_INDEX].body->append_items(std::move(new_items));
- if(!tabs[MESSAGES_TAB_INDEX].body->items.empty() && num_new_messages > 0)
- tabs[MESSAGES_TAB_INDEX].body->set_selected_item(tabs[MESSAGES_TAB_INDEX].body->items.size() - 1);
} else {
std::string err_msg = "Failed to get messages in room: " + current_room_id;
show_notification("QuickMedia", err_msg, Urgency::CRITICAL);
@@ -3320,17 +3323,16 @@ namespace QuickMedia {
return false;
};
- struct SyncFutureResult {
- BodyItems body_items;
- size_t num_new_messages;
- };
-
- std::future<SyncFutureResult> sync_future;
+ std::future<BodyItems> sync_future;
bool sync_running = false;
std::string sync_future_room_id;
sf::Clock sync_timer;
sf::Int32 sync_min_time_ms = 0; // Sync immediately the first time
+ std::future<BodyItems> previous_messages_future;
+ bool fetching_previous_messages_running = false;
+ std::string previous_messages_future_room_id;
+
const float tab_spacer_height = 0.0f;
sf::Vector2f body_pos;
sf::Vector2f body_size;
@@ -3350,7 +3352,19 @@ namespace QuickMedia {
redraw = true;
} else if(event.type == sf::Event::KeyPressed) {
if(event.key.code == sf::Keyboard::Up) {
- tabs[selected_tab].body->select_previous_item();
+ bool item_changed = tabs[selected_tab].body->select_previous_item();
+ // Top hit
+ if(!item_changed && !fetching_previous_messages_running) {
+ fetching_previous_messages_running = true;
+ previous_messages_future_room_id = current_room_id;
+ previous_messages_future = std::async(std::launch::async, [this, &previous_messages_future_room_id]() {
+ Matrix *matrix = static_cast<Matrix*>(current_plugin);
+ BodyItems result_items;
+ if(matrix->get_previous_room_messages(previous_messages_future_room_id, result_items) != PluginResult::OK)
+ fprintf(stderr, "Failed to get previous matrix messages in room: %s\n", previous_messages_future_room_id.c_str());
+ return result_items;
+ });
+ }
} else if(event.key.code == sf::Keyboard::Down) {
tabs[selected_tab].body->select_next_item();
} else if(event.key.code == sf::Keyboard::Escape) {
@@ -3420,36 +3434,45 @@ namespace QuickMedia {
sync_running = true;
sync_timer.restart();
sync_future_room_id = current_room_id;
- sync_future = std::async(std::launch::async, [this, &sync_future_room_id, room_message_index]() {
+ sync_future = std::async(std::launch::async, [this, &sync_future_room_id]() {
Matrix *matrix = static_cast<Matrix*>(current_plugin);
- SyncFutureResult result;
- result.num_new_messages = 0;
+ BodyItems result_items;
if(matrix->sync() == PluginResult::OK) {
fprintf(stderr, "Synced matrix\n");
- if(matrix->get_room_messages(sync_future_room_id, room_message_index, result.body_items, result.num_new_messages) != PluginResult::OK) {
+ if(matrix->get_new_room_messages(sync_future_room_id, result_items) != PluginResult::OK) {
fprintf(stderr, "Failed to get new matrix messages in room: %s\n", sync_future_room_id.c_str());
}
} else {
fprintf(stderr, "Failed to sync matrix\n");
}
- return result;
+ return result_items;
});
}
if(sync_future.valid() && sync_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
- SyncFutureResult sync_future_result = sync_future.get();
+ BodyItems new_body_items = sync_future.get();
// Ignore finished sync if it happened in another room. When we navigate back to the room we will get the messages again
if(sync_future_room_id == current_room_id) {
- room_message_index += sync_future_result.num_new_messages;
- tabs[MESSAGES_TAB_INDEX].body->append_items(std::move(sync_future_result.body_items));
- if(!tabs[MESSAGES_TAB_INDEX].body->items.empty() && sync_future_result.num_new_messages > 0)
- tabs[MESSAGES_TAB_INDEX].body->set_selected_item(tabs[MESSAGES_TAB_INDEX].body->items.size() - 1);
+ tabs[MESSAGES_TAB_INDEX].body->append_items(std::move(new_body_items));
}
sync_running = false;
}
+ if(previous_messages_future.valid() && previous_messages_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
+ BodyItems new_body_items = previous_messages_future.get();
+ fprintf(stderr, "Finished fetching older messages, num new messages: %zu\n", new_body_items.size());
+ // Ignore finished fetch of messages if it happened in another room. When we navigate back to the room we will get the messages again
+ if(previous_messages_future_room_id == current_room_id) {
+ size_t num_new_messages = new_body_items.size();
+ int selected_item_index = tabs[MESSAGES_TAB_INDEX].body->get_selected_item();
+ tabs[MESSAGES_TAB_INDEX].body->prepend_items(std::move(new_body_items));
+ tabs[MESSAGES_TAB_INDEX].body->set_selected_item(selected_item_index + num_new_messages);
+ }
+ fetching_previous_messages_running = false;
+ }
+
chat_input.update();
window.clear(back_color);