Add the right-click ability on avatars

This commit is contained in:
Evan Carroll 2026-01-18 10:05:38 -06:00
parent d1cbb3ba34
commit 0492043625
7 changed files with 438 additions and 2 deletions

View file

@ -55,6 +55,7 @@ fn parse_emote_command(cmd: &str) -> Option<String> {
/// - `on_focus_change`: Callback when focus state changes
/// - `on_open_settings`: Callback to open settings popup
/// - `on_open_inventory`: Callback to open inventory popup
/// - `whisper_target`: Signal containing the display name to whisper to (triggers pre-fill)
#[component]
pub fn ChatInput(
ws_sender: WsSenderStorage,
@ -68,6 +69,9 @@ pub fn ChatInput(
on_open_settings: Option<Callback<()>>,
#[prop(optional)]
on_open_inventory: Option<Callback<()>>,
/// Signal containing the display name to whisper to. When set, pre-fills the input.
#[prop(optional, into)]
whisper_target: Option<Signal<Option<String>>>,
) -> impl IntoView {
let (message, set_message) = signal(String::new());
let (command_mode, set_command_mode) = signal(CommandMode::None);
@ -121,6 +125,41 @@ pub fn ChatInput(
});
}
// Handle whisper target pre-fill
#[cfg(feature = "hydrate")]
{
Effect::new(move |_| {
let Some(whisper_signal) = whisper_target else {
return;
};
let Some(target_name) = whisper_signal.get() else {
return;
};
// Pre-fill with /whisper command
let placeholder = "your message here";
let whisper_text = format!("/whisper {} {}", target_name, placeholder);
if let Some(input) = input_ref.get() {
// Set the message
set_message.set(whisper_text.clone());
set_command_mode.set(CommandMode::None);
// Update input value
input.set_value(&whisper_text);
// Focus the input
let _ = input.focus();
// Select the placeholder text so it gets replaced when typing
let prefix_len = format!("/whisper {} ", target_name).len() as u32;
let total_len = whisper_text.len() as u32;
let _ = input.set_selection_range(prefix_len, total_len);
}
});
}
// Apply emotion via WebSocket
let apply_emotion = {
move |emotion: String| {