VNOX-Client/src/net/internal/dispatch/channel.rs
loki5512344 bf0b237afd Initial commit: split VNOX monorepo into VNOX-Client
Desktop client with egui + wgpu UI, audio pipeline (cpal/opus/rodio),
networking (LNEx protocol), and identity management with encrypted vault.

Jitter buffer module extracted from voice-node for standalone operation.
2026-07-09 11:52:57 +02:00

162 lines
6 KiB
Rust

use anyhow::{Result, anyhow};
use serde_json;
use tokio::sync::mpsc;
use super::super::super::payloads::*;
use super::super::super::types::NetEvent;
use super::super::super::types::{ChannelListItem as InfoChannelListItem, ChatMsg, MemberInfo};
pub async fn handle(pid: u16, payload: &[u8], tx: &mpsc::Sender<NetEvent>) -> Result<()> {
match pid {
PID_CHANNEL_STATE => {
let p: ChannelStatePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::ChannelState {
channel_id: p.channel_id,
channel_name: p.channel_name,
kind: p.kind,
members: p
.members
.into_iter()
.map(|m| MemberInfo {
user_id: m.user_id,
nickname: m.nickname,
in_voice: m.in_voice,
})
.collect(),
voice_endpoint: p.voice_endpoint,
})
.await;
}
PID_CHANNEL_CREATE => {
let p: ChannelCreatePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::ChannelCreated {
channel_id: p.channel_id,
channel_name: p.channel_name,
kind: p.kind,
})
.await;
}
PID_CHANNEL_DELETE => {
let p: ChannelDeletePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::ChannelDeleted {
channel_id: p.channel_id,
})
.await;
}
PID_CHANNEL_LIST => {
let p: ChannelListPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::ChannelListEvent {
channels: p
.channels
.into_iter()
.map(|c| InfoChannelListItem {
channel_id: c.channel_id,
channel_name: c.channel_name,
kind: c.kind,
})
.collect(),
})
.await;
}
PID_CHAT_MESSAGE => {
let p: ChatMessagePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::ChatMessage {
message_id: p.message_id,
channel_id: p.channel_id,
sender_id: p.sender_id.clone(),
nickname: p.sender_id,
content: p.content,
timestamp: p.timestamp,
reply_to: p.reply_to,
})
.await;
}
PID_CHAT_HISTORY => {
let p: ChatHistoryPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::ChatHistory {
channel_id: p.channel_id,
messages: p
.messages
.into_iter()
.map(|m| ChatMsg {
message_id: m.message_id,
sender_id: m.sender_id,
content: m.content,
timestamp: m.timestamp,
reply_to: m.reply_to,
})
.collect(),
})
.await;
}
PID_USER_JOIN => {
let p: UserJoinPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::UserJoin {
channel_id: p.channel_id,
user_id: p.user_id,
nickname: p.nickname,
})
.await;
}
PID_USER_LEAVE => {
let p: UserLeavePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::UserLeave {
channel_id: p.channel_id,
user_id: p.user_id,
})
.await;
}
PID_PONG => {
let p: PongPayload = serde_json::from_slice(payload)?;
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as i64;
let rtt_ms = (now - p.timestamp).max(0) as u32;
let _ = tx.send(NetEvent::LatencyUpdate { rtt_ms }).await;
}
PID_READ_RECEIPT_BROADCAST => {
let p: serde_json::Value = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::ReadReceiptBroadcast {
channel_id: p["channel_id"].as_str().unwrap_or_default().into(),
user_id: p["user_id"].as_str().unwrap_or_default().into(),
last_read_message_id: p["last_read_message_id"]
.as_str()
.unwrap_or_default()
.into(),
})
.await;
}
PID_ERROR => {
let p: ErrorPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::Error {
code: p.code,
message: p.message,
})
.await;
}
PID_DISCONNECT => return Err(anyhow!("server disconnected")),
PID_TYPING_START => {
let p: serde_json::Value = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::TypingStart {
user_id: p["user_id"].as_str().unwrap_or_default().into(),
nickname: p["nickname"].as_str().unwrap_or_default().into(),
channel_id: p["channel_id"].as_str().unwrap_or_default().into(),
})
.await;
}
_ => {}
}
Ok(())
}