aboutsummaryrefslogtreecommitdiffstats
path: root/filamento
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2025-04-11 08:43:10 +0100
committerLibravatar cel 🌸 <cel@bunny.garden>2025-04-11 08:43:10 +0100
commit509187a1c5abc333e93660deb6dacef208a515bc (patch)
tree644642d5a3fe0c30f25e6ce71139979ae343bc3c /filamento
parent15faa6b95ffb5c64a56e212cf386c29fef56efc8 (diff)
downloadluz-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.rs67
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) => {