[fractal/fractal-next] room: Use the transaction_id for pending events



commit 1d158e52ae1dd678664d07c6d28075c49557cbab
Author: Kévin Commaille <zecakeh tedomum fr>
Date:   Thu Nov 11 15:35:50 2021 +0100

    room: Use the transaction_id for pending events
    
    Fixes #853

 src/session/room/event.rs    | 17 ++++++++++++++++-
 src/session/room/mod.rs      |  5 ++---
 src/session/room/timeline.rs | 33 ++++++++++++++++++---------------
 3 files changed, 36 insertions(+), 19 deletions(-)
---
diff --git a/src/session/room/event.rs b/src/session/room/event.rs
index 04a4c39e..febd87fb 100644
--- a/src/session/room/event.rs
+++ b/src/session/room/event.rs
@@ -5,7 +5,7 @@ use matrix_sdk::{
         events::{
             room::message::MessageType, room::message::Relation, AnyMessageEventContent,
             AnyRedactedSyncMessageEvent, AnyRedactedSyncStateEvent, AnySyncMessageEvent,
-            AnySyncRoomEvent, AnySyncStateEvent,
+            AnySyncRoomEvent, AnySyncStateEvent, Unsigned,
         },
         identifiers::{EventId, UserId},
         MilliSecondsSinceUnixEpoch,
@@ -233,6 +233,21 @@ impl Event {
         }
     }
 
+    pub fn matrix_transaction_id(&self) -> Option<String> {
+        let priv_ = imp::Event::from_instance(self);
+
+        priv_
+            .pure_event
+            .borrow()
+            .as_ref()
+            .unwrap()
+            .event
+            .get_field::<Unsigned>("unsigned")
+            .ok()
+            .and_then(|opt| opt)
+            .and_then(|unsigned| unsigned.transaction_id)
+    }
+
     pub fn source(&self) -> String {
         let priv_ = imp::Event::from_instance(self);
 
diff --git a/src/session/room/mod.rs b/src/session/room/mod.rs
index a9871453..701e5bbd 100644
--- a/src/session/room/mod.rs
+++ b/src/session/room/mod.rs
@@ -842,12 +842,11 @@ impl Room {
         let content = event.content();
 
         if let MatrixRoom::Joined(matrix_room) = self.matrix_room() {
-            let pending_id = event.event_id().clone();
             let json = serde_json::to_string(&AnySyncRoomEvent::Message(event)).unwrap();
             let raw_event: Raw<AnySyncRoomEvent> =
                 Raw::from_json(RawValue::from_string(json).unwrap());
             let event = Event::new(raw_event.into(), self);
-            priv_.timeline.get().unwrap().append_pending(event);
+            priv_.timeline.get().unwrap().append_pending(txn_id, event);
 
             let handle = spawn_tokio!(async move { matrix_room.send(content, Some(txn_id)).await });
 
@@ -856,7 +855,7 @@ impl Room {
                 clone!(@weak self as obj => async move {
                     // FIXME: We should retry the request if it fails
                     match handle.await.unwrap() {
-                            Ok(result) => obj.timeline().set_event_id_for_pending(pending_id, 
result.event_id),
+                            Ok(_) => {},
                             Err(error) => error!("Couldn’t send message: {}", error),
                     };
                 })
diff --git a/src/session/room/timeline.rs b/src/session/room/timeline.rs
index f3cd94f4..420a137c 100644
--- a/src/session/room/timeline.rs
+++ b/src/session/room/timeline.rs
@@ -1,9 +1,12 @@
 use gtk::{gio, glib, glib::clone, prelude::*, subclass::prelude::*};
 use log::error;
-use matrix_sdk::ruma::{
-    api::client::r0::message::get_message_events::Direction,
-    events::{AnySyncRoomEvent, AnySyncStateEvent},
-    identifiers::EventId,
+use matrix_sdk::{
+    ruma::{
+        api::client::r0::message::get_message_events::Direction,
+        events::{AnySyncRoomEvent, AnySyncStateEvent},
+        identifiers::EventId,
+    },
+    uuid::Uuid,
 };
 
 use crate::session::room::{Event, Item, ItemType, Room};
@@ -25,7 +28,7 @@ mod imp {
         /// A Hashmap linking `EventId` to corresponding `Event`
         pub event_map: RefCell<HashMap<EventId, Event>>,
         /// Maps the temporary `EventId` of the pending Event to the real `EventId`
-        pub pending_events: RefCell<HashMap<EventId, EventId>>,
+        pub pending_events: RefCell<HashMap<String, EventId>>,
         pub loading: Cell<bool>,
         pub complete: Cell<bool>,
         pub oldest_event: RefCell<Option<EventId>>,
@@ -347,7 +350,10 @@ impl Timeline {
             for event in batch.into_iter() {
                 let event_id = event.matrix_event_id();
 
-                if let Some(pending_id) = pending_events.remove(&event_id) {
+                if let Some(pending_id) = event
+                    .matrix_transaction_id()
+                    .and_then(|txn_id| pending_events.remove(&txn_id))
+                {
                     let mut event_map = priv_.event_map.borrow_mut();
 
                     if let Some(pending_event) = event_map.remove(&pending_id) {
@@ -376,7 +382,7 @@ impl Timeline {
     }
 
     /// Append an event that wasn't yet fully sent and received via a sync
-    pub fn append_pending(&self, event: Event) {
+    pub fn append_pending(&self, txn_id: Uuid, event: Event) {
         let priv_ = imp::Timeline::from_instance(self);
 
         priv_
@@ -384,6 +390,11 @@ impl Timeline {
             .borrow_mut()
             .insert(event.matrix_event_id(), event.clone());
 
+        priv_
+            .pending_events
+            .borrow_mut()
+            .insert(txn_id.to_string(), event.matrix_event_id());
+
         let index = {
             let mut list = priv_.list.borrow_mut();
             let index = list.len();
@@ -402,14 +413,6 @@ impl Timeline {
         }
     }
 
-    pub fn set_event_id_for_pending(&self, pending_event_id: EventId, event_id: EventId) {
-        let priv_ = imp::Timeline::from_instance(self);
-        priv_
-            .pending_events
-            .borrow_mut()
-            .insert(event_id, pending_event_id);
-    }
-
     /// Returns the event with the given id
     pub fn event_by_id(&self, event_id: &EventId) -> Option<Event> {
         // TODO: if the referenced event isn't known to us we will need to request it


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