gitdataai/lib/channel/http/handler/presence.rs
2026-05-30 01:38:40 +08:00

95 lines
3.1 KiB
Rust

use chrono::Utc;
use uuid::Uuid;
use crate::event::{RoomInfo, UserInfo, member, presence};
use crate::{ChannelBus, ChannelResult};
use super::WsOutEvent;
use super::WsHandler;
impl WsHandler {
pub(super) async fn dnd_update(
bus: &ChannelBus,
user_id: Uuid,
room: Uuid,
do_not_disturb: Option<bool>,
dnd_start_hour: Option<i16>,
dnd_end_hour: Option<i16>,
) -> ChannelResult<Option<WsOutEvent>> {
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<Option<WsOutEvent>> {
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<String>,
text: Option<String>,
expires_at: Option<chrono::DateTime<chrono::Utc>>,
) -> ChannelResult<Option<WsOutEvent>> {
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 }))
}
}