From c945fb7c4349f83180b66d5aa1d35f9e90ec4ca3e7dbb32e3609393d1b53a3ba Mon Sep 17 00:00:00 2001 From: Evan Carroll Date: Tue, 27 Jan 2026 01:00:39 -0600 Subject: [PATCH] remove members by key --- .../src/components/avatar.rs | 21 +++++++- .../src/components/scene_viewer.rs | 51 +++++++++++-------- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/crates/chattyness-user-ui/src/components/avatar.rs b/crates/chattyness-user-ui/src/components/avatar.rs index d03e4eb..39469d7 100644 --- a/crates/chattyness-user-ui/src/components/avatar.rs +++ b/crates/chattyness-user-ui/src/components/avatar.rs @@ -663,13 +663,28 @@ pub fn Avatar( // Effect to draw the avatar when canvas is ready or appearance changes Effect::new(move |_| { // Subscribe to redraw trigger so this effect re-runs when images load - let _ = redraw_trigger.get(); + let trigger_count = redraw_trigger.get(); // Get current values from signals let m = member.get(); let layout = layout_memo.get(); + // Debug: log avatar redraw + web_sys::console::log_1( + &format!( + "[Avatar Redraw] user={} trigger={} pos=({:.1}, {:.1}) screen=({:.1}, {:.1})", + m.member.display_name, + trigger_count, + m.member.position_x, + m.member.position_y, + layout.canvas_screen_x, + layout.canvas_screen_y, + ) + .into(), + ); + let Some(canvas) = canvas_ref.get() else { + web_sys::console::log_1(&"[Avatar Redraw] canvas not ready".into()); return; }; @@ -716,7 +731,11 @@ pub fn Avatar( // Set onload handler to trigger redraw when image loads let trigger = set_redraw_trigger; + let path_for_log = normalized_path.clone(); let onload = Closure::once(Box::new(move || { + web_sys::console::log_1( + &format!("[Avatar] Image loaded: {}", path_for_log).into(), + ); trigger.update(|v| *v += 1); }) as Box); img.set_onload(Some(onload.as_ref().unchecked_ref())); diff --git a/crates/chattyness-user-ui/src/components/scene_viewer.rs b/crates/chattyness-user-ui/src/components/scene_viewer.rs index 4c3641e..b885f11 100644 --- a/crates/chattyness-user-ui/src/components/scene_viewer.rs +++ b/crates/chattyness-user-ui/src/components/scene_viewer.rs @@ -468,14 +468,14 @@ pub fn RealmSceneViewer( }) .into(); - let members_by_key = Signal::derive(move || { - sorted_members.get().into_iter().enumerate() - .map(|(idx, m)| (member_key(&m), (idx, m))) - .collect::>() - }); - - let member_keys = Memo::new(move |_| { - sorted_members.get().iter().map(member_key).collect::>() + // Create indexed members for z-ordering (index determines stacking) + let indexed_members = Signal::derive(move || { + sorted_members + .get() + .into_iter() + .enumerate() + .map(|(idx, m)| (idx, m)) + .collect::>() }); let scene_name = scene.name.clone(); @@ -511,33 +511,40 @@ pub fn RealmSceneViewer(
- {move || { - member_keys.get().into_iter().map(|key| { - let member_signal = Signal::derive(move || { - members_by_key.get().get(&key).map(|(_, m)| m.clone()).expect("member key should exist") + = Memo::new(move |_| { + sorted_members + .get() + .into_iter() + .find(|m| member_key(m) == key) + .unwrap_or_else(|| initial_member.clone()) }); - let z_index_signal = Signal::derive(move || { - members_by_key.get().get(&key).map(|(idx, _)| (*idx as i32) + Z_AVATAR_BASE).unwrap_or(Z_AVATAR_BASE) - }); - let z = z_index_signal.get_untracked(); - // Derive bubble signal for this member - let bubble_signal = Signal::derive(move || { + + // Bubble signal for this member + let bubble_signal: Signal> = Signal::derive(move || { active_bubbles.get().get(&key).cloned() }); view! { } - }).collect_view() - }} + } + /> {move || { let Some(fading_signal) = fading_members else { return Vec::new().into_iter().collect_view();