From 089818f9078c53de7ff9e6596eb7eb82cc8d6727 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 2 Nov 2022 19:29:18 +0100 Subject: Matrix: update room info in ui when receiving updates --- src/plugins/Matrix.cpp | 130 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 9 deletions(-) (limited to 'src/plugins/Matrix.cpp') diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index 7318383..db37a97 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -510,6 +510,25 @@ namespace QuickMedia { chat_page->set_user_info(std::move(user_info)); } + void MatrixQuickMedia::set_room_info(MatrixEventRoomInfo room_info) { + auto it = room_body_item_by_room.find(room_info.room); + if(it == room_body_item_by_room.end()) + return; + + if(room_info.name) { + std::string room_name = room_info.name.value_or(room_info.room->id); + string_replace_all(room_name, '\n', ' '); + it->second->set_title(std::move(room_name)); + //body_item->thumbnail_url = room->get_avatar_url(); + } + + if(room_info.avatar_url) + it->second->thumbnail_url = room_info.avatar_url.value(); + + if(chat_page) + chat_page->set_room_info(std::move(room_info)); + } + void MatrixQuickMedia::for_each_user_in_room(RoomData *room, std::function callback) { auto &users = users_by_room[room]; for(const auto &user : users) { @@ -980,9 +999,17 @@ namespace QuickMedia { } } - void MatrixChatPage::set_current_room(RoomData *room, Body *users_body) { + void MatrixChatPage::set_room_info(MatrixEventRoomInfo room_info) { + if(!current_room || !room_info_update_callback || room_info.room != current_room) + return; + + room_info_update_callback(room_info); + } + + void MatrixChatPage::set_current_room(RoomData *room, Body *users_body, MatrixRoomInfoUpdateCallback room_info_update_callback) { this->current_room = room; this->users_body = users_body; + this->room_info_update_callback = std::move(room_info_update_callback); if(!room || !users_body) return; @@ -2521,6 +2548,53 @@ namespace QuickMedia { message->timestamp = timestamp; message->transaction_id = std::move(transaction_id); return message; + } else if(strcmp(type_json.GetString(), "m.room.name") == 0) { + std::string sender_display_name = extract_first_line_remove_newline_elipses(room_data->get_user_display_name(user_sender), AUTHOR_MAX_LENGTH); + const rapidjson::Value &new_room_name = GetMember(*content_json, "name"); + + auto message = std::make_shared(); + message->type = MessageType::SYSTEM; + message->user = user; + message->event_id = event_id_str; + if(new_room_name.IsString() && new_room_name.GetStringLength() > 0) + message->body = sender_display_name + " changed the room name to \"" + new_room_name.GetString() + "\""; + else + message->body = sender_display_name + " removed the room name"; + message->related_event_id = std::move(related_event_id); + message->related_event_type = related_event_type; + message->timestamp = timestamp; + message->transaction_id = std::move(transaction_id); + return message; + } else if(strcmp(type_json.GetString(), "m.room.topic") == 0) { + std::string sender_display_name = extract_first_line_remove_newline_elipses(room_data->get_user_display_name(user_sender), AUTHOR_MAX_LENGTH); + const rapidjson::Value &new_room_topic = GetMember(*content_json, "topic"); + + auto message = std::make_shared(); + message->type = MessageType::SYSTEM; + message->user = user; + message->event_id = event_id_str; + if(new_room_topic.IsString() && new_room_topic.GetStringLength() > 0) + message->body = sender_display_name + " changed the room topic to \"" + new_room_topic.GetString() + "\""; + else + message->body = sender_display_name + " removed the room topic"; + message->related_event_id = std::move(related_event_id); + message->related_event_type = related_event_type; + message->timestamp = timestamp; + message->transaction_id = std::move(transaction_id); + return message; + } else if(strcmp(type_json.GetString(), "m.room.avatar") == 0) { + std::string sender_display_name = extract_first_line_remove_newline_elipses(room_data->get_user_display_name(user_sender), AUTHOR_MAX_LENGTH); + + auto message = std::make_shared(); + message->type = MessageType::SYSTEM; + message->user = user; + message->event_id = event_id_str; + message->body = sender_display_name + " changed the room avatar"; + message->related_event_id = std::move(related_event_id); + message->related_event_type = related_event_type; + message->timestamp = timestamp; + message->transaction_id = std::move(transaction_id); + return message; } else { auto message = std::make_shared(); message->type = MessageType::UNIMPLEMENTED; @@ -2637,6 +2711,10 @@ namespace QuickMedia { if(!events_json.IsArray()) return; + bool update_room_name = false; + bool update_room_topic = false; + bool update_room_avatar_url = false; + for(const rapidjson::Value &event_item_json : events_json.GetArray()) { if(!event_item_json.IsObject()) continue; @@ -2661,7 +2739,7 @@ namespace QuickMedia { if(!name_json.IsString()) continue; - room_data->set_name(name_json.GetString(), item_timestamp); // TODO: Update room name in gui + update_room_name |= room_data->set_name(name_json.GetString(), item_timestamp); room_data->name_is_fallback = false; } else if(strcmp(type_json.GetString(), "m.room.avatar") == 0) { const rapidjson::Value &content_json = GetMember(event_item_json, "content"); @@ -2672,7 +2750,7 @@ namespace QuickMedia { if(!url_json.IsString() || strncmp(url_json.GetString(), "mxc://", 6) != 0) continue; - room_data->set_avatar_url(get_thumbnail_url(homeserver, thumbnail_url_extract_media_id(url_json.GetString())), item_timestamp); // TODO: Update avatar url in gui + update_room_avatar_url |= room_data->set_avatar_url(get_thumbnail_url(homeserver, thumbnail_url_extract_media_id(url_json.GetString())), item_timestamp); room_data->avatar_is_fallback = false; } else if(strcmp(type_json.GetString(), "m.room.topic") == 0) { const rapidjson::Value &content_json = GetMember(event_item_json, "content"); @@ -2683,21 +2761,32 @@ namespace QuickMedia { if(!topic_json.IsString()) continue; - room_data->set_topic(topic_json.GetString(), item_timestamp); // TODO: Update topic in gui + update_room_topic |= room_data->set_topic(topic_json.GetString(), item_timestamp); } } + + MatrixEventRoomInfo room_info_event; + room_info_event.room = room_data; + room_info_event.name = update_room_name ? std::optional(room_data->get_name()) : std::nullopt; + room_info_event.topic = update_room_topic ? std::optional(room_data->get_topic()) : std::nullopt; + room_info_event.avatar_url = update_room_avatar_url ? std::optional(room_data->get_avatar_url()) : std::nullopt; + if(update_room_name || update_room_topic || update_room_avatar_url) + trigger_event(room_data, MatrixEventType::ROOM_INFO, std::move(room_info_event)); } void Matrix::set_room_info_to_users_if_empty(RoomData *room, const std::string &room_creator_user_id) { - bool has_room_name = room->has_name(); - bool has_room_avatar_url = room->has_avatar_url(); + const bool has_room_name = room->has_name(); + const bool has_room_avatar_url = room->has_avatar_url(); + + bool update_room_name = false; + bool update_room_avatar_url = false; std::vector> users_excluding_me; if(!has_room_name || !has_room_avatar_url || room->name_is_fallback || room->avatar_is_fallback) users_excluding_me = room->get_users_excluding_me(my_user_id); if(!has_room_name) { - room->set_name(combine_user_display_names_for_room_name(users_excluding_me, room_creator_user_id), 0); // TODO: Update in gui + update_room_name |= room->set_name(combine_user_display_names_for_room_name(users_excluding_me, room_creator_user_id), 0); room->name_is_fallback = true; } @@ -2705,13 +2794,20 @@ namespace QuickMedia { if(users_excluding_me.empty()) { auto user = get_user_by_id(room, room_creator_user_id); if(user) - room->set_avatar_url(room->get_user_avatar_url(user), 0); // TODO: Update in gui + update_room_avatar_url |= room->set_avatar_url(room->get_user_avatar_url(user), 0); } else { // TODO: If there are multiple users, then we want to use some other type of avatar, not the first users avatar - room->set_avatar_url(room->get_user_avatar_url(users_excluding_me.front()), 0); // TODO: Update in gui + update_room_avatar_url |= room->set_avatar_url(room->get_user_avatar_url(users_excluding_me.front()), 0); } room->avatar_is_fallback = true; } + + MatrixEventRoomInfo room_info_event; + room_info_event.room = room; + room_info_event.name = update_room_name ? std::optional(room->get_name()) : std::nullopt; + room_info_event.avatar_url = update_room_avatar_url ? std::optional(room->get_avatar_url()) : std::nullopt; + if(update_room_name || update_room_avatar_url) + trigger_event(room, MatrixEventType::ROOM_INFO, std::move(room_info_event)); } void Matrix::events_add_pinned_events(const rapidjson::Value &events_json, RoomData *room_data) { @@ -4902,6 +4998,22 @@ namespace QuickMedia { }); break; } + default: + break; + } + } + + void Matrix::trigger_event(RoomData *room, MatrixEventType type, MatrixEventRoomInfo room_info) { + room_info.room = room; + switch(type) { + case MatrixEventType::ROOM_INFO: { + ui_thread_tasks.push([this, room_info{std::move(room_info)}]{ + delegate->set_room_info(std::move(room_info)); + }); + break; + } + default: + break; } } } \ No newline at end of file -- cgit v1.2.3