[fractal] room: Handle latest change without Event
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal] room: Handle latest change without Event
- Date: Tue, 26 Apr 2022 10:13:48 +0000 (UTC)
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]