From 8f6803c25a46fd95e6e65858f4aaa9131e54c6c5 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 3 Oct 2020 17:24:51 +0200 Subject: Matrix: show unread marker from previous session (fetch m.read marker from server) --- src/plugins/Matrix.cpp | 130 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 43 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index 69c2686..ec7064b 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -239,56 +239,41 @@ namespace QuickMedia { } const Json::Value &state_json = (*it)["state"]; - if(!state_json.isObject()) - continue; - - const Json::Value &events_json = state_json["events"]; - events_add_user_info(events_json, room_it->second.get()); - events_set_room_name(events_json, room_it->second.get()); - } - - for(Json::Value::const_iterator it = join_json.begin(); it != join_json.end(); ++it) { - if(!it->isObject()) - continue; - - Json::Value room_id = it.key(); - if(!room_id.isString()) - continue; - - std::string room_id_str = room_id.asString(); - - auto room_it = room_data_by_id.find(room_id_str); - if(room_it == room_data_by_id.end()) { - auto room_data = std::make_unique(); - room_data->id = room_id_str; - room_data_by_id.insert(std::make_pair(room_id_str, std::move(room_data))); - room_it = room_data_by_id.find(room_id_str); // TODO: Get iterator from above insert + if(state_json.isObject()) { + const Json::Value &events_json = state_json["events"]; + events_add_user_info(events_json, room_it->second.get()); + events_set_room_name(events_json, room_it->second.get()); } const Json::Value &timeline_json = (*it)["timeline"]; - if(!timeline_json.isObject()) - continue; + if(timeline_json.isObject()) { + if(room_it->second->prev_batch.empty()) { + // This may be non-existent if this is the first event in the room + const Json::Value &prev_batch_json = timeline_json["prev_batch"]; + if(prev_batch_json.isString()) + room_it->second->prev_batch = prev_batch_json.asString(); + } - if(room_it->second->prev_batch.empty()) { - // This may be non-existent if this is the first event in the room - const Json::Value &prev_batch_json = timeline_json["prev_batch"]; - if(prev_batch_json.isString()) - room_it->second->prev_batch = prev_batch_json.asString(); - } + // TODO: Is there no better way to check for notifications? this is not robust... + bool has_unread_notifications = false; + const Json::Value &unread_notification_json = (*it)["unread_notifications"]; + if(unread_notification_json.isObject()) { + const Json::Value &highlight_count_json = unread_notification_json["highlight_count"]; + if(highlight_count_json.isNumeric() && highlight_count_json.asInt64() > 0) + has_unread_notifications = true; + } - // TODO: Is there no better way to check for notifications? this is not robust... - bool has_unread_notifications = false; - const Json::Value &unread_notification_json = (*it)["unread_notifications"]; - if(unread_notification_json.isObject()) { - const Json::Value &highlight_count_json = unread_notification_json["highlight_count"]; - if(highlight_count_json.isNumeric() && highlight_count_json.asInt64() > 0) - has_unread_notifications = true; + const Json::Value &events_json = timeline_json["events"]; + events_add_user_info(events_json, room_it->second.get()); + events_add_messages(events_json, room_it->second.get(), MessageDirection::AFTER, &room_messages, has_unread_notifications); + events_set_room_name(events_json, room_it->second.get()); } - const Json::Value &events_json = timeline_json["events"]; - events_add_user_info(events_json, room_it->second.get()); - events_add_messages(events_json, room_it->second.get(), MessageDirection::AFTER, &room_messages, has_unread_notifications); - events_set_room_name(events_json, room_it->second.get()); + const Json::Value &ephemeral_json = (*it)["ephemeral"]; + if(ephemeral_json.isObject()) { + const Json::Value &events_json = ephemeral_json["events"]; + events_add_user_read_markers(events_json, room_it->second.get()); + } } return PluginResult::OK; @@ -362,6 +347,56 @@ namespace QuickMedia { } } + void Matrix::events_add_user_read_markers(const Json::Value &events_json, RoomData *room_data) { + if(!events_json.isArray()) + return; + + for(const Json::Value &event_item_json : events_json) { + if(!event_item_json.isObject()) + continue; + + const Json::Value &type_json = event_item_json["type"]; + if(!type_json.isString() || strcmp(type_json.asCString(), "m.receipt") != 0) + continue; + + const Json::Value &content_json = event_item_json["content"]; + if(!content_json.isObject()) + continue; + + for(Json::Value::const_iterator it = content_json.begin(); it != content_json.end(); ++it) { + if(!it->isObject()) + continue; + + Json::Value event_id_json = it.key(); + if(!event_id_json.isString()) + continue; + + const Json::Value &read_json = (*it)["m.read"]; + if(!read_json.isObject()) + continue; + + std::string event_id_str = event_id_json.asString(); + + for(Json::Value::const_iterator user_id_it = read_json.begin(); user_id_it != read_json.end(); ++user_id_it) { + if(!user_id_it->isObject()) + continue; + + Json::Value user_id_json = user_id_it.key(); + if(!user_id_json.isString()) + continue; + + auto user_it = room_data->user_info_by_user_id.find(user_id_json.asString()); + if(user_it == room_data->user_info_by_user_id.end()) { + fprintf(stderr, "Receipt read receipt for unknown user: %s, ignoring...\n", user_id_json.asCString()); + continue; + } + + room_data->user_info[user_it->second].read_marker_event_id = event_id_str; + } + } + } + } + static std::string message_content_extract_thumbnail_url(const Json::Value &content_json, const std::string &homeserver) { const Json::Value &info_json = content_json["info"]; if(info_json.isObject()) { @@ -1725,4 +1760,13 @@ namespace QuickMedia { *upload_size = upload_limit.value(); return PluginResult::OK; } + + const UserInfo* Matrix::get_me(const std::string &room_id) const { + auto room_it = room_data_by_id.find(room_id); + if(room_it == room_data_by_id.end()) { + fprintf(stderr, "Error: no such room: %s\n", room_id.c_str()); + return nullptr; + } + return &room_it->second->user_info[room_it->second->user_info_by_user_id[user_id]]; + } } \ No newline at end of file -- cgit v1.2.3