[fractal] timeline: Remove event when it should be hidden after decryption
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal] timeline: Remove event when it should be hidden after decryption
- Date: Thu, 15 Sep 2022 15:05:28 +0000 (UTC)
commit 0b8d78c7e38e8beb62974f74b16a266fd420358d
Author: Kévin Commaille <zecakeh tedomum fr>
Date: Thu Sep 15 15:24:38 2022 +0200
timeline: Remove event when it should be hidden after decryption
src/session/room/event/supported_event.rs | 29 ++++++++++++++++++----
src/session/room/timeline/mod.rs | 41 +++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 5 deletions(-)
---
diff --git a/src/session/room/event/supported_event.rs b/src/session/room/event/supported_event.rs
index 367f55f74..ec329cec8 100644
--- a/src/session/room/event/supported_event.rs
+++ b/src/session/room/event/supported_event.rs
@@ -1,5 +1,5 @@
use gtk::{glib, glib::clone, prelude::*, subclass::prelude::*};
-use log::debug;
+use log::{debug, error};
use matrix_sdk::{
deserialized_responses::SyncTimelineEvent,
media::MediaEventContent,
@@ -25,7 +25,7 @@ use crate::{
prelude::*,
session::room::{
timeline::{TimelineItem, TimelineItemImpl},
- Member, ReactionList, Room,
+ Member, ReactionList, Room, UnsupportedEvent,
},
spawn, spawn_tokio,
utils::{filename_for_mime, media_type_uid},
@@ -192,6 +192,9 @@ impl SupportedEvent {
/// Set the deserialized Matrix event of this `SupportedEvent`.
fn set_matrix_event(&self, matrix_event: AnySyncTimelineEvent) {
+ let was_hidden = self.is_hidden_event();
+ let event_id = matrix_event.event_id().to_owned();
+
if let AnySyncTimelineEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted(
SyncMessageLikeEvent::Original(_),
)) = matrix_event
@@ -202,6 +205,13 @@ impl SupportedEvent {
}
self.imp().matrix_event.replace(Some(matrix_event));
+
+ // Remove the event from the timeline if is should now be hidden.
+ let is_hidden = self.is_hidden_event();
+ if !was_hidden && is_hidden {
+ self.room().timeline().remove_event(&event_id);
+ }
+
self.notify("activatable");
}
@@ -227,9 +237,18 @@ impl SupportedEvent {
self.room().disconnect(keys_handle);
}
let pure_event = SyncTimelineEvent::from(decrypted);
- let matrix_event = pure_event.event.deserialize().unwrap();
- self.set_pure_event(pure_event);
- self.set_matrix_event(matrix_event);
+ if let Ok(matrix_event) = pure_event.event.deserialize() {
+ self.set_pure_event(pure_event);
+ self.set_matrix_event(matrix_event);
+ } else {
+ error!("Couldn’t deserialize event: {:?}", pure_event.event);
+
+ // Remove this event from the timeline.
+ let room = self.room();
+ let new_event = UnsupportedEvent::new(pure_event, &room);
+ room.timeline()
+ .replace_supported_event(self.event_id(), new_event);
+ }
}
Err(error) => {
let room_name = room.display_name();
diff --git a/src/session/room/timeline/mod.rs b/src/session/room/timeline/mod.rs
index f95ab67f8..c57414c00 100644
--- a/src/session/room/timeline/mod.rs
+++ b/src/session/room/timeline/mod.rs
@@ -746,6 +746,21 @@ impl Timeline {
self.imp().event_map.borrow().get(event_id).cloned()
}
+ /// Get the position of the event with the given id in this `Timeline`.
+ pub fn find_event_position(&self, event_id: &EventId) -> Option<usize> {
+ self.imp()
+ .list
+ .borrow()
+ .iter()
+ .enumerate()
+ .find_map(|(pos, item)| {
+ item.downcast_ref::<Event>()
+ .and_then(|event| event.event_id())
+ .filter(|item_event_id| item_event_id == event_id)
+ .map(|_| pos)
+ })
+ }
+
/// Fetch the event with the given id.
///
/// If the event can't be found locally, a request will be made to the
@@ -865,6 +880,32 @@ impl Timeline {
self.imp().list.borrow_mut().pop_front();
self.upcast_ref::<gio::ListModel>().items_changed(0, 1, 0);
}
+
+ /// Remove the given event from the timeline.
+ ///
+ /// This should be used when the source of an `Event` changes and it should
+ /// be hidden now.
+ pub fn remove_event(&self, event_id: &EventId) {
+ if let Some(index) = self.find_event_position(event_id) {
+ self.imp().list.borrow_mut().remove(index);
+
+ self.items_changed(index as u32, 1, 0);
+ }
+ }
+
+ /// Replace the supported event with the given ID with the given unsupported
+ /// event in this timeline.
+ ///
+ /// This should be used when the source of a `SupportedEvent` changes, and
+ /// the new source fails to deserialize.
+ pub fn replace_supported_event(&self, event_id: OwnedEventId, event: UnsupportedEvent) {
+ self.remove_event(&event_id);
+
+ self.imp()
+ .event_map
+ .borrow_mut()
+ .insert(event_id, event.upcast());
+ }
}
async fn handle_forward_stream(
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]