b453d5d
use models::chat::room_user_settings::{self, RoomNotificationLevel};
use sea_orm::{ActiveModelTrait, EntityTrait, Set};
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use utoipa::ToSchema;
use uuid::Uuid;
use crate::errors::ChatError;
use crate::services::service::ChatService;
use crate::share::lookup::require_room_readable;
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct RoomSettingDto {
pub room_id: Uuid,
pub notification_level: RoomNotificationLevel,
pub muted: bool,
pub mute_until: Option<OffsetDateTime>,
pub favorite: bool,
pub hidden: bool,
}
#[derive(Debug, Clone, Deserialize, ToSchema)]
pub struct UpdateRoomSettingCmd {
#[serde(default)]
pub notification_level: Option<RoomNotificationLevel>,
#[serde(default)]
pub muted: Option<bool>,
#[serde(default)]
pub mute_minutes: Option<i64>,
#[serde(default)]
pub favorite: Option<bool>,
#[serde(default)]
pub hidden: Option<bool>,
}
impl From<room_user_settings::Model> for RoomSettingDto {
fn from(s: room_user_settings::Model) -> Self {
Self {
room_id: s.room_id,
notification_level: s.notification_level,
muted: s.muted,
mute_until: s.mute_until,
favorite: s.favorite,
hidden: s.hidden,
}
}
}
impl ChatService {
pub async fn get_room_setting(
&self,
caller: i64,
room_id: Uuid,
) -> Result<RoomSettingDto, ChatError> {
let _ctx = require_room_readable(self, room_id, caller).await?;
let row = room_user_settings::Entity::find_by_id((caller, room_id))
.one(self.db().read())
.await?;
match row {
Some(row) => Ok(RoomSettingDto::from(row)),
None => Ok(RoomSettingDto {
room_id,
notification_level: RoomNotificationLevel::Default,
muted: false,
mute_until: None,
favorite: false,
hidden: false,
}),
}
}
pub async fn update_room_setting(
&self,
caller: i64,
room_id: Uuid,
cmd: UpdateRoomSettingCmd,
) -> Result<RoomSettingDto, ChatError> {
let _ctx = require_room_readable(self, room_id, caller).await?;
let now = OffsetDateTime::now_utc();
let existing = room_user_settings::Entity::find_by_id((caller, room_id))
.one(self.db().write())
.await?;
let mut am: room_user_settings::ActiveModel = match existing {
Some(row) => row.into(),
None => room_user_settings::ActiveModel {
user_id: Set(caller),
room_id: Set(room_id),
notification_level: Set(RoomNotificationLevel::Default),
muted: Set(false),
mute_until: Set(None),
favorite: Set(false),
hidden: Set(false),
updated_at: Set(now),
},
};
if let Some(level) = cmd.notification_level {
am.notification_level = Set(level);
}
if let Some(muted) = cmd.muted {
am.muted = Set(muted);
if !muted {
am.mute_until = Set(None);
}
}
if let Some(minutes) = cmd.mute_minutes {
am.mute_until = Set(if minutes > 0 {
Some(now + time::Duration::minutes(minutes))
} else {
None
});
am.muted = Set(minutes > 0);
}
if let Some(favorite) = cmd.favorite {
am.favorite = Set(favorite);
}
if let Some(hidden) = cmd.hidden {
am.hidden = Set(hidden);
}
am.updated_at = Set(now);
am.save(self.db().write()).await?;
let row = room_user_settings::Entity::find_by_id((caller, room_id))
.one(self.db().read())
.await?
.ok_or(ChatError::Internal("setting vanished".into()))?;
Ok(RoomSettingDto::from(row))
}
}