diff options
author | 2025-04-11 08:43:10 +0100 | |
---|---|---|
committer | 2025-04-11 08:43:10 +0100 | |
commit | 509187a1c5abc333e93660deb6dacef208a515bc (patch) | |
tree | 644642d5a3fe0c30f25e6ce71139979ae343bc3c /filamento | |
parent | 15faa6b95ffb5c64a56e212cf386c29fef56efc8 (diff) | |
download | luz-509187a1c5abc333e93660deb6dacef208a515bc.tar.gz luz-509187a1c5abc333e93660deb6dacef208a515bc.tar.bz2 luz-509187a1c5abc333e93660deb6dacef208a515bc.zip |
fix(filamento): `handle_get_roster_with_users()` should not call the client handle so on connection function can complete
Diffstat (limited to '')
-rw-r--r-- | filamento/src/logic/online.rs | 67 |
1 files changed, 60 insertions, 7 deletions
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<Fs: FileStore + Clone>( } } +// 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<Fs: FileStore + Clone>( logic: &ClientLogic<Fs>, + connection: Connected, ) -> Result<Vec<(Contact, User)>, 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<Contact> = 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<Fs: FileStore + Clone>( @@ -1031,7 +1084,7 @@ pub async fn handle_online_result<Fs: FileStore + Clone>( 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) => { |