fix some emotion bugs

This commit is contained in:
Evan Carroll 2026-01-13 14:08:38 -06:00
parent bd28e201a2
commit 989e20757b
11 changed files with 1203 additions and 190 deletions

View file

@ -191,7 +191,7 @@ async fn handle_socket(
tracing::info!("[WS] Channel joined");
// Get initial state
let members = match get_members_with_avatars(&mut *conn, channel_id, realm_id).await {
let members = match get_members_with_avatars(&mut conn, channel_id, realm_id).await {
Ok(m) => m,
Err(e) => {
tracing::error!("[WS] Failed to get members: {:?}", e);
@ -231,8 +231,11 @@ async fn handle_socket(
}
// Broadcast join to others
let avatar = avatars::get_avatar_render_data(&mut *conn, user.id, realm_id)
let avatar = avatars::get_avatar_with_paths_conn(&mut *conn, user.id, realm_id)
.await
.ok()
.flatten()
.map(|a| a.to_render_data())
.unwrap_or_default();
let join_msg = ServerMessage::MemberJoined {
member: ChannelMemberWithAvatar { member, avatar },
@ -322,6 +325,36 @@ async fn handle_socket(
// Respond with pong directly (not broadcast)
// This is handled in the send task via individual message
}
ClientMessage::SendChatMessage { content } => {
// Validate message
if content.is_empty() || content.len() > 500 {
continue;
}
// Get member's current position and emotion
let member_info = channel_members::get_channel_member(
&mut *recv_conn,
channel_id,
user_id,
realm_id,
)
.await;
if let Ok(Some(member)) = member_info {
let msg = ServerMessage::ChatMessageReceived {
message_id: Uuid::new_v4(),
user_id: Some(user_id),
guest_session_id: None,
display_name: member.display_name.clone(),
content,
emotion: member.current_emotion as u8,
x: member.position_x,
y: member.position_y,
timestamp: chrono::Utc::now().timestamp_millis(),
};
let _ = tx.send(msg);
}
}
}
}
}
@ -376,25 +409,32 @@ async fn handle_socket(
}
/// Helper: Get all channel members with their avatar render data.
async fn get_members_with_avatars<'e>(
executor: impl sqlx::PgExecutor<'e>,
async fn get_members_with_avatars(
conn: &mut sqlx::pool::PoolConnection<sqlx::Postgres>,
channel_id: Uuid,
realm_id: Uuid,
) -> Result<Vec<ChannelMemberWithAvatar>, AppError> {
// Get members first, then we need to get avatars
// But executor is consumed by the first query, so we need the pool
// Actually, let's just inline this to avoid the complexity
let members = channel_members::get_channel_members(executor, channel_id, realm_id).await?;
// Get members first
let members = channel_members::get_channel_members(&mut **conn, channel_id, realm_id).await?;
// For avatar data, we'll just return default for now since the query
// would need another executor
let result: Vec<ChannelMemberWithAvatar> = members
.into_iter()
.map(|member| ChannelMemberWithAvatar {
member,
avatar: AvatarRenderData::default(),
})
.collect();
// Fetch avatar data for each member using full avatar with paths
// This avoids the CASE statement approach and handles all emotions correctly
let mut result = Vec::with_capacity(members.len());
for member in members {
let avatar = if let Some(user_id) = member.user_id {
// Get full avatar and convert to render data for current emotion
avatars::get_avatar_with_paths_conn(&mut **conn, user_id, realm_id)
.await
.ok()
.flatten()
.map(|a| a.to_render_data())
.unwrap_or_default()
} else {
// Guest users don't have avatars
AvatarRenderData::default()
};
result.push(ChannelMemberWithAvatar { member, avatar });
}
Ok(result)
}