From 12fb631bac1030284f91c20446773eb4f4733ed7 Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Wed, 11 Jun 2025 03:25:54 +0100 Subject: feat: use spawn_blocking for avatar image processing --- filamento/src/logic/connect.rs | 2 +- filamento/src/logic/mod.rs | 2 +- filamento/src/logic/online.rs | 44 ++++++++++++++++++++++++------------------ 3 files changed, 27 insertions(+), 21 deletions(-) (limited to 'filamento/src') diff --git a/filamento/src/logic/connect.rs b/filamento/src/logic/connect.rs index 9d61ca4..6e392f1 100644 --- a/filamento/src/logic/connect.rs +++ b/filamento/src/logic/connect.rs @@ -11,7 +11,7 @@ use crate::{ use super::ClientLogic; -pub async fn handle_connect( +pub async fn handle_connect( logic: ClientLogic, connection: Connected, ) { diff --git a/filamento/src/logic/mod.rs b/filamento/src/logic/mod.rs index 146f3b0..ddf0343 100644 --- a/filamento/src/logic/mod.rs +++ b/filamento/src/logic/mod.rs @@ -127,7 +127,7 @@ impl ClientLogic { } } -impl Logic for ClientLogic { +impl Logic for ClientLogic { type Cmd = Command; // pub async fn handle_stream_error(self, error) {} diff --git a/filamento/src/logic/online.rs b/filamento/src/logic/online.rs index febd3e1..2bf9cd8 100644 --- a/filamento/src/logic/online.rs +++ b/filamento/src/logic/online.rs @@ -11,7 +11,9 @@ use stanza::{ iq::{self, Iq, IqType, Query}, Stanza }, xep_0030::{info, items}, xep_0060::{self, owner, pubsub::{self, Pubsub}}, xep_0084, xep_0172::{self, Nick}, xep_0203::Delay }; -use tokio::sync::oneshot; +use tokio::{sync::oneshot, task::spawn_blocking}; +#[cfg(target_arch = "wasm32")] +use tokio_with_wasm::alias as tokio; use tracing::{debug, error, info}; use uuid::Uuid; @@ -27,7 +29,7 @@ use super::{ }, ClientLogic }; -pub async fn handle_online(logic: ClientLogic, command: Command, connection: Connected) { +pub async fn handle_online(logic: ClientLogic, command: Command, connection: Connected) { let result = handle_online_result(&logic, command, connection).await; match result { Ok(_) => {} @@ -973,29 +975,33 @@ pub async fn handle_change_nick(logic: &ClientLogic, Ok(()) } -pub async fn handle_change_avatar(logic: &ClientLogic, img_data: Option>) -> Result<(), AvatarPublishError> { +pub async fn handle_change_avatar(logic: &ClientLogic, img_data: Option>) -> Result<(), AvatarPublishError> { match img_data { // set avatar Some(data) => { - // load the image data and guess the format - let image = ImageReader::new(Cursor::new(data)).with_guessed_format()?.decode()?; + let (bytes, hash, data_png, data_b64) = spawn_blocking(move || -> Result<_, _> { + // load the image data and guess the format + let image = ImageReader::new(Cursor::new(data)).with_guessed_format()?.decode()?; + + // convert the image to png; + let mut data_png = Vec::new(); + let image = image.resize(192, 192, image::imageops::FilterType::Nearest); + image.write_to(&mut Cursor::new(&mut data_png), image::ImageFormat::Jpeg)?; - // convert the image to png; - let mut data_png = Vec::new(); - let image = image.resize(192, 192, image::imageops::FilterType::Nearest); - image.write_to(&mut Cursor::new(&mut data_png), image::ImageFormat::Jpeg)?; + // calculate the length of the data in bytes. + let bytes = data_png.len().try_into()?; - // calculate the length of the data in bytes. - let bytes = data_png.len().try_into()?; + // calculate sha1 hash of the data + let mut sha1 = Sha1::new(); + sha1.update(&data_png); + let sha1_result = sha1.finalize(); + let hash = hex::encode(sha1_result); - // calculate sha1 hash of the data - let mut sha1 = Sha1::new(); - sha1.update(&data_png); - let sha1_result = sha1.finalize(); - let hash = hex::encode(sha1_result); + // encode the image data as base64 + let data_b64 = BASE64_STANDARD.encode(data_png.clone()); - // encode the image data as base64 - let data_b64 = BASE64_STANDARD.encode(data_png.clone()); + Ok::<(u32, String, Vec, String), AvatarPublishError>((bytes, hash, data_png, data_b64)) + }).await.unwrap()?; // publish the data to the data node logic.client().publish(pep::Item::AvatarData(Some(avatar::Data { hash: hash.clone(), data_b64 })), "urn:xmpp:avatar:data".to_string()).await?; @@ -1081,7 +1087,7 @@ pub async fn handle_delete_pep_node( } // TODO: could probably macro-ise? -pub async fn handle_online_result( +pub async fn handle_online_result( logic: &ClientLogic, command: Command, connection: Connected, -- cgit