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

@ -51,6 +51,17 @@ pub type WsSender = Box<dyn Fn(ClientMessage)>;
/// Local stored value type for the sender (non-Send, WASM-compatible).
pub type WsSenderStorage = StoredValue<Option<WsSender>, LocalStorage>;
/// Information about the current channel member (received on Welcome).
#[derive(Clone, Debug)]
pub struct ChannelMemberInfo {
/// The user's user_id (if authenticated user).
pub user_id: Option<uuid::Uuid>,
/// The user's guest_session_id (if guest).
pub guest_session_id: Option<uuid::Uuid>,
/// The user's display name.
pub display_name: String,
}
/// Hook to manage WebSocket connection for a channel.
///
/// Returns a tuple of:
@ -66,6 +77,7 @@ pub fn use_channel_websocket(
on_prop_dropped: Callback<LooseProp>,
on_prop_picked_up: Callback<uuid::Uuid>,
on_member_fading: Callback<FadingMember>,
on_welcome: Option<Callback<ChannelMemberInfo>>,
) -> (Signal<WsState>, WsSenderStorage) {
use std::cell::RefCell;
use std::rc::Rc;
@ -162,6 +174,7 @@ pub fn use_channel_websocket(
let on_prop_dropped_clone = on_prop_dropped.clone();
let on_prop_picked_up_clone = on_prop_picked_up.clone();
let on_member_fading_clone = on_member_fading.clone();
let on_welcome_clone = on_welcome.clone();
// For starting heartbeat on Welcome
let ws_ref_for_heartbeat = ws_ref.clone();
let heartbeat_started: Rc<RefCell<bool>> = Rc::new(RefCell::new(false));
@ -174,7 +187,7 @@ pub fn use_channel_websocket(
if let Ok(msg) = serde_json::from_str::<ServerMessage>(&text) {
// Check for Welcome message to start heartbeat with server-provided config
if let ServerMessage::Welcome { ref config, .. } = msg {
if let ServerMessage::Welcome { ref config, ref member, .. } = msg {
if !*heartbeat_started_clone.borrow() {
*heartbeat_started_clone.borrow_mut() = true;
let ping_interval_ms = config.ping_interval_secs * 1000;
@ -194,6 +207,15 @@ pub fn use_channel_websocket(
});
std::mem::forget(heartbeat);
}
// Call on_welcome callback with current user info
if let Some(ref callback) = on_welcome_clone {
let info = ChannelMemberInfo {
user_id: member.user_id,
guest_session_id: member.guest_session_id,
display_name: member.display_name.clone(),
};
callback.run(info);
}
}
handle_server_message(
msg,
@ -406,6 +428,7 @@ pub fn use_channel_websocket(
_on_prop_dropped: Callback<LooseProp>,
_on_prop_picked_up: Callback<uuid::Uuid>,
_on_member_fading: Callback<FadingMember>,
_on_welcome: Option<Callback<ChannelMemberInfo>>,
) -> (Signal<WsState>, WsSenderStorage) {
let (ws_state, _) = signal(WsState::Disconnected);
let sender: WsSenderStorage = StoredValue::new_local(None);