i18n+filtering fork - fluent-templates v2
at main 89 lines 2.4 kB view raw
1use anyhow::Result; 2use axum::{ 3 extract::State, 4 response::{IntoResponse, Redirect}, 5}; 6use axum_extra::extract::{ 7 cookie::{Cookie, CookieJar, SameSite}, 8 Cached, Form, 9}; 10use minijinja::context as template_context; 11use serde::Deserialize; 12use std::{borrow::Cow, str::FromStr}; 13use unic_langid::LanguageIdentifier; 14 15use crate::storage::handle::{handle_update_field, HandleField}; 16 17use super::{ 18 context::WebContext, errors::WebError, middleware_auth::Auth, middleware_i18n::COOKIE_LANG, 19 templates::render_alert, 20}; 21 22#[derive(Deserialize, Clone)] 23pub struct LanguageForm { 24 language: String, 25} 26 27#[tracing::instrument(skip_all, err)] 28pub async fn handle_set_language( 29 State(web_context): State<WebContext>, 30 Cached(auth): Cached<Auth>, 31 jar: CookieJar, 32 Form(language_form): Form<LanguageForm>, 33) -> Result<impl IntoResponse, WebError> { 34 let default_context = template_context! { 35 current_handle => auth.0, 36 canonical_url => format!("https://{}/language", web_context.config.external_base), 37 }; 38 39 let use_language = LanguageIdentifier::from_str(&language_form.language); 40 if use_language.is_err() { 41 return Ok(render_alert( 42 web_context.engine.clone(), 43 "en-us", 44 "Invalid language", 45 default_context, 46 ) 47 .into_response()); 48 } 49 50 let use_language = use_language.unwrap(); 51 52 let found = web_context 53 .i18n_context 54 .supported_languages 55 .iter() 56 .find(|lang| lang.matches(&use_language, true, false)); 57 if found.is_none() { 58 return Ok(render_alert( 59 web_context.engine.clone(), 60 "en-us", 61 "Invalid language", 62 default_context, 63 ) 64 .into_response()); 65 } 66 let found = found.unwrap(); 67 68 if let Some(handle) = auth.0 { 69 if let Err(err) = handle_update_field( 70 &web_context.pool, 71 &handle.did, 72 HandleField::Language(Cow::Owned(found.to_string())), 73 ) 74 .await 75 { 76 tracing::error!(error = ?err, "Failed to update language"); 77 } 78 } 79 80 let mut cookie = Cookie::new(COOKIE_LANG, found.to_string()); 81 cookie.set_path("/"); 82 cookie.set_http_only(true); 83 cookie.set_secure(true); 84 cookie.set_same_site(Some(SameSite::Lax)); 85 86 let updated_jar = jar.add(cookie); 87 88 Ok((updated_jar, Redirect::to("/")).into_response()) 89}