a06673b
use db::conn::sea_orm::{ActiveModelTrait, ConnectionTrait, EntityTrait, Set};
use time::OffsetDateTime;
use uuid::Uuid;
use crate::error::{UserError, UserResult};
use crate::features::UserService;
use super::types::{UpdatePreferencesCmd, UserPreferences};
pub async fn get_or_create(
svc: &UserService,
user_id: Uuid,
) -> UserResult<UserPreferences> {
let db = svc.db.reader();
let pref = db::user::user_preferences::Entity::find_by_id(user_id)
.one(&db)
.await?;
if let Some(m) = pref {
return Ok(UserPreferences::from(m));
}
let writer = svc.db.writer();
let active: db::user::user_preferences::ActiveModel =
db::user::user_preferences::ActiveModel::builder()
.set_user_id(user_id)
.set_theme_mode(String::from("system"))
.set_created_at(OffsetDateTime::now_utc())
.set_updated_at(OffsetDateTime::now_utc())
.into();
let inserted = active.insert(&writer).await?;
Ok(UserPreferences::from(inserted))
}
pub async fn update(
svc: &UserService,
user_id: Uuid,
cmd: UpdatePreferencesCmd,
) -> UserResult<UserPreferences> {
if let Some(ref mode) = cmd.theme_mode
&& (mode.is_empty() || mode.len() > 32) {
return Err(UserError::BadRequest(
"theme_mode length must be 1..=32".into(),
));
}
let writer = svc.db.writer();
let existing = db::user::user_preferences::Entity::find_by_id(user_id)
.one(&writer)
.await?;
let now = OffsetDateTime::now_utc();
let existing_present = existing.is_some();
let mut active: db::user::user_preferences::ActiveModel = match existing {
Some(m) => m.into(),
None => db::user::user_preferences::ActiveModel::builder()
.set_user_id(user_id)
.set_theme_mode(String::from("system"))
.set_created_at(now)
.set_updated_at(now)
.into(),
};
if let Some(v) = cmd.theme_mode {
active.theme_mode = Set(v);
}
if let Some(v) = cmd.theme_token {
active.theme_token = Set(v);
}
if let Some(v) = cmd.theme_version {
active.theme_version = Set(v);
}
if let Some(v) = cmd.diff_view_style {
active.diff_view_style = Set(v);
}
if let Some(v) = cmd.in_app_flags {
active.in_app_flags = Set(v);
}
if let Some(v) = cmd.email_flags {
active.email_flags = Set(v);
}
if let Some(v) = cmd.push_flags {
active.push_flags = Set(v);
}
if let Some(v) = cmd.email_digest {
active.email_digest = Set(v);
}
if let Some(v) = cmd.mute_until {
if let Some(ts) = v {
let parsed = OffsetDateTime::parse(
&ts,
&time::format_description::well_known::Rfc3339,
)
.map_err(|e| UserError::BadRequest(format!("invalid mute_until: {e}")))?;
active.mute_until = Set(Some(parsed));
} else {
active.mute_until = Set(None);
}
}
if let Some(v) = cmd.allow_dms_from {
active.allow_dms_from = Set(v.into());
}
if let Some(v) = cmd.allow_mentions_from {
active.allow_mentions_from = Set(v.into());
}
if let Some(v) = cmd.show_online_status {
active.show_online_status = Set(v);
}
active.updated_at = Set(now);
let saved = if existing_present {
active.update(&writer).await?
} else {
active.insert(&writer).await?
};
Ok(UserPreferences::from(saved))
}
#[allow(dead_code)]
fn _connection_bound<C: ConnectionTrait>(_: &C) {}