feat: heroes, don't send notifications every time

next
timokoesters 2020-06-04 18:27:57 +02:00
parent b7f7a39973
commit 32da76b9a2
No known key found for this signature in database
GPG Key ID: 24DA7517711A2BA4
1 changed files with 91 additions and 18 deletions

View File

@ -24,8 +24,8 @@ use ruma_client_api::{
keys::{self, claim_keys, get_keys, upload_keys}, keys::{self, claim_keys, get_keys, upload_keys},
media::{create_content, get_content, get_content_thumbnail, get_media_config}, media::{create_content, get_content, get_content_thumbnail, get_media_config},
membership::{ membership::{
forget_room, get_member_events, invite_user, join_room_by_id, join_room_by_id_or_alias, ban_user, forget_room, get_member_events, invite_user, join_room_by_id,
kick_user, leave_room, ban_user, unban_user, join_room_by_id_or_alias, kick_user, leave_room, unban_user,
}, },
message::{create_message_event, get_message_events}, message::{create_message_event, get_message_events},
presence::set_presence, presence::set_presence,
@ -2151,7 +2151,9 @@ pub fn sync_route(
let mut send_member_count = false; let mut send_member_count = false;
let mut send_full_state = false; let mut send_full_state = false;
let mut send_notification_counts = false;
for pdu in &pdus { for pdu in &pdus {
send_notification_counts = true;
if pdu.kind == EventType::RoomMember { if pdu.kind == EventType::RoomMember {
send_member_count = true; send_member_count = true;
if !send_full_state && pdu.state_key == Some(user_id.to_string()) { if !send_full_state && pdu.state_key == Some(user_id.to_string()) {
@ -2171,7 +2173,85 @@ pub fn sync_route(
} }
} }
let notification_count = let state = db.rooms.room_state(&room_id).unwrap();
let (joined_member_count, invited_member_count, heroes) = if send_member_count {
let joined_member_count = db.rooms.room_members(&room_id).count();
let invited_member_count = db.rooms.room_members_invited(&room_id).count();
// Recalculate heroes (first 5 members)
let mut heroes = Vec::new();
if joined_member_count + invited_member_count <= 5 {
// Go through all PDUs and for each member event, check if the user is still joined or
// invited until we have 5 or we reach the end
for hero in db
.rooms
.all_pdus(&room_id)
.unwrap()
.filter_map(|pdu| pdu.ok()) // Ignore all broken pdus
.filter(|pdu| pdu.kind == EventType::RoomMember)
.filter_map(|pdu| {
let content = serde_json::from_value::<
EventJson<ruma_events::room::member::MemberEventContent>,
>(pdu.content.clone())
.unwrap()
.deserialize()
.unwrap();
let current_content = serde_json::from_value::<
EventJson<ruma_events::room::member::MemberEventContent>,
>(
state
.get(&(
EventType::RoomMember,
pdu.state_key.clone().expect(
"TODO: error handling. Is it really a state event?",
),
))
.expect("a user that joined once will always have a member event")
.content
.clone(),
)
.unwrap()
.deserialize()
.unwrap();
// The membership was and still is invite or join
if matches!(
content.membership,
ruma_events::room::member::MembershipState::Join
| ruma_events::room::member::MembershipState::Invite
) && matches!(
current_content.membership,
ruma_events::room::member::MembershipState::Join
| ruma_events::room::member::MembershipState::Invite
) {
Some(pdu.state_key.unwrap())
} else {
None
}
})
{
if heroes.contains(&hero) || hero == user_id.to_string() {
continue;
}
heroes.push(hero);
}
}
(
Some(joined_member_count),
Some(invited_member_count),
heroes,
)
} else {
(None, None, Vec::new())
};
let notification_count = if send_notification_counts {
if let Some(last_read) = db.rooms.edus.room_read_get(&room_id, &user_id).unwrap() { if let Some(last_read) = db.rooms.edus.room_read_get(&room_id, &user_id).unwrap() {
Some( Some(
(db.rooms (db.rooms
@ -2188,7 +2268,10 @@ pub fn sync_route(
) )
} else { } else {
None None
}; }
} else {
None
};
// They /sync response doesn't always return all messages, so we say the output is // They /sync response doesn't always return all messages, so we say the output is
// limited unless there are enough events // limited unless there are enough events
@ -2247,17 +2330,9 @@ pub fn sync_route(
.collect(), .collect(),
}), }),
summary: sync_events::RoomSummary { summary: sync_events::RoomSummary {
heroes: Vec::new(), heroes,
joined_member_count: if send_member_count { joined_member_count: joined_member_count.map(|n| (n as u32).into()),
Some((db.rooms.room_members(&room_id).count() as u32).into()) invited_member_count: invited_member_count.map(|n| (n as u32).into()),
} else {
None
},
invited_member_count: if send_member_count {
Some((db.rooms.room_members_invited(&room_id).count() as u32).into())
} else {
None
},
}, },
unread_notifications: sync_events::UnreadNotificationsCount { unread_notifications: sync_events::UnreadNotificationsCount {
highlight_count: None, highlight_count: None,
@ -2271,9 +2346,7 @@ pub fn sync_route(
// TODO: state before timeline // TODO: state before timeline
state: sync_events::State { state: sync_events::State {
events: if send_full_state { events: if send_full_state {
db.rooms state
.room_state(&room_id)
.unwrap()
.into_iter() .into_iter()
.map(|(_, pdu)| pdu.to_state_event()) .map(|(_, pdu)| pdu.to_state_event())
.collect() .collect()