feat: heroes, don't send notifications every time
This commit is contained in:
		
							parent
							
								
									b7f7a39973
								
							
						
					
					
						commit
						32da76b9a2
					
				
					 1 changed files with 91 additions and 18 deletions
				
			
		|  | @ -24,8 +24,8 @@ use ruma_client_api::{ | |||
|         keys::{self, claim_keys, get_keys, upload_keys}, | ||||
|         media::{create_content, get_content, get_content_thumbnail, get_media_config}, | ||||
|         membership::{ | ||||
|             forget_room, get_member_events, invite_user, join_room_by_id, join_room_by_id_or_alias, | ||||
|             kick_user, leave_room, ban_user, unban_user, | ||||
|             ban_user, forget_room, get_member_events, invite_user, join_room_by_id, | ||||
|             join_room_by_id_or_alias, kick_user, leave_room, unban_user, | ||||
|         }, | ||||
|         message::{create_message_event, get_message_events}, | ||||
|         presence::set_presence, | ||||
|  | @ -2151,7 +2151,9 @@ pub fn sync_route( | |||
| 
 | ||||
|         let mut send_member_count = false; | ||||
|         let mut send_full_state = false; | ||||
|         let mut send_notification_counts = false; | ||||
|         for pdu in &pdus { | ||||
|             send_notification_counts = true; | ||||
|             if pdu.kind == EventType::RoomMember { | ||||
|                 send_member_count = true; | ||||
|                 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() { | ||||
|                 Some( | ||||
|                     (db.rooms | ||||
|  | @ -2188,7 +2268,10 @@ pub fn sync_route( | |||
|                 ) | ||||
|             } else { | ||||
|                 None | ||||
|             }; | ||||
|             } | ||||
|         } else { | ||||
|             None | ||||
|         }; | ||||
| 
 | ||||
|         // They /sync response doesn't always return all messages, so we say the output is
 | ||||
|         // limited unless there are enough events
 | ||||
|  | @ -2247,17 +2330,9 @@ pub fn sync_route( | |||
|                         .collect(), | ||||
|                 }), | ||||
|                 summary: sync_events::RoomSummary { | ||||
|                     heroes: Vec::new(), | ||||
|                     joined_member_count: if send_member_count { | ||||
|                         Some((db.rooms.room_members(&room_id).count() 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 | ||||
|                     }, | ||||
|                     heroes, | ||||
|                     joined_member_count: joined_member_count.map(|n| (n as u32).into()), | ||||
|                     invited_member_count: invited_member_count.map(|n| (n as u32).into()), | ||||
|                 }, | ||||
|                 unread_notifications: sync_events::UnreadNotificationsCount { | ||||
|                     highlight_count: None, | ||||
|  | @ -2271,9 +2346,7 @@ pub fn sync_route( | |||
|                 // TODO: state before timeline
 | ||||
|                 state: sync_events::State { | ||||
|                     events: if send_full_state { | ||||
|                         db.rooms | ||||
|                             .room_state(&room_id) | ||||
|                             .unwrap() | ||||
|                         state | ||||
|                             .into_iter() | ||||
|                             .map(|(_, pdu)| pdu.to_state_event()) | ||||
|                             .collect() | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue