111 lines
3.8 KiB
Rust
111 lines
3.8 KiB
Rust
use db::sqlx;
|
|
use model::users::UserAppearanceModel;
|
|
use serde::{Deserialize, Serialize};
|
|
use session::Session;
|
|
|
|
use crate::{AppService, error::AppError, session_user};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
|
|
pub struct UserAppearanceConfig {
|
|
pub theme: String,
|
|
pub code_theme: String,
|
|
pub layout_density: String,
|
|
pub sidebar_collapsed: bool,
|
|
pub show_line_numbers: bool,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, utoipa::ToSchema)]
|
|
pub struct UpdateUserAppearanceConfig {
|
|
pub theme: Option<String>,
|
|
pub code_theme: Option<String>,
|
|
pub layout_density: Option<String>,
|
|
pub sidebar_collapsed: Option<bool>,
|
|
pub show_line_numbers: Option<bool>,
|
|
}
|
|
|
|
impl AppService {
|
|
pub async fn user_update_appearance_config(
|
|
&self,
|
|
ctx: &Session,
|
|
params: UpdateUserAppearanceConfig,
|
|
) -> Result<UserAppearanceConfig, AppError> {
|
|
let user_uid = session_user(ctx)?;
|
|
let mut config = self.user_appearance_config(user_uid).await?;
|
|
if let Some(theme) = params.theme {
|
|
config.theme = theme;
|
|
}
|
|
if let Some(code_theme) = params.code_theme {
|
|
config.code_theme = code_theme;
|
|
}
|
|
if let Some(layout_density) = params.layout_density {
|
|
config.layout_density = layout_density;
|
|
}
|
|
if let Some(sidebar_collapsed) = params.sidebar_collapsed {
|
|
config.sidebar_collapsed = sidebar_collapsed;
|
|
}
|
|
if let Some(show_line_numbers) = params.show_line_numbers {
|
|
config.show_line_numbers = show_line_numbers;
|
|
}
|
|
let now = chrono::Utc::now();
|
|
sqlx::query(
|
|
"INSERT INTO user_appearance \
|
|
(\"user\", theme, code_theme, layout_density, sidebar_collapsed, show_line_numbers, created_at, updated_at) \
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $7) \
|
|
ON CONFLICT (\"user\") DO UPDATE SET \
|
|
theme = EXCLUDED.theme, code_theme = EXCLUDED.code_theme, layout_density = EXCLUDED.layout_density, \
|
|
sidebar_collapsed = EXCLUDED.sidebar_collapsed, show_line_numbers = EXCLUDED.show_line_numbers, \
|
|
updated_at = EXCLUDED.updated_at",
|
|
)
|
|
.bind(user_uid)
|
|
.bind(&config.theme)
|
|
.bind(&config.code_theme)
|
|
.bind(&config.layout_density)
|
|
.bind(config.sidebar_collapsed)
|
|
.bind(config.show_line_numbers)
|
|
.bind(now)
|
|
.execute(self.db.writer())
|
|
.await
|
|
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
|
|
Ok(config)
|
|
}
|
|
|
|
pub async fn user_appearance_config(
|
|
&self,
|
|
user_uid: uuid::Uuid,
|
|
) -> Result<UserAppearanceConfig, AppError> {
|
|
let row = sqlx::query_as::<_, UserAppearanceModel>(
|
|
"SELECT \"user\", theme, code_theme, layout_density, sidebar_collapsed, show_line_numbers, created_at, updated_at \
|
|
FROM user_appearance WHERE \"user\" = $1",
|
|
)
|
|
.bind(user_uid)
|
|
.fetch_optional(self.db.reader())
|
|
.await
|
|
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
|
|
Ok(row.map(Into::into).unwrap_or_default())
|
|
}
|
|
}
|
|
|
|
impl Default for UserAppearanceConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
theme: "system".to_string(),
|
|
code_theme: "github-dark".to_string(),
|
|
layout_density: "comfortable".to_string(),
|
|
sidebar_collapsed: false,
|
|
show_line_numbers: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<UserAppearanceModel> for UserAppearanceConfig {
|
|
fn from(value: UserAppearanceModel) -> Self {
|
|
Self {
|
|
theme: value.theme,
|
|
code_theme: value.code_theme,
|
|
layout_density: value.layout_density,
|
|
sidebar_collapsed: value.sidebar_collapsed,
|
|
show_line_numbers: value.show_line_numbers,
|
|
}
|
|
}
|
|
}
|