Add a toggle between dark and light theme

This commit is contained in:
Greg Burri 2025-03-31 15:31:06 +02:00
parent d22617538e
commit 559ed139aa
34 changed files with 640 additions and 469 deletions

View file

@ -85,6 +85,13 @@ const TRACING_LEVEL: tracing::Level = tracing::Level::DEBUG;
#[cfg(not(debug_assertions))]
const TRACING_LEVEL: tracing::Level = tracing::Level::INFO;
#[derive(Debug, Clone)]
pub struct Context {
pub user: Option<model::User>,
pub tr: Tr,
pub dark_theme: bool,
}
// TODO: Should main returns 'Result'?
#[tokio::main]
async fn main() {
@ -294,11 +301,7 @@ async fn main() {
.merge(html_routes)
.nest("/ron-api", ron_api_routes)
.fallback(services::not_found)
.layer(middleware::from_fn(translation))
.layer(middleware::from_fn_with_state(
state.clone(),
user_authentication,
))
.layer(middleware::from_fn_with_state(state.clone(), context))
.with_state(state)
.nest_service("/favicon.ico", ServeFile::new("static/favicon.ico"))
.nest_service("/static", ServeDir::new("static"))
@ -321,19 +324,6 @@ async fn main() {
event!(Level::INFO, "Recipes stopped");
}
async fn user_authentication(
ConnectInfo(addr): ConnectInfo<SocketAddr>,
State(connection): State<db::Connection>,
mut req: Request,
next: Next,
) -> Result<Response> {
let jar = CookieJar::from_headers(req.headers());
let (client_ip, client_user_agent) = utils::get_ip_and_user_agent(req.headers(), addr);
let user = get_current_user(connection, &jar, &client_ip, &client_user_agent).await;
req.extensions_mut().insert(user);
Ok(next.run(req).await)
}
#[derive(Debug, Clone)]
struct Lang(Option<String>);
@ -384,16 +374,21 @@ fn url_rewriting(mut req: Request) -> Request {
/// - Get from the cookie.
/// - Get from the HTTP header `accept-language`.
/// - Set as `translation::DEFAULT_LANGUAGE_CODE`.
async fn translation(
Extension(lang): Extension<Lang>,
Extension(user): Extension<Option<model::User>>,
async fn context(
ConnectInfo(addr): ConnectInfo<SocketAddr>,
State(connection): State<db::Connection>,
Extension(lang_from_url): Extension<Lang>,
mut req: Request,
next: Next,
) -> Result<Response> {
let language = if let Some(lang) = lang.0 {
let jar = CookieJar::from_headers(req.headers());
let (client_ip, client_user_agent) = utils::get_ip_and_user_agent(req.headers(), addr);
let user = get_current_user(connection, &jar, &client_ip, &client_user_agent).await;
let language = if let Some(lang) = lang_from_url.0 {
lang
} else if let Some(user) = user {
user.lang
} else if let Some(ref user) = user {
user.lang.clone()
} else {
let available_codes = translation::available_codes();
let jar = CookieJar::from_headers(req.headers());
@ -420,7 +415,17 @@ async fn translation(
let tr = Tr::new(&language);
req.extensions_mut().insert(tr);
let dark_theme = match jar.get(common::consts::COOKIE_DARK_THEME) {
Some(dark_theme_cookie) => dark_theme_cookie.value().parse().unwrap_or_default(),
None => false,
};
req.extensions_mut().insert(Context {
user,
tr,
dark_theme,
});
Ok(next.run(req).await)
}