From 509187a1c5abc333e93660deb6dacef208a515bc Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Fri, 11 Apr 2025 08:43:10 +0100 Subject: fix(filamento): `handle_get_roster_with_users()` should not call the client handle so on connection function can complete --- filamento/src/logic/online.rs | 67 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 7 deletions(-) (limited to 'filamento/src/logic/online.rs') diff --git a/filamento/src/logic/online.rs b/filamento/src/logic/online.rs index c560b9b..767f923 100644 --- a/filamento/src/logic/online.rs +++ b/filamento/src/logic/online.rs @@ -94,16 +94,69 @@ pub async fn handle_get_roster( } } +// this can't query the client... otherwise there is a hold-up and the connection can't complete pub async fn handle_get_roster_with_users( logic: &ClientLogic, + connection: Connected, ) -> Result, RosterError> { - let roster = logic.client.get_roster().await?; - let mut users = Vec::new(); - for contact in &roster { - let user = logic.db().read_user(contact.user_jid.clone()).await?; - users.push(user); + let iq_id = Uuid::new_v4().to_string(); + let stanza = Stanza::Iq(Iq { + from: Some(connection.jid().clone()), + id: iq_id.to_string(), + to: None, + r#type: IqType::Get, + lang: None, + query: Some(iq::Query::Roster(stanza::roster::Query { + ver: None, + items: Vec::new(), + })), + errors: Vec::new(), + }); + let response = logic + .pending() + .request(&connection, stanza, iq_id.clone()) + .await?; + // TODO: timeout + match response { + Stanza::Iq(Iq { + from: _, + id, + to: _, + r#type, + lang: _, + query: Some(iq::Query::Roster(stanza::roster::Query { ver: _, items })), + errors: _, + }) if id == iq_id && r#type == IqType::Result => { + let contacts: Vec = items.into_iter().map(|item| item.into()).collect(); + if let Err(e) = logic.db().replace_cached_roster(contacts.clone()).await { + logic + .handle_error(Error::Roster(RosterError::Cache(e.into()))) + .await; + }; + let mut users = Vec::new(); + for contact in &contacts { + let user = logic.db().read_user(contact.user_jid.clone()).await?; + users.push(user); + } + Ok(contacts.into_iter().zip(users).collect()) + } + ref s @ Stanza::Iq(Iq { + from: _, + ref id, + to: _, + r#type, + lang: _, + query: _, + ref errors, + }) if *id == iq_id && r#type == IqType::Error => { + if let Some(error) = errors.first() { + Err(RosterError::StanzaError(error.clone())) + } else { + Err(RosterError::UnexpectedStanza(s.clone())) + } + } + s => Err(RosterError::UnexpectedStanza(s)), } - Ok(roster.into_iter().zip(users).collect()) } pub async fn handle_add_contact( @@ -1031,7 +1084,7 @@ pub async fn handle_online_result( let _ = result_sender.send(roster); } Command::GetRosterWithUsers(result_sender) => { - let roster = handle_get_roster_with_users(logic).await; + let roster = handle_get_roster_with_users(logic, connection).await; let _ = result_sender.send(roster); } Command::GetChats(sender) => { -- cgit