refactor: optimize avatar load and messages adding

This commit is contained in:
MeexReay 2025-08-31 14:25:06 +03:00
parent 91c2c7f35e
commit b501c30ca3
2 changed files with 50 additions and 54 deletions

View File

@ -72,6 +72,7 @@ pub fn clear_chat_messages(ctx: Arc<Context>, messages: Vec<String>) {
} }
pub fn add_chat_messages(ctx: Arc<Context>, messages: Vec<String>) { pub fn add_chat_messages(ctx: Arc<Context>, messages: Vec<String>) {
println!("add chat messages: {}", messages.len());
let _ = ctx let _ = ctx
.sender .sender
.read() .read()
@ -818,13 +819,12 @@ fn setup(_: &Application, ctx: Arc<Context>, ui: UiModel) {
let ctx = ctx.clone(); let ctx = ctx.clone();
move || { move || {
while let Ok((messages, clear)) = receiver.recv() { while let Ok((messages, clear)) = receiver.recv() {
println!("got chat messages: {}", messages.len());
let ctx = ctx.clone(); let ctx = ctx.clone();
let messages = Arc::new(messages); let messages = Arc::new(messages);
let added = Arc::new(AtomicBool::new(false));
timeout_add_once(Duration::ZERO, { timeout_add_once(Duration::ZERO, {
let messages = messages.clone(); let messages = messages.clone();
let added = added.clone();
move || { move || {
GLOBAL.with(|global| { GLOBAL.with(|global| {
@ -838,60 +838,56 @@ fn setup(_: &Application, ctx: Arc<Context>, ui: UiModel) {
for message in messages.iter() { for message in messages.iter() {
on_add_message(ctx.clone(), &ui, message.to_string(), !clear); on_add_message(ctx.clone(), &ui, message.to_string(), !clear);
} }
}
});
added.store(true, Ordering::SeqCst) thread::spawn(move || {
for message in messages.iter() {
let Some(avatar_url) = grab_avatar(message) else { continue };
let avatar_id = get_avatar_id(&avatar_url);
let Some(avatar) = load_avatar(&avatar_url)
.and_then(|avatar| load_pixbuf(&avatar).ok())
.and_then(|pixbuf|
pixbuf.scale_simple(32, 32, InterpType::Bilinear
))
.and_then(|pixbuf| Some((
pixbuf.pixel_bytes()?,
pixbuf.colorspace(),
pixbuf.has_alpha(),
pixbuf.bits_per_sample(),
pixbuf.width(),
pixbuf.height(),
pixbuf.rowstride()
))) else { continue };
timeout_add_once(Duration::ZERO, {
move || {
GLOBAL.with(|global| {
if let Some(ui) = &*global.borrow() {
let pixbuf = Pixbuf::from_bytes(
&avatar.0,
avatar.1,
avatar.2,
avatar.3,
avatar.4,
avatar.5,
avatar.6
);
if let Some(pics) = ui.avatars.lock().unwrap().remove(&avatar_id) {
for pic in pics {
pic.set_pixbuf(Some(&pixbuf));
}
}
}
});
}
});
} }
}); });
} }
}); });
for message in messages.iter() {
let Some(avatar_url) = grab_avatar(message) else { continue };
let avatar_id = get_avatar_id(&avatar_url);
let Some(avatar) = load_avatar(&avatar_url)
.and_then(|avatar| load_pixbuf(&avatar).ok())
.and_then(|pixbuf|
pixbuf.scale_simple(32, 32, InterpType::Bilinear
))
.and_then(|pixbuf| Some((
pixbuf.pixel_bytes()?,
pixbuf.colorspace(),
pixbuf.has_alpha(),
pixbuf.bits_per_sample(),
pixbuf.width(),
pixbuf.height(),
pixbuf.rowstride()
))) else { continue };
timeout_add_once(Duration::ZERO, {
let added = added.clone();
move || {
while !added.load(Ordering::SeqCst) {}
GLOBAL.with(|global| {
if let Some(ui) = &*global.borrow() {
let pixbuf = Pixbuf::from_bytes(
&avatar.0,
avatar.1,
avatar.2,
avatar.3,
avatar.4,
avatar.5,
avatar.6
);
if let Some(pics) = ui.avatars.lock().unwrap().remove(&avatar_id) {
for pic in pics {
pic.set_pixbuf(Some(&pixbuf));
}
}
}
});
}
});
}
} }
} }
}); });

View File

@ -67,9 +67,9 @@ pub fn sanitize_text(input: &str) -> String {
#[cfg(feature = "gtk")] #[cfg(feature = "gtk")]
pub fn add_message(ctx: Arc<Context>, message: &str) -> Result<(), Box<dyn Error>> { pub fn add_message(ctx: Arc<Context>, message: &str) -> Result<(), Box<dyn Error>> {
for i in message.split("\n").map(|o| o.to_string()) { let messages: Vec<String> = message.split("\n").map(|o| o.to_string()).collect();
print_message(ctx.clone(), i)?; ctx.add_message(ctx.config(|o| o.max_messages), messages.clone());
} add_chat_messages(ctx.clone(), messages);
Ok(()) Ok(())
} }