From 864cfaec544497dfc0531dd6be4d93488b303df39091f2cdae4a469e5f79af5d Mon Sep 17 00:00:00 2001 From: Evan Carroll Date: Tue, 20 Jan 2026 20:11:37 -0600 Subject: [PATCH] fix: teleport was prepopulating prior wisper --- .../chattyness-user-ui/src/components/chat.rs | 8 ++++++-- crates/chattyness-user-ui/src/pages/realm.rs | 20 ++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/crates/chattyness-user-ui/src/components/chat.rs b/crates/chattyness-user-ui/src/components/chat.rs index 314eb67..1ea4738 100644 --- a/crates/chattyness-user-ui/src/components/chat.rs +++ b/crates/chattyness-user-ui/src/components/chat.rs @@ -128,8 +128,9 @@ pub fn ChatInput( #[prop(optional)] on_open_log: Option>, /// Signal containing the display name to whisper to. When set, pre-fills the input. - #[prop(optional, into)] - whisper_target: Option>>, + /// Uses RwSignal so the component can clear it after consuming. + #[prop(optional)] + whisper_target: Option>>, /// List of available scenes for teleport command. #[prop(optional, into)] scenes: Option>>, @@ -240,6 +241,9 @@ pub fn ChatInput( let _ = input.focus(); let len = whisper_prefix.len() as u32; let _ = input.set_selection_range(len, len); + + // Clear the whisper target so it doesn't re-trigger on re-render + whisper_signal.set(None); } }); } diff --git a/crates/chattyness-user-ui/src/pages/realm.rs b/crates/chattyness-user-ui/src/pages/realm.rs index 113fb53..3fe2a94 100644 --- a/crates/chattyness-user-ui/src/pages/realm.rs +++ b/crates/chattyness-user-ui/src/pages/realm.rs @@ -111,7 +111,7 @@ pub fn RealmPage() -> impl IntoView { let (is_guest, set_is_guest) = signal(false); // Whisper target - when set, triggers pre-fill in ChatInput - let (whisper_target, set_whisper_target) = signal(Option::::None); + let whisper_target = RwSignal::new(Option::::None); // Notification state for cross-scene whispers let (current_notification, set_current_notification) = @@ -852,10 +852,17 @@ pub fn RealmPage() -> impl IntoView { *closure_holder_clone.borrow_mut() = Some(closure); // Add keyup handler for releasing '?' (hotkey help) + // We hide on any keyup when visible, since ? = Shift+/ and releasing + // either key means the user is no longer holding '?' let keyup_closure = Closure::::new( move |ev: web_sys::KeyboardEvent| { - if ev.key() == "?" { + let key = ev.key(); + // Hide if releasing ?, /, or Shift while help is visible + if hotkey_help_visible.get_untracked() + && (key == "?" || key == "/" || key == "Shift") + { set_hotkey_help_visible.set(false); + ev.prevent_default(); } }, ); @@ -1024,9 +1031,8 @@ pub fn RealmPage() -> impl IntoView { let on_open_log_cb = Callback::new(move |_: ()| { set_log_open.set(true); }); - let whisper_target_signal = Signal::derive(move || whisper_target.get()); let on_whisper_request_cb = Callback::new(move |target: String| { - set_whisper_target.set(Some(target)); + whisper_target.set(Some(target)); }); let scenes_signal = Signal::derive(move || available_scenes.get()); let teleport_enabled_signal = Signal::derive(move || allow_user_teleport.get()); @@ -1074,7 +1080,7 @@ pub fn RealmPage() -> impl IntoView { on_open_settings=on_open_settings_cb on_open_inventory=on_open_inventory_cb on_open_log=on_open_log_cb - whisper_target=whisper_target_signal + whisper_target=whisper_target scenes=scenes_signal allow_user_teleport=teleport_enabled_signal on_teleport=on_teleport_cb @@ -1179,7 +1185,7 @@ pub fn RealmPage() -> impl IntoView { impl IntoView { open=Signal::derive(move || history_modal_open.get()) on_close=Callback::new(move |_: ()| set_history_modal_open.set(false)) on_reply=Callback::new(move |name: String| { - set_whisper_target.set(Some(name)); + whisper_target.set(Some(name)); }) on_context=Callback::new(move |name: String| { set_conversation_partner.set(name);