aboutsummaryrefslogtreecommitdiff
path: root/src/QuickMedia.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r--src/QuickMedia.cpp81
1 files changed, 71 insertions, 10 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index cb58a27..15ae39c 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -3279,6 +3279,16 @@ namespace QuickMedia {
source.a + diff_a * progress);
}
+ static std::string extract_first_line(const std::string &str) {
+ size_t index = str.find('\n');
+ if(index == std::string::npos)
+ return str;
+ else if(index == 0)
+ return "";
+ else
+ return str.substr(0, index - 1);
+ }
+
void Program::chat_page() {
assert(current_plugin->name == "matrix");
Matrix *matrix = static_cast<Matrix*>(current_plugin);
@@ -3320,7 +3330,8 @@ namespace QuickMedia {
*/
// 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) {
+ RoomSyncMessages room_sync_messages;
+ if(matrix->sync(room_sync_messages) != PluginResult::OK) {
show_notification("QuickMedia", "Intial matrix sync failed", Urgency::CRITICAL);
current_page = Page::EXIT;
return;
@@ -3332,6 +3343,24 @@ namespace QuickMedia {
return;
}
+ struct RoomBodyData {
+ std::shared_ptr<BodyItem> body_item;
+ bool last_message_read;
+ };
+
+ std::unordered_map<std::string, RoomBodyData> body_items_by_room_id;
+ for(auto body_item : tabs[ROOMS_TAB_INDEX].body->items) {
+ // TODO: Set |last_message_read| depending on read markers (either remote matrix read markers or locally saved ones)
+ body_items_by_room_id[body_item->url] = { body_item, true };
+ }
+
+ for(auto &[room, messages] : room_sync_messages) {
+ auto room_body_item_it = body_items_by_room_id.find(room->id);
+ if(room_body_item_it != body_items_by_room_id.end() && !messages.empty()) {
+ room_body_item_it->second.body_item->set_description(matrix->message_get_author_displayname(room, messages.back().get()) + ": " + extract_first_line(messages.back()->body));
+ }
+ }
+
// TODO: the initial room to view should be the last viewed room when closing QuickMedia.
// The room id should be saved in a file when changing viewed room.
std::string current_room_id;
@@ -3341,6 +3370,11 @@ namespace QuickMedia {
// TODO: Allow empty initial room (if the user hasn't joined any room yet).
assert(!current_room_id.empty());
+ RoomBodyData *current_room_body_data = nullptr;
+ auto room_body_item_it = body_items_by_room_id.find(current_room_id);
+ if(room_body_item_it != body_items_by_room_id.end())
+ current_room_body_data = &room_body_item_it->second;
+
// get_all_room_messages is not needed here because its done in the loop, where the initial timeout is 0ms
enum class ChatState {
@@ -3423,7 +3457,12 @@ namespace QuickMedia {
return false;
};
- std::future<BodyItems> sync_future;
+ struct SyncFutureResult {
+ BodyItems body_items;
+ RoomSyncMessages room_sync_messages;
+ };
+
+ std::future<SyncFutureResult> sync_future;
bool sync_running = false;
std::string sync_future_room_id;
sf::Clock sync_timer;
@@ -3642,6 +3681,10 @@ namespace QuickMedia {
std::string err_msg = "Failed to get messages in room: " + current_room_id;
show_notification("QuickMedia", err_msg, Urgency::CRITICAL);
}
+
+ auto room_body_item_it = body_items_by_room_id.find(current_room_id);
+ if(room_body_item_it != body_items_by_room_id.end())
+ current_room_body_data = &room_body_item_it->second;
}
}
}
@@ -3757,30 +3800,38 @@ namespace QuickMedia {
sync_future = std::async(std::launch::async, [this, &sync_future_room_id]() {
Matrix *matrix = static_cast<Matrix*>(current_plugin);
- BodyItems result_items;
- if(matrix->sync() == PluginResult::OK) {
+ SyncFutureResult result;
+ if(matrix->sync(result.room_sync_messages) == PluginResult::OK) {
fprintf(stderr, "Synced matrix\n");
- if(matrix->get_new_room_messages(sync_future_room_id, result_items) != PluginResult::OK) {
+ if(matrix->get_new_room_messages(sync_future_room_id, result.body_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_items;
+ return result;
});
}
if(sync_future.valid() && sync_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
- BodyItems new_body_items = sync_future.get();
+ SyncFutureResult sync_result = 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) {
int num_items = tabs[MESSAGES_TAB_INDEX].body->items.size();
bool scroll_to_end = (num_items == 0 || (num_items > 0 && tabs[MESSAGES_TAB_INDEX].body->get_selected_item() == num_items - 1));
- tabs[MESSAGES_TAB_INDEX].body->append_items(std::move(new_body_items));
+ tabs[MESSAGES_TAB_INDEX].body->append_items(std::move(sync_result.body_items));
if(scroll_to_end)
tabs[MESSAGES_TAB_INDEX].body->select_last_item();
}
+ for(auto &[room, messages] : sync_result.room_sync_messages) {
+ auto room_body_item_it = body_items_by_room_id.find(room->id);
+ if(room_body_item_it != body_items_by_room_id.end() && !messages.empty()) {
+ room_body_item_it->second.body_item->set_description("Unread: " + matrix->message_get_author_displayname(room, messages.back().get()) + ": " + extract_first_line(messages.back()->body));
+ room_body_item_it->second.body_item->title_color = sf::Color(255, 100, 100);
+ room_body_item_it->second.last_message_read = false;
+ }
+ }
sync_running = false;
}
@@ -3872,8 +3923,18 @@ 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 && !tabs[selected_tab].body->is_last_item_fully_visible()) {
- window.draw(more_messages_below_rect);
+ if(tabs[selected_tab].type == ChatTabType::MESSAGES) {
+ if(tabs[selected_tab].body->is_last_item_fully_visible()) {
+ if(current_room_body_data && !current_room_body_data->last_message_read) {
+ if(strncmp(current_room_body_data->body_item->get_description().c_str(), "Unread: ", 8) == 0)
+ current_room_body_data->body_item->set_description(current_room_body_data->body_item->get_description().c_str() + 8);
+ // TODO: Show a line like nheko instead for unread messages, or something else
+ current_room_body_data->body_item->title_color = sf::Color::White;
+ current_room_body_data->last_message_read = true;
+ }
+ } else {
+ window.draw(more_messages_below_rect);
+ }
}
if(tabs[selected_tab].type == ChatTabType::MESSAGES) {