aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2025-06-11 03:25:54 +0100
committerLibravatar cel 🌸 <cel@bunny.garden>2025-06-11 03:25:54 +0100
commit12fb631bac1030284f91c20446773eb4f4733ed7 (patch)
treeb1e60b8cf8b69c2a84e2d41e7edcf57ed1d2ef7b
parentbddaa534a19e98155b4f1a9dc3f7cab47b64d317 (diff)
downloadluz-12fb631bac1030284f91c20446773eb4f4733ed7.tar.gz
luz-12fb631bac1030284f91c20446773eb4f4733ed7.tar.bz2
luz-12fb631bac1030284f91c20446773eb4f4733ed7.zip
feat: use spawn_blocking for avatar image processing
Diffstat (limited to '')
-rw-r--r--filamento/src/logic/connect.rs2
-rw-r--r--filamento/src/logic/mod.rs2
-rw-r--r--filamento/src/logic/online.rs44
3 files changed, 27 insertions, 21 deletions
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<Fs: FileStore + Clone + Send + Sync>(
+pub async fn handle_connect<Fs: FileStore + Clone + Send + Sync + 'static>(
logic: ClientLogic<Fs>,
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<Fs: FileStore> ClientLogic<Fs> {
}
}
-impl<Fs: FileStore + Clone + Send + Sync> Logic for ClientLogic<Fs> {
+impl<Fs: FileStore + Clone + Send + Sync + 'static> Logic for ClientLogic<Fs> {
type Cmd = Command<Fs>;
// 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<Fs: FileStore + Clone>(logic: ClientLogic<Fs>, command: Command<Fs>, connection: Connected) {
+pub async fn handle_online<Fs: FileStore + Clone + 'static>(logic: ClientLogic<Fs>, command: Command<Fs>, connection: Connected) {
let result = handle_online_result(&logic, command, connection).await;
match result {
Ok(_) => {}
@@ -973,29 +975,33 @@ pub async fn handle_change_nick<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>,
Ok(())
}
-pub async fn handle_change_avatar<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>, img_data: Option<Vec<u8>>) -> Result<(), AvatarPublishError<Fs>> {
+pub async fn handle_change_avatar<Fs: FileStore + Clone + 'static>(logic: &ClientLogic<Fs>, img_data: Option<Vec<u8>>) -> Result<(), AvatarPublishError<Fs>> {
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<u8>, String), AvatarPublishError<Fs>>((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<Fs: FileStore + Clone>(
}
// TODO: could probably macro-ise?
-pub async fn handle_online_result<Fs: FileStore + Clone>(
+pub async fn handle_online_result<Fs: FileStore + Clone + 'static>(
logic: &ClientLogic<Fs>,
command: Command<Fs>,
connection: Connected,