134 lines
5.1 KiB
Rust
134 lines
5.1 KiB
Rust
use models::RoomId;
|
|
use queue::{ReactionGroup, RoomMessageEvent, RoomMessageStreamChunkEvent, TypingEvent};
|
|
use room::types::NotificationEvent;
|
|
|
|
use super::types::WsOutEvent;
|
|
use crate::event::{member, message, notify, reaction};
|
|
|
|
pub struct EventDispatcher;
|
|
|
|
impl EventDispatcher {
|
|
pub fn dispatch_message(event: &RoomMessageEvent) -> WsOutEvent {
|
|
WsOutEvent::MessageNew {
|
|
room_id: event.room_id,
|
|
data: message::MessageNewService {
|
|
id: event.id,
|
|
seq: event.seq,
|
|
room: event.room_id,
|
|
sender_type: event.sender_type.clone(),
|
|
sender_id: event.sender_id,
|
|
display_name: event.display_name.clone(),
|
|
thread: event.thread_id,
|
|
in_reply_to: event.in_reply_to,
|
|
content: event.content.clone(),
|
|
content_type: event.content_type.clone(),
|
|
thinking_content: event.thinking_content.clone(),
|
|
thinking_is_chunked: false,
|
|
send_at: event.send_at,
|
|
reactions: None,
|
|
},
|
|
}
|
|
}
|
|
|
|
/// Dispatch MessageStreamStart — WS only sends message_id + SSE URL.
|
|
/// Full chunk content is delivered via dedicated SSE endpoint.
|
|
pub fn dispatch_stream_start(event: &RoomMessageStreamChunkEvent) -> WsOutEvent {
|
|
WsOutEvent::MessageStreamStart {
|
|
room_id: event.room_id,
|
|
data: message::MessageStreamStartService {
|
|
message_id: event.message_id,
|
|
room: event.room_id,
|
|
sse_url: format!("/ws/ai-stream/{}/{}", event.room_id, event.message_id),
|
|
display_name: event.display_name.clone(),
|
|
},
|
|
}
|
|
}
|
|
|
|
/// Dispatch MessageStreamDone — WS notifies client that SSE stream ended.
|
|
pub fn dispatch_stream_done(event: &RoomMessageStreamChunkEvent) -> WsOutEvent {
|
|
WsOutEvent::MessageStreamDone {
|
|
room_id: event.room_id,
|
|
data: message::MessageStreamDoneService {
|
|
message_id: event.message_id,
|
|
room: event.room_id,
|
|
content: event.content.clone(),
|
|
thinking_content: None,
|
|
display_name: event.display_name.clone(),
|
|
error: event.error.clone(),
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn dispatch_typing(event: &TypingEvent) -> WsOutEvent {
|
|
match event.action.as_str() {
|
|
"start" => WsOutEvent::TypingStart {
|
|
room_id: event.room_id,
|
|
data: member::TypingStartService {
|
|
room: event.room_id,
|
|
user: event.user_id,
|
|
username: event.username.clone(),
|
|
avatar_url: event.avatar_url.clone(),
|
|
sender_type: event.sender_type.clone(),
|
|
},
|
|
},
|
|
_ => WsOutEvent::TypingStop {
|
|
room_id: event.room_id,
|
|
data: member::TypingStopService {
|
|
room: event.room_id,
|
|
user: event.user_id,
|
|
username: event.username.clone(),
|
|
avatar_url: event.avatar_url.clone(),
|
|
sender_type: event.sender_type.clone(),
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn dispatch_notification(event: &NotificationEvent) -> WsOutEvent {
|
|
WsOutEvent::NotifyCreated {
|
|
data: notify::NotifyCreatedService {
|
|
id: event.notification.id,
|
|
room: event.notification.room,
|
|
project: event.notification.project,
|
|
user_id: event.notification.user_id,
|
|
notification_type: event.event_type.clone(),
|
|
title: event.notification.title.clone(),
|
|
content: event.notification.content.clone(),
|
|
related_message_id: event.notification.related_message_id,
|
|
related_user_id: event.notification.related_user_id,
|
|
related_room_id: event.notification.related_room_id,
|
|
metadata: event.notification.metadata.clone(),
|
|
created_at: event.timestamp,
|
|
deep_link_url: event.deep_link_url.clone(),
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn dispatch_reactions(
|
|
room_id: RoomId,
|
|
message_id: uuid::Uuid,
|
|
reactions: &[ReactionGroup],
|
|
) -> WsOutEvent {
|
|
WsOutEvent::ReactionBatchUpdated {
|
|
room_id,
|
|
data: reaction::ReactionBatchUpdatedService {
|
|
room: room_id,
|
|
message: message_id,
|
|
reactions: reactions
|
|
.iter()
|
|
.map(|g| reaction::ReactionGroup {
|
|
emoji: g.emoji.clone(),
|
|
count: g.count as i64,
|
|
reacted_by_me: g.reacted_by_me,
|
|
users: g
|
|
.users
|
|
.iter()
|
|
.filter_map(|u| u.parse::<uuid::Uuid>().ok())
|
|
.collect(),
|
|
})
|
|
.collect(),
|
|
},
|
|
}
|
|
}
|
|
}
|