[fractal] Transform the sync response in AppOp instead of the backend module



commit c581b614480b3857dd52745a0e094cde5525b170
Author: Alejandro Domínguez <adomu net-c com>
Date:   Wed Dec 2 10:26:09 2020 +0100

    Transform the sync response in AppOp instead of the backend module

 fractal-gtk/src/appop/sync.rs   | 136 ++++++++++++++++++++++++++++++++++++----
 fractal-gtk/src/backend/sync.rs | 125 +++---------------------------------
 2 files changed, 131 insertions(+), 130 deletions(-)
---
diff --git a/fractal-gtk/src/appop/sync.rs b/fractal-gtk/src/appop/sync.rs
index b72d969c..9228a9bb 100644
--- a/fractal-gtk/src/appop/sync.rs
+++ b/fractal-gtk/src/appop/sync.rs
@@ -1,11 +1,23 @@
-use crate::util::i18n::i18n;
-
 use crate::app::{App, RUNTIME};
 use crate::appop::AppOp;
 use crate::backend::{
-    sync::{self, RoomElement},
+    sync::{self, RoomElement, SyncRet, SyncUpdates},
     HandleError,
 };
+use crate::model::{
+    member::Member,
+    room::{Room, RoomMembership, RoomTag},
+};
+use crate::util::i18n::i18n;
+use log::{error, warn};
+use matrix_sdk::api::r0::sync::sync_events::JoinedRoom;
+use matrix_sdk::api::r0::sync::sync_events::Response as SyncResponse;
+use matrix_sdk::events::AnyEphemeralRoomEventContent;
+use matrix_sdk::events::AnySyncMessageEvent;
+use matrix_sdk::events::AnySyncRoomEvent;
+use matrix_sdk::events::AnySyncStateEvent;
+use matrix_sdk::identifiers::{RoomId, UserId};
+use std::collections::BTreeMap;
 
 impl AppOp {
     pub fn initial_sync(&self, show: bool) {
@@ -17,7 +29,12 @@ impl AppOp {
     }
 
     pub fn sync(&mut self, initial: bool, number_tries: u32) {
-        if let (Some(login_data), false) = (self.login_data.clone(), self.syncing) {
+        if let (Some((session_client, user_id)), false) = (
+            self.login_data
+                .as_ref()
+                .map(|ld| (ld.session_client.clone(), ld.uid.clone())),
+            self.syncing,
+        ) {
             self.syncing = true;
             // for the initial sync we set the since to None to avoid long syncing
             // the since can be a very old value and following the spec we should
@@ -26,16 +43,11 @@ impl AppOp {
             let join_to_room = self.join_to_room.clone();
             let since = self.since.clone().filter(|_| !initial);
             RUNTIME.spawn(async move {
-                let query = sync::sync(
-                    login_data.session_client,
-                    login_data.uid,
-                    since,
-                    number_tries,
-                )
-                .await;
+                let query = sync::sync(session_client, since, number_tries).await;
 
                 match query {
-                    Ok(sync_ret) => {
+                    Ok(response) => {
+                        let sync_ret = transform_sync_response(response, initial, user_id);
                         let clear_room_list = sync_ret.updates.is_none();
                         if let Some(updates) = sync_ret.updates {
                             let rooms = sync_ret.rooms;
@@ -121,3 +133,103 @@ impl AppOp {
         self.sync(false, number_tries);
     }
 }
+
+fn transform_sync_response(response: SyncResponse, initial: bool, user_id: UserId) -> SyncRet {
+    let updates = if initial {
+        None
+    } else {
+        Some(get_sync_updates(&response.rooms.join, &user_id))
+    };
+
+    SyncRet {
+        rooms: Room::from_sync_response(&response, user_id),
+        next_batch: response.next_batch,
+        updates,
+    }
+}
+
+fn get_sync_updates(join: &BTreeMap<RoomId, JoinedRoom>, user_id: &UserId) -> SyncUpdates {
+    SyncUpdates {
+        room_notifications: join
+            .iter()
+            .map(|(k, room)| (k.clone(), room.unread_notifications.clone()))
+            .collect(),
+        typing_events_as_rooms: join
+            .iter()
+            .map(|(k, room)| {
+                let typing: Vec<Member> = room.ephemeral.events
+                    .iter()
+                    .map(|ev| ev.deserialize())
+                    .inspect(|result_ev| if let Err(err) = result_ev {
+                        warn!("Bad event: {}", err);
+                    })
+                    .filter_map(Result::ok)
+                    .filter_map(|event| match event.content() {
+                        AnyEphemeralRoomEventContent::Typing(content) => {
+                            Some(content.user_ids)
+                        }
+                        _ => None,
+                    })
+                    .flatten()
+                    // ignoring the user typing notifications
+                    .filter(|user| user != user_id)
+                    .map(|uid| Member {
+                        uid,
+                        alias: None,
+                        avatar: None,
+                    })
+                    .collect();
+
+                Room {
+                    typing_users: typing,
+                    ..Room::new(k.clone(), RoomMembership::Joined(RoomTag::None))
+                }
+            })
+            .collect(),
+        new_events: join
+            .iter()
+            .flat_map(|(room_id, room)| {
+                let room_id = room_id.clone();
+                room.timeline
+                    .events
+                    .iter()
+                    .map(move |ev| Ok((room_id.clone(), ev.deserialize()?)))
+            })
+            .inspect(|result_ev: &Result<_, serde_json::Error>| {
+                if let Err(err) = result_ev {
+                    warn!("Bad event: {}", err);
+                }
+            })
+            .filter_map(Result::ok)
+            .filter_map(|(room_id, event)| {
+                match event {
+                    AnySyncRoomEvent::State(AnySyncStateEvent::RoomName(ev)) => {
+                        let name = ev.content.name().map(Into::into).unwrap_or_default();
+                        Some(RoomElement::Name(room_id, name))
+                    }
+                    AnySyncRoomEvent::State(AnySyncStateEvent::RoomTopic(ev)) => {
+                        Some(RoomElement::Topic(room_id, ev.content.topic))
+                    }
+                    AnySyncRoomEvent::State(AnySyncStateEvent::RoomAvatar(_)) => {
+                        Some(RoomElement::NewAvatar(room_id))
+                    }
+                    AnySyncRoomEvent::State(AnySyncStateEvent::RoomMember(ev)) => {
+                        Some(RoomElement::MemberEvent(ev.into_full_event(room_id)))
+                    }
+                    AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomRedaction(ev)) => {
+                        Some(RoomElement::RemoveMessage(room_id, ev.redacts))
+                    }
+                    AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomMessage(_)) => None,
+                    AnySyncRoomEvent::Message(AnySyncMessageEvent::Sticker(_)) => {
+                        // This event is managed in the room list
+                        None
+                    }
+                    ev => {
+                        error!("EVENT NOT MANAGED: {:?}", ev);
+                        None
+                    }
+                }
+            })
+            .collect(),
+    }
+}
diff --git a/fractal-gtk/src/backend/sync.rs b/fractal-gtk/src/backend/sync.rs
index 78d4b682..36455b54 100644
--- a/fractal-gtk/src/backend/sync.rs
+++ b/fractal-gtk/src/backend/sync.rs
@@ -1,34 +1,22 @@
 use crate::globals;
-use crate::model::{
-    member::Member,
-    room::{Room, RoomMembership, RoomTag},
-};
+use crate::model::room::Room;
+use log::error;
 use matrix_sdk::api::r0::filter::Filter as EventFilter;
 use matrix_sdk::api::r0::filter::FilterDefinition;
 use matrix_sdk::api::r0::filter::LazyLoadOptions;
 use matrix_sdk::api::r0::filter::RoomEventFilter;
 use matrix_sdk::api::r0::filter::RoomFilter;
 use matrix_sdk::api::r0::sync::sync_events::Filter;
-use matrix_sdk::api::r0::sync::sync_events::JoinedRoom;
 use matrix_sdk::api::r0::sync::sync_events::Response;
 use matrix_sdk::api::r0::sync::sync_events::UnreadNotificationsCount;
 use matrix_sdk::assign;
 use matrix_sdk::events::room::member::MemberEventContent;
-use matrix_sdk::events::AnyEphemeralRoomEventContent;
-use matrix_sdk::events::AnySyncMessageEvent;
-use matrix_sdk::events::AnySyncRoomEvent;
-use matrix_sdk::events::AnySyncStateEvent;
 use matrix_sdk::events::StateEvent;
-use matrix_sdk::SyncSettings;
-
-use log::{error, warn};
-use matrix_sdk::identifiers::{EventId, RoomId, UserId};
+use matrix_sdk::identifiers::{EventId, RoomId};
 use matrix_sdk::Client as MatrixClient;
 use matrix_sdk::Error as MatrixError;
-use std::{
-    collections::{BTreeMap, HashMap},
-    time::Duration,
-};
+use matrix_sdk::SyncSettings;
+use std::{collections::HashMap, time::Duration};
 
 use super::{get_ruma_client_error, remove_matrix_access_token_if_present, HandleError};
 use crate::app::App;
@@ -74,10 +62,9 @@ pub struct SyncUpdates {
 
 pub async fn sync(
     session_client: MatrixClient,
-    user_id: UserId,
     since: Option<String>,
     number_tries: u32,
-) -> Result<SyncRet, SyncError> {
+) -> Result<Response, SyncError> {
     let initial = since.is_none();
     let timeline_not_types = [String::from("m.call.*")];
     let timeline_types = [String::from("m.room.message"), String::from("m.sticker")];
@@ -118,7 +105,7 @@ pub async fn sync(
     };
 
     match session_client.sync_once(sync_settings).await {
-        Ok(response) => Ok(transform_sync_response(response, since.is_some(), user_id)),
+        Ok(response) => Ok(response),
         Err(err) => {
             // we wait if there's an error to avoid 100% CPU
             // we wait even longer, if it's a 429 (Too Many Requests) error
@@ -138,101 +125,3 @@ pub async fn sync(
         }
     }
 }
-
-fn transform_sync_response(response: Response, has_since: bool, user_id: UserId) -> SyncRet {
-    SyncRet {
-        rooms: Room::from_sync_response(&response, user_id.clone()),
-        next_batch: response.next_batch,
-        updates: if !has_since {
-            None
-        } else {
-            Some(get_sync_updates(&response.rooms.join, &user_id))
-        },
-    }
-}
-
-fn get_sync_updates(join: &BTreeMap<RoomId, JoinedRoom>, user_id: &UserId) -> SyncUpdates {
-    SyncUpdates {
-        room_notifications: join
-            .iter()
-            .map(|(k, room)| (k.clone(), room.unread_notifications.clone()))
-            .collect(),
-        typing_events_as_rooms: join
-            .iter()
-            .map(|(k, room)| {
-                let typing: Vec<Member> = room.ephemeral.events
-                    .iter()
-                    .map(|ev| ev.deserialize())
-                    .inspect(|result_ev| if let Err(err) = result_ev {
-                        warn!("Bad event: {}", err);
-                    })
-                    .filter_map(Result::ok)
-                    .filter_map(|event| match event.content() {
-                        AnyEphemeralRoomEventContent::Typing(content) => {
-                            Some(content.user_ids)
-                        }
-                        _ => None,
-                    })
-                    .flatten()
-                    // ignoring the user typing notifications
-                    .filter(|user| user != user_id)
-                    .map(|uid| Member {
-                        uid,
-                        alias: None,
-                        avatar: None,
-                    })
-                    .collect();
-
-                Room {
-                    typing_users: typing,
-                    ..Room::new(k.clone(), RoomMembership::Joined(RoomTag::None))
-                }
-            })
-            .collect(),
-        new_events: join
-            .iter()
-            .flat_map(|(room_id, room)| {
-                let room_id = room_id.clone();
-                room.timeline
-                    .events
-                    .iter()
-                    .map(move |ev| Ok((room_id.clone(), ev.deserialize()?)))
-            })
-            .inspect(|result_ev: &Result<_, serde_json::Error>| {
-                if let Err(err) = result_ev {
-                    warn!("Bad event: {}", err);
-                }
-            })
-            .filter_map(Result::ok)
-            .filter_map(|(room_id, event)| {
-                match event {
-                    AnySyncRoomEvent::State(AnySyncStateEvent::RoomName(ev)) => {
-                        let name = ev.content.name().map(Into::into).unwrap_or_default();
-                        Some(RoomElement::Name(room_id, name))
-                    }
-                    AnySyncRoomEvent::State(AnySyncStateEvent::RoomTopic(ev)) => {
-                        Some(RoomElement::Topic(room_id, ev.content.topic))
-                    }
-                    AnySyncRoomEvent::State(AnySyncStateEvent::RoomAvatar(_)) => {
-                        Some(RoomElement::NewAvatar(room_id))
-                    }
-                    AnySyncRoomEvent::State(AnySyncStateEvent::RoomMember(ev)) => {
-                        Some(RoomElement::MemberEvent(ev.into_full_event(room_id)))
-                    }
-                    AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomRedaction(ev)) => {
-                        Some(RoomElement::RemoveMessage(room_id, ev.redacts))
-                    }
-                    AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomMessage(_)) => None,
-                    AnySyncRoomEvent::Message(AnySyncMessageEvent::Sticker(_)) => {
-                        // This event is managed in the room list
-                        None
-                    }
-                    ev => {
-                        error!("EVENT NOT MANAGED: {:?}", ev);
-                        None
-                    }
-                }
-            })
-            .collect(),
-    }
-}


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