[fractal] Create rooms through matrix-sdk



commit b5a85ee0881a46d4c87eac821db30a96d6984f23
Author: Alejandro Domínguez <adomu net-c com>
Date:   Sun Aug 16 04:31:49 2020 +0200

    Create rooms through matrix-sdk

 fractal-gtk/src/appop/room.rs                      |  17 +--
 fractal-gtk/src/appop/start_chat.rs                |  20 ++-
 fractal-gtk/src/backend/room.rs                    | 156 +++++++++------------
 fractal-matrix-api/src/meson.build                 |   4 -
 fractal-matrix-api/src/r0.rs                       |   1 -
 fractal-matrix-api/src/r0/config.rs                |   2 -
 .../src/r0/config/get_global_account_data.rs       |  28 ----
 .../src/r0/config/set_global_account_data.rs       |  30 ----
 fractal-matrix-api/src/r0/room.rs                  |  10 --
 fractal-matrix-api/src/r0/room/create_room.rs      |  72 ----------
 10 files changed, 83 insertions(+), 257 deletions(-)
---
diff --git a/fractal-gtk/src/appop/room.rs b/fractal-gtk/src/appop/room.rs
index 74d76477..e65f70ae 100644
--- a/fractal-gtk/src/appop/room.rs
+++ b/fractal-gtk/src/appop/room.rs
@@ -378,8 +378,9 @@ impl AppOp {
     }
 
     pub fn create_new_room(&mut self) {
-        let login_data = unwrap_or_unit_return!(self.login_data.clone());
-        let name = self
+        let session_client =
+            unwrap_or_unit_return!(self.login_data.as_ref().map(|ld| ld.session_client.clone()));
+        let name_entry = self
             .ui
             .builder
             .get_object::<gtk::Entry>("new_room_name")
@@ -390,7 +391,7 @@ impl AppOp {
             .get_object::<gtk::ToggleButton>("private_visibility_button")
             .expect("Can't find private_visibility_button in ui file.");
 
-        let n = name.get_text().to_string();
+        let name = name_entry.get_text().to_string();
         // Since the switcher
         let privacy = if private.get_active() {
             room::RoomType::Private
@@ -398,14 +399,8 @@ impl AppOp {
             room::RoomType::Public
         };
 
-        let name = n;
-        thread::spawn(move || {
-            match room::new_room(
-                login_data.session_client.homeserver().clone(),
-                login_data.access_token,
-                name,
-                privacy,
-            ) {
+        RUNTIME.spawn(async move {
+            match room::new_room(session_client, name, privacy).await {
                 Ok(r) => {
                     APPOP!(new_room, (r));
                 }
diff --git a/fractal-gtk/src/appop/start_chat.rs b/fractal-gtk/src/appop/start_chat.rs
index 1c902b26..61ea26d4 100644
--- a/fractal-gtk/src/appop/start_chat.rs
+++ b/fractal-gtk/src/appop/start_chat.rs
@@ -1,8 +1,7 @@
 use crate::backend::room;
 use gtk::prelude::*;
-use std::thread;
 
-use crate::app::App;
+use crate::app::{App, RUNTIME};
 use crate::appop::AppOp;
 use crate::appop::SearchType;
 use crate::backend::HandleError;
@@ -13,17 +12,14 @@ impl AppOp {
             return;
         }
 
-        let login_data = unwrap_or_unit_return!(self.login_data.clone());
-        let user = self.invite_list[0].clone();
+        let (session_client, user_id) = unwrap_or_unit_return!(self
+            .login_data
+            .as_ref()
+            .map(|ld| (ld.session_client.clone(), ld.uid.clone())));
+        let member = self.invite_list[0].0.clone();
 
-        let member = user.0;
-        thread::spawn(move || {
-            match room::direct_chat(
-                login_data.session_client.homeserver().clone(),
-                login_data.access_token,
-                login_data.uid,
-                member,
-            ) {
+        RUNTIME.spawn(async move {
+            match room::direct_chat(session_client, &user_id, member).await {
                 Ok(r) => {
                     APPOP!(new_room, (r));
                 }
diff --git a/fractal-gtk/src/backend/room.rs b/fractal-gtk/src/backend/room.rs
index 0afc0c1d..68945831 100644
--- a/fractal-gtk/src/backend/room.rs
+++ b/fractal-gtk/src/backend/room.rs
@@ -12,7 +12,6 @@ use std::fs;
 use std::io::Error as IoError;
 use std::path::{Path, PathBuf};
 
-use std::collections::HashMap;
 use std::convert::TryFrom;
 use std::time::Duration;
 
@@ -28,10 +27,18 @@ use crate::model::{
     message::Message,
     room::{Room, RoomMembership, RoomTag},
 };
-use fractal_api::r0::config::get_global_account_data::request as get_global_account_data;
-use fractal_api::r0::config::get_global_account_data::Parameters as GetGlobalAccountDataParameters;
-use fractal_api::r0::config::set_global_account_data::request as set_global_account_data;
-use fractal_api::r0::config::set_global_account_data::Parameters as SetGlobalAccountDataParameters;
+use fractal_api::api::r0::config::get_global_account_data::Request as GetGlobalAccountDataRequest;
+use fractal_api::api::r0::config::set_global_account_data::Request as SetGlobalAccountDataRequest;
+use fractal_api::api::r0::room::create_room::Request as CreateRoomRequest;
+use fractal_api::api::r0::room::create_room::RoomPreset;
+use fractal_api::api::r0::room::Visibility;
+use fractal_api::assign;
+use fractal_api::events::room::history_visibility::HistoryVisibility;
+use fractal_api::events::room::history_visibility::HistoryVisibilityEventContent;
+use fractal_api::events::AnyBasicEventContent;
+use fractal_api::events::AnyInitialStateEvent;
+use fractal_api::events::EventType;
+use fractal_api::events::InitialStateEvent;
 use fractal_api::r0::config::set_room_account_data::request as set_room_account_data;
 use fractal_api::r0::config::set_room_account_data::Parameters as SetRoomAccountDataParameters;
 use fractal_api::r0::filter::RoomEventFilter;
@@ -58,12 +65,6 @@ use fractal_api::r0::redact::redact_event::request as redact_event;
 use fractal_api::r0::redact::redact_event::Body as RedactEventBody;
 use fractal_api::r0::redact::redact_event::Parameters as RedactEventParameters;
 use fractal_api::r0::redact::redact_event::Response as RedactEventResponse;
-use fractal_api::r0::room::create_room::request as create_room;
-use fractal_api::r0::room::create_room::Body as CreateRoomBody;
-use fractal_api::r0::room::create_room::Parameters as CreateRoomParameters;
-use fractal_api::r0::room::create_room::Response as CreateRoomResponse;
-use fractal_api::r0::room::create_room::RoomPreset;
-use fractal_api::r0::room::Visibility;
 use fractal_api::r0::state::create_state_events_for_key::request as create_state_events_for_key;
 use fractal_api::r0::state::create_state_events_for_key::Parameters as CreateStateEventsForKeyParameters;
 use fractal_api::r0::state::get_state_events_for_key::request as get_state_events_for_key;
@@ -82,6 +83,7 @@ use fractal_api::r0::typing::Body as TypingNotificationBody;
 use fractal_api::r0::typing::Parameters as TypingNotificationParameters;
 use fractal_api::r0::AccessToken;
 
+use serde_json::value::to_raw_value;
 use serde_json::Value as JsonValue;
 
 use super::{
@@ -650,10 +652,10 @@ pub enum RoomType {
 }
 
 #[derive(Debug)]
-pub struct NewRoomError(ReqwestError);
+pub struct NewRoomError(MatrixError);
 
-impl From<ReqwestError> for NewRoomError {
-    fn from(err: ReqwestError) -> Self {
+impl From<MatrixError> for NewRoomError {
+    fn from(err: MatrixError) -> Self {
         Self(err)
     }
 }
@@ -673,28 +675,23 @@ impl HandleError for NewRoomError {
     }
 }
 
-pub fn new_room(
-    base: Url,
-    access_token: AccessToken,
+pub async fn new_room(
+    session_client: MatrixClient,
     name: String,
     privacy: RoomType,
 ) -> Result<Room, NewRoomError> {
-    let params = CreateRoomParameters { access_token };
-
     let (visibility, preset) = match privacy {
         RoomType::Public => (Visibility::Public, RoomPreset::PublicChat),
         RoomType::Private => (Visibility::Private, RoomPreset::PrivateChat),
     };
 
-    let body = CreateRoomBody {
-        name: Some(name.clone()),
-        visibility: Some(visibility),
+    let request = assign!(CreateRoomRequest::new(), {
+        name: Some(&name),
+        visibility: visibility,
         preset: Some(preset),
-        ..Default::default()
-    };
+    });
 
-    let request = create_room(base, &params, &body)?;
-    let response: CreateRoomResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
+    let response = session_client.create_room(request).await?;
 
     Ok(Room {
         name: Some(name),
@@ -704,13 +701,13 @@ pub fn new_room(
 
 #[derive(Debug)]
 pub enum DirectChatError {
-    Reqwest(ReqwestError),
-    EventsDeserialization(IdError),
+    Matrix(MatrixError),
+    EventsDeserialization,
 }
 
-impl From<ReqwestError> for DirectChatError {
-    fn from(err: ReqwestError) -> Self {
-        Self::Reqwest(err)
+impl From<MatrixError> for DirectChatError {
+    fn from(err: MatrixError) -> Self {
+        Self::Matrix(err)
     }
 }
 
@@ -730,84 +727,69 @@ impl HandleError for DirectChatError {
     }
 }
 
-fn update_direct_chats(
-    base: Url,
-    access_token: AccessToken,
-    user_id: UserId,
+async fn update_direct_chats(
+    session_client: MatrixClient,
+    user_id: &UserId,
     room_id: RoomId,
     user: Member,
 ) -> Result<(), DirectChatError> {
-    let params = GetGlobalAccountDataParameters {
-        access_token: access_token.clone(),
+    let event_type = EventType::Direct;
+
+    let request = GetGlobalAccountDataRequest::new(user_id, event_type.as_ref());
+    let response = session_client.send(request).await?;
+
+    let mut directs = match response
+        .account_data
+        .deserialize()
+        .map(|data| data.content())
+    {
+        Ok(AnyBasicEventContent::Direct(directs)) => directs,
+        _ => return Err(DirectChatError::EventsDeserialization),
     };
 
-    let request = get_global_account_data(base.clone(), &params, &user_id, "m.direct")?;
-    let response: JsonValue = HTTP_CLIENT.get_client().execute(request)?.json()?;
-
-    let mut directs = response
-        .as_object()
-        .into_iter()
-        .flatten()
-        .map(|(uid, rooms)| {
-            let roomlist = rooms
-                .as_array()
-                .unwrap()
-                .iter()
-                .map(|x| RoomId::try_from(x.as_str().unwrap_or_default()))
-                .collect::<Result<Vec<RoomId>, IdError>>()?;
-            Ok((UserId::try_from(uid.as_str())?, roomlist))
-        })
-        .collect::<Result<HashMap<UserId, Vec<RoomId>>, IdError>>()
-        .map_err(DirectChatError::EventsDeserialization)?;
+    directs.entry(user.uid).or_default().push(room_id);
 
-    if let Some(v) = directs.get_mut(&user.uid) {
-        v.push(room_id);
-    } else {
-        directs.insert(user.uid, vec![room_id]);
-    }
+    let request = SetGlobalAccountDataRequest::new(
+        to_raw_value(&directs).or(Err(DirectChatError::EventsDeserialization))?,
+        event_type.as_ref(),
+        user_id,
+    );
 
-    let params = SetGlobalAccountDataParameters { access_token };
-
-    let request = set_global_account_data(base, &params, &json!(directs), &user_id, "m.direct")?;
-    HTTP_CLIENT.get_client().execute(request)?;
+    session_client.send(request).await?;
 
     Ok(())
 }
 
-pub fn direct_chat(
-    base: Url,
-    access_token: AccessToken,
-    user_id: UserId,
+pub async fn direct_chat(
+    session_client: MatrixClient,
+    user_id: &UserId,
     user: Member,
 ) -> Result<Room, DirectChatError> {
-    let params = CreateRoomParameters {
-        access_token: access_token.clone(),
-    };
+    let invite = &[user.uid.clone()];
+    let initial_state = &[AnyInitialStateEvent::RoomHistoryVisibility(
+        InitialStateEvent {
+            state_key: Default::default(),
+            content: HistoryVisibilityEventContent::new(HistoryVisibility::Invited),
+        },
+    )];
 
-    let body = CreateRoomBody {
-        invite: vec![user.uid.clone()],
-        visibility: Some(Visibility::Private),
+    let request = assign!(CreateRoomRequest::new(), {
+        invite,
+        visibility: Visibility::Private,
         preset: Some(RoomPreset::PrivateChat),
         is_direct: true,
-        initial_state: vec![json!({
-            "type": "m.room.history_visibility",
-            "content": {
-                "history_visibility": "invited"
-            }
-        })],
-        ..Default::default()
-    };
+        initial_state,
+    });
 
-    let request = create_room(base.clone(), &params, &body)?;
-    let response: CreateRoomResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
+    let response = session_client.create_room(request).await?;
 
     update_direct_chats(
-        base,
-        access_token,
+        session_client.clone(),
         user_id,
         response.room_id.clone(),
         user.clone(),
-    )?;
+    )
+    .await?;
 
     Ok(Room {
         name: user.alias,
diff --git a/fractal-matrix-api/src/meson.build b/fractal-matrix-api/src/meson.build
index 282d497c..3afeee5d 100644
--- a/fractal-matrix-api/src/meson.build
+++ b/fractal-matrix-api/src/meson.build
@@ -8,8 +8,6 @@ api_sources = files(
   'r0/account/login.rs',
   'r0/account/logout.rs',
   'r0/account/register.rs',
-  'r0/config/get_global_account_data.rs',
-  'r0/config/set_global_account_data.rs',
   'r0/config/set_room_account_data.rs',
   'r0/contact/create.rs',
   'r0/contact/delete.rs',
@@ -26,7 +24,6 @@ api_sources = files(
   'r0/profile/set_display_name.rs',
   'r0/read_marker/set_read_marker.rs',
   'r0/redact/redact_event.rs',
-  'r0/room/create_room.rs',
   'r0/search/user.rs',
   'r0/server/domain_info.rs',
   'r0/state/create_state_events_for_key.rs',
@@ -46,7 +43,6 @@ api_sources = files(
   'r0/profile.rs',
   'r0/read_marker.rs',
   'r0/redact.rs',
-  'r0/room.rs',
   'r0/search.rs',
   'r0/server.rs',
   'r0/state.rs',
diff --git a/fractal-matrix-api/src/r0.rs b/fractal-matrix-api/src/r0.rs
index e66e4dd0..e7088cb0 100644
--- a/fractal-matrix-api/src/r0.rs
+++ b/fractal-matrix-api/src/r0.rs
@@ -9,7 +9,6 @@ pub mod profile;
 pub mod pushrules;
 pub mod read_marker;
 pub mod redact;
-pub mod room;
 pub mod search;
 pub mod server;
 pub mod state;
diff --git a/fractal-matrix-api/src/r0/config.rs b/fractal-matrix-api/src/r0/config.rs
index 62850769..2cbdc922 100644
--- a/fractal-matrix-api/src/r0/config.rs
+++ b/fractal-matrix-api/src/r0/config.rs
@@ -1,3 +1 @@
-pub mod get_global_account_data;
-pub mod set_global_account_data;
 pub mod set_room_account_data;


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