use chrono::Utc; use uuid::Uuid; use crate::event::{RoomInfo, UserInfo, member, presence}; use crate::{ChannelBus, ChannelResult}; use super::WsHandler; use super::WsOutEvent; impl WsHandler { pub(super) async fn dnd_update( bus: &ChannelBus, user_id: Uuid, room: Uuid, do_not_disturb: Option, dnd_start_hour: Option, dnd_end_hour: Option, ) -> ChannelResult> { Self::ensure_room_access(bus, user_id, room).await?; let do_not_disturb = do_not_disturb.unwrap_or(false); let start_hour = dnd_start_hour.map(|h| h as i32); let end_hour = dnd_end_hour.map(|h| h as i32); let key = format!("dnd:{}:{}", user_id, room); let dnd_data = serde_json::json!({ "do_not_disturb": do_not_disturb, "dnd_start_hour": start_hour, "dnd_end_hour": end_hour, }); bus.inner.cache.set(&key, &dnd_data).await?; let dnd_room = bus .lookup_room(room) .await .unwrap_or_else(|_| RoomInfo::unknown(room)); let dnd_user = bus .lookup_user(user_id) .await .unwrap_or_else(|_| UserInfo::unknown(user_id)); let data = member::DndUpdatedService { room: dnd_room, user: dnd_user, do_not_disturb, dnd_start_hour: start_hour, dnd_end_hour: end_hour, }; bus.publish_room_event(room, "member.dnd_updated", &data) .await?; Ok(None) } pub(super) async fn presence_update( bus: &ChannelBus, user_id: Uuid, status: presence::UserPresenceStatus, ) -> ChannelResult> { let pc_user = bus .lookup_user(user_id) .await .unwrap_or_else(|_| UserInfo::unknown(user_id)); let data = presence::PresenceChangedService { user: pc_user, project: None, status, last_seen_at: Some(Utc::now()), }; let rooms = crate::rooms::user_rooms( &bus.inner.db, &bus.inner.cache, &bus.inner.config, user_id, ) .await?; for room in rooms { bus.publish_room_event(room, "presence.changed", &data) .await?; } Ok(Some(WsOutEvent::PresenceChanged { data })) } pub(super) async fn custom_status_update( bus: &ChannelBus, user_id: Uuid, emoji: Option, text: Option, expires_at: Option>, ) -> ChannelResult> { let cs_user = bus .lookup_user(user_id) .await .unwrap_or_else(|_| UserInfo::unknown(user_id)); let data = presence::CustomStatusUpdatedService { user: cs_user, emoji, text, expires_at, }; let rooms = crate::rooms::user_rooms( &bus.inner.db, &bus.inner.cache, &bus.inner.config, user_id, ) .await?; for room in rooms { bus.publish_room_event(room, "custom_status.updated", &data) .await?; } Ok(Some(WsOutEvent::CustomStatusUpdated { data })) } }