[fractal] room: Keep track of user activity



commit 5fea3cd583d85fb75c0bce6972b4833450554778
Author: Kévin Commaille <zecakeh tedomum fr>
Date:   Fri Jul 15 10:30:05 2022 +0200

    room: Keep track of user activity
    
    Allow to sort the members list by activity

 src/session/room/member.rs       | 38 ++++++++++++++++++++++++++++++++++++++
 src/session/room/timeline/mod.rs | 20 +++++++++++++++++++-
 2 files changed, 57 insertions(+), 1 deletion(-)
---
diff --git a/src/session/room/member.rs b/src/session/room/member.rs
index 8040ae54c..00630d537 100644
--- a/src/session/room/member.rs
+++ b/src/session/room/member.rs
@@ -69,6 +69,8 @@ mod imp {
     pub struct Member {
         pub power_level: Cell<PowerLevel>,
         pub membership: Cell<Membership>,
+        /// The timestamp of the latest activity of this member.
+        pub latest_activity: Cell<u64>,
     }
 
     #[glib::object_subclass]
@@ -99,16 +101,39 @@ mod imp {
                         Membership::default() as i32,
                         glib::ParamFlags::READABLE | glib::ParamFlags::EXPLICIT_NOTIFY,
                     ),
+                    glib::ParamSpecUInt64::new(
+                        "latest-activity",
+                        "Latest Activity",
+                        "The timestamp of the latest activity of this member",
+                        u64::MIN,
+                        u64::MAX,
+                        0,
+                        glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
+                    ),
                 ]
             });
 
             PROPERTIES.as_ref()
         }
 
+        fn set_property(
+            &self,
+            obj: &Self::Type,
+            _id: usize,
+            value: &glib::Value,
+            pspec: &glib::ParamSpec,
+        ) {
+            match pspec.name() {
+                "latest-activity" => obj.set_latest_activity(value.get().unwrap()),
+                _ => unimplemented!(),
+            }
+        }
+
         fn property(&self, obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
             match pspec.name() {
                 "power-level" => obj.power_level().to_value(),
                 "membership" => obj.membership().to_value(),
+                "latest-activity" => obj.latest_activity().to_value(),
                 _ => unimplemented!(),
             }
         }
@@ -169,6 +194,19 @@ impl Member {
         self.notify("membership");
     }
 
+    pub fn latest_activity(&self) -> u64 {
+        self.imp().latest_activity.get()
+    }
+
+    pub fn set_latest_activity(&self, activity: u64) {
+        if self.latest_activity() >= activity {
+            return;
+        }
+
+        self.imp().latest_activity.set(activity);
+        self.notify("latest-activity");
+    }
+
     /// Update the user based on the room member.
     pub fn update_from_room_member(&self, member: &RoomMember) {
         if member.user_id() != &*self.user_id() {
diff --git a/src/session/room/timeline/mod.rs b/src/session/room/timeline/mod.rs
index ee3e69412..f95ab67f8 100644
--- a/src/session/room/timeline/mod.rs
+++ b/src/session/room/timeline/mod.rs
@@ -651,7 +651,7 @@ impl Timeline {
             let mut pending_events = priv_.pending_events.borrow_mut();
             let mut hidden_events = vec![];
 
-            for event in batch {
+            for event in batch.into_iter() {
                 if let Some(event_id) = event
                     .downcast_ref::<UnsupportedEvent>()
                     .and_then(|event| event.event_id())
@@ -661,6 +661,15 @@ impl Timeline {
                 } else if let Ok(event) = event.downcast::<SupportedEvent>() {
                     let event_id = event.event_id();
 
+                    if event.counts_as_unread() {
+                        event.sender().set_latest_activity(
+                            event
+                                .origin_server_ts()
+                                .map(|ts| ts.0.into())
+                                .unwrap_or_default(),
+                        );
+                    }
+
                     if let Some(pending_id) = event
                         .transaction_id()
                         .and_then(|txn_id| pending_events.remove(&txn_id))
@@ -783,6 +792,15 @@ impl Timeline {
                     priv_.event_map.borrow_mut().insert(event_id, event);
                     added -= 1;
                 } else if let Ok(event) = event.downcast::<SupportedEvent>() {
+                    if event.counts_as_unread() {
+                        event.sender().set_latest_activity(
+                            event
+                                .origin_server_ts()
+                                .map(|ts| ts.0.into())
+                                .unwrap_or_default(),
+                        );
+                    }
+
                     priv_
                         .event_map
                         .borrow_mut()


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