[fractal] room: Handle latest change without Event



commit 90e4980cf513e333ac4a868033be1a68946a467a
Author: Kévin Commaille <zecakeh tedomum fr>
Date:   Fri Apr 22 12:01:37 2022 +0200

    room: Handle latest change without Event

 src/session/room/event.rs        | 20 ------------------
 src/session/room/mod.rs          | 45 ++++++++++++++++++++++++++++++++++++++--
 src/session/room/timeline/mod.rs | 29 +-------------------------
 3 files changed, 44 insertions(+), 50 deletions(-)
---
diff --git a/src/session/room/event.rs b/src/session/room/event.rs
index 63167e190..b4722f9b9 100644
--- a/src/session/room/event.rs
+++ b/src/session/room/event.rs
@@ -20,14 +20,12 @@ use matrix_sdk::{
     },
     Error as MatrixError,
 };
-use ruma::events::room::member::MembershipState;
 
 use super::{
     timeline::{TimelineItem, TimelineItemImpl},
     Member, ReactionList, Room,
 };
 use crate::{
-    session::UserExt,
     spawn_tokio,
     utils::{filename_for_mime, media_type_uid},
 };
@@ -693,22 +691,4 @@ impl Event {
             .await?;
         Ok(Some(event))
     }
-
-    /// Whether this `Event` can be used as the `latest_change` of a room.
-    ///
-    /// This means that the event is a message, or it is the state event of the
-    /// user joining the room, which should be the oldest possible change.
-    pub fn can_be_latest_change(&self) -> bool {
-        if let Some(event) = self.matrix_event() {
-            matches!(event, AnySyncRoomEvent::MessageLike(_))
-                || matches!(event, AnySyncRoomEvent::State(AnySyncStateEvent::RoomMember(event))
-                    if event.state_key == self.room().session().user().unwrap().user_id().to_string()
-                    && event.content.membership == MembershipState::Join
-                    && event.unsigned.prev_content.as_ref()
-                            .filter(|content| content.membership == MembershipState::Join).is_none()
-                )
-        } else {
-            false
-        }
-    }
 }
diff --git a/src/session/room/mod.rs b/src/session/room/mod.rs
index 28e913daa..6a447a43a 100644
--- a/src/session/room/mod.rs
+++ b/src/session/room/mod.rs
@@ -768,7 +768,10 @@ impl Room {
                         }
 
                         // The event is older than the read receipt so it has been read.
-                        if event.can_be_latest_change()
+                        if event
+                            .matrix_event()
+                            .filter(|event| can_be_latest_change(event, &user_id))
+                            .is_some()
                             && event.matrix_origin_server_ts()
                                 <= read_receipt.matrix_origin_server_ts()
                         {
@@ -864,8 +867,13 @@ impl Room {
                             return true;
                         }
 
+                        let user_id = self.session().user().unwrap().user_id();
                         // The user hasn't read the latest message.
-                        if event.can_be_latest_change() {
+                        if event
+                            .matrix_event()
+                            .filter(|event| can_be_latest_change(event, &user_id))
+                            .is_some()
+                        {
                             return false;
                         }
                     }
@@ -1541,6 +1549,23 @@ impl Room {
     pub fn verification(&self) -> Option<IdentityVerification> {
         self.imp().verification.borrow().clone()
     }
+
+    /// Update the latest change of the room with the given events.
+    ///
+    /// The events must be in reverse chronological order.
+    pub fn update_latest_change<'a>(&self, events: impl Iterator<Item = &'a AnySyncRoomEvent>) {
+        let user_id = self.session().user().unwrap().user_id();
+        let mut latest_change = self.latest_change();
+
+        for event in events {
+            if can_be_latest_change(event, &user_id) {
+                latest_change = latest_change.max(event.origin_server_ts().get().into());
+                break;
+            }
+        }
+
+        self.set_latest_change(latest_change);
+    }
 }
 
 trait GlibDateTime {
@@ -1554,3 +1579,19 @@ trait GlibDateTime {
     }
 }
 impl GlibDateTime for glib::DateTime {}
+
+/// Whether the given event can be used as the `latest_change` of a room.
+///
+/// `user_id` must be the `UserId` of the current account's user.
+///
+/// This means that the event is a message, or it is the state event of the
+/// user joining the room, which should be the oldest possible change.
+fn can_be_latest_change(event: &AnySyncRoomEvent, user_id: &UserId) -> bool {
+    matches!(event, AnySyncRoomEvent::MessageLike(_))
+        || matches!(event, AnySyncRoomEvent::State(AnySyncStateEvent::RoomMember(event))
+            if event.state_key == user_id.as_str()
+            && event.content.membership == MembershipState::Join
+            && event.unsigned.prev_content.as_ref()
+                    .filter(|content| content.membership == MembershipState::Join).is_none()
+        )
+}
diff --git a/src/session/room/timeline/mod.rs b/src/session/room/timeline/mod.rs
index aaa6de3bf..434ce8dea 100644
--- a/src/session/room/timeline/mod.rs
+++ b/src/session/room/timeline/mod.rs
@@ -573,6 +573,7 @@ impl Timeline {
                 room.session()
                     .verification_list()
                     .handle_response_room(&room, deser_events.iter());
+                room.update_latest_change(deser_events.iter());
 
                 let events: Vec<Event> = events
                     .into_iter()
@@ -585,20 +586,6 @@ impl Timeline {
                     return false;
                 }
 
-                // Update the latest change of the room.
-                let room = self.room();
-                let mut latest_change = room.latest_change();
-                // We receive the events in reverse chronological order so start from the
-                // beginning.
-                for event in events.iter() {
-                    if event.can_be_latest_change() {
-                        latest_change =
-                            latest_change.max(event.matrix_origin_server_ts().get().into());
-                        break;
-                    }
-                }
-                room.set_latest_change(latest_change);
-
                 self.set_state(TimelineState::Ready);
                 self.prepend(events);
                 true
@@ -859,20 +846,6 @@ async fn handle_forward_stream(
                     .map(|event| Event::new(event, &timeline.room()))
                     .collect();
 
-                // Update the latest change of the room.
-                let room = timeline.room();
-                let mut latest_change = room.latest_change();
-                // We receive the events in chronological order so start from the end.
-                let mut iter = events.iter();
-                while let Some(event) = iter.next_back() {
-                    if event.can_be_latest_change() {
-                        latest_change =
-                            latest_change.max(event.matrix_origin_server_ts().get().into());
-                        break;
-                    }
-                }
-                room.set_latest_change(latest_change);
-
                 timeline.append(events);
 
                 true


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]