simplified and removed terminal stuff
This commit is contained in:
@@ -61,6 +61,7 @@ impl Hooks for App {
|
||||
.add_route(controllers::auth::routes())
|
||||
.add_route(controllers::admin::routes())
|
||||
.add_route(controllers::blog::routes())
|
||||
.add_route(controllers::i18n::routes())
|
||||
.add_route(controllers::media::routes())
|
||||
.add_route(controllers::pages::routes())
|
||||
.add_route(controllers::frontend::routes())
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
controllers::{admin, auth as auth_controller},
|
||||
controllers::{admin, auth as auth_controller, i18n::current_lang},
|
||||
models::{
|
||||
_entities::{blog_articles, site_pages},
|
||||
users::{self, LoginParams},
|
||||
@@ -122,7 +122,11 @@ async fn home(
|
||||
format::view(
|
||||
&v,
|
||||
"home/index.html",
|
||||
json!({ "articles": articles, "logged_in_admin": logged_in_admin(&ctx, &jar).await }),
|
||||
json!({
|
||||
"articles": articles,
|
||||
"logged_in_admin": logged_in_admin(&ctx, &jar).await,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -138,6 +142,7 @@ async fn about(
|
||||
json!({
|
||||
"page": about_page(&ctx).await?,
|
||||
"logged_in_admin": logged_in_admin(&ctx, &jar).await,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -157,7 +162,11 @@ async fn blog_index(
|
||||
format::view(
|
||||
&v,
|
||||
"blog/index.html",
|
||||
json!({ "articles": articles, "logged_in_admin": logged_in_admin(&ctx, &jar).await }),
|
||||
json!({
|
||||
"articles": articles,
|
||||
"logged_in_admin": logged_in_admin(&ctx, &jar).await,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -183,7 +192,11 @@ async fn blog_show(
|
||||
format::view(
|
||||
&v,
|
||||
"blog/show.html",
|
||||
json!({ "article": article, "logged_in_admin": logged_in_admin(&ctx, &jar).await }),
|
||||
json!({
|
||||
"article": article,
|
||||
"logged_in_admin": logged_in_admin(&ctx, &jar).await,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -200,12 +213,17 @@ async fn admin_login_page(
|
||||
format::view(
|
||||
&v,
|
||||
"admin/login.html",
|
||||
json!({ "error": null, "logged_in_admin": false }),
|
||||
json!({
|
||||
"error": null,
|
||||
"logged_in_admin": false,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn admin_login(
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
Form(params): Form<LoginParams>,
|
||||
@@ -214,7 +232,11 @@ async fn admin_login(
|
||||
return format::view(
|
||||
&v,
|
||||
"admin/login.html",
|
||||
json!({ "error": "Invalid credentials", "logged_in_admin": false }),
|
||||
json!({
|
||||
"error": "Invalid credentials",
|
||||
"logged_in_admin": false,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -222,7 +244,11 @@ async fn admin_login(
|
||||
return format::view(
|
||||
&v,
|
||||
"admin/login.html",
|
||||
json!({ "error": "Invalid credentials", "logged_in_admin": false }),
|
||||
json!({
|
||||
"error": "Invalid credentials",
|
||||
"logged_in_admin": false,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -246,21 +272,31 @@ async fn admin_logout() -> Result<Response> {
|
||||
#[debug_handler]
|
||||
async fn admin_home(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
let admin_user = admin::current_admin(auth, &ctx).await?;
|
||||
format::view(&v, "admin/index.html", json!({ "admin": admin_user }))
|
||||
format::view(
|
||||
&v,
|
||||
"admin/index.html",
|
||||
json!({ "admin": admin_user, "lang": current_lang(&jar) }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn admin_about(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
admin::current_admin(auth, &ctx).await?;
|
||||
format::view(&v, "admin/about.html", json!({ "page": about_page(&ctx).await? }))
|
||||
format::view(
|
||||
&v,
|
||||
"admin/about.html",
|
||||
json!({ "page": about_page(&ctx).await?, "lang": current_lang(&jar) }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
@@ -280,6 +316,7 @@ async fn admin_about_update(
|
||||
#[debug_handler]
|
||||
async fn admin_articles(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
@@ -288,17 +325,22 @@ async fn admin_articles(
|
||||
.order_by_desc(blog_articles::Column::CreatedAt)
|
||||
.all(&ctx.db)
|
||||
.await?;
|
||||
format::view(&v, "admin/blog/index.html", json!({ "articles": articles }))
|
||||
format::view(
|
||||
&v,
|
||||
"admin/blog/index.html",
|
||||
json!({ "articles": articles, "lang": current_lang(&jar) }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn admin_article_new(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
admin::current_admin(auth, &ctx).await?;
|
||||
format::view(&v, "admin/blog/new.html", json!({}))
|
||||
format::view(&v, "admin/blog/new.html", json!({ "lang": current_lang(&jar) }))
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
@@ -332,6 +374,7 @@ async fn admin_article_create(
|
||||
#[debug_handler]
|
||||
async fn admin_article_edit(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
Path(id): Path<Uuid>,
|
||||
State(ctx): State<AppContext>,
|
||||
@@ -340,7 +383,7 @@ async fn admin_article_edit(
|
||||
format::view(
|
||||
&v,
|
||||
"admin/blog/edit.html",
|
||||
json!({ "article": article_by_id(&ctx, id).await? }),
|
||||
json!({ "article": article_by_id(&ctx, id).await?, "lang": current_lang(&jar) }),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
60
src/controllers/i18n.rs
Normal file
60
src/controllers/i18n.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use axum::{
|
||||
http::{header, HeaderMap},
|
||||
response::Redirect,
|
||||
};
|
||||
use loco_rs::prelude::*;
|
||||
use serde::Deserialize;
|
||||
|
||||
pub const LANG_COOKIE: &str = "lang";
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct LangForm {
|
||||
pub lang: String,
|
||||
}
|
||||
|
||||
pub fn current_lang(jar: &axum_extra::extract::cookie::CookieJar) -> String {
|
||||
match jar.get(LANG_COOKIE).map(|cookie| cookie.value().to_string()) {
|
||||
Some(ref lang) if lang == "en" => "en".to_string(),
|
||||
_ => "sk".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn set_lang(headers: HeaderMap, Form(form): Form<LangForm>) -> Result<Response> {
|
||||
let lang = if form.lang == "en" { "en" } else { "sk" };
|
||||
let cookie = format!("{LANG_COOKIE}={lang}; Path=/; Max-Age=31536000; SameSite=Lax");
|
||||
|
||||
Ok((
|
||||
[(header::SET_COOKIE, cookie)],
|
||||
Redirect::to(&back_path(&headers)),
|
||||
)
|
||||
.into_response())
|
||||
}
|
||||
|
||||
fn back_path(headers: &HeaderMap) -> String {
|
||||
let raw = headers
|
||||
.get(header::REFERER)
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.unwrap_or("/");
|
||||
|
||||
if raw.starts_with('/') {
|
||||
return raw.to_string();
|
||||
}
|
||||
|
||||
if let Some(after_scheme) = raw.split_once("://").map(|(_, rest)| rest) {
|
||||
if let Some(path_start) = after_scheme.find('/') {
|
||||
let path = &after_scheme[path_start..];
|
||||
return if path.starts_with('/') {
|
||||
path.to_string()
|
||||
} else {
|
||||
"/".to_string()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
"/".to_string()
|
||||
}
|
||||
|
||||
pub fn routes() -> Routes {
|
||||
Routes::new().add("/lang", post(set_lang))
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
controllers::{admin, auth as auth_controller},
|
||||
controllers::{admin, auth as auth_controller, i18n::current_lang},
|
||||
models::{
|
||||
_entities::{audio_albums, audio_tracks},
|
||||
users,
|
||||
@@ -439,6 +439,7 @@ async fn image_upload(auth: auth::JWT, State(ctx): State<AppContext>, multipart:
|
||||
#[debug_handler]
|
||||
async fn admin_images(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
Query(query): Query<HashMap<String, String>>,
|
||||
State(ctx): State<AppContext>,
|
||||
@@ -451,6 +452,7 @@ async fn admin_images(
|
||||
json!({
|
||||
"uploaded": uploaded,
|
||||
"uploaded_url": uploaded.map(|filename| format!("/images/{filename}")),
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -507,7 +509,11 @@ async fn public_albums(
|
||||
format::view(
|
||||
&v,
|
||||
"audio/albums.html",
|
||||
json!({ "albums": albums, "logged_in_admin": logged_in_admin(&ctx, &jar).await }),
|
||||
json!({
|
||||
"albums": albums,
|
||||
"logged_in_admin": logged_in_admin(&ctx, &jar).await,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -544,6 +550,7 @@ async fn public_album(
|
||||
"album": album,
|
||||
"tracks": tracks,
|
||||
"logged_in_admin": logged_in_admin(&ctx, &jar).await,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -599,13 +606,18 @@ async fn public_tracks(
|
||||
format::view(
|
||||
&v,
|
||||
"audio/tracks.html",
|
||||
json!({ "tracks": tracks, "logged_in_admin": logged_in_admin(&ctx, &jar).await }),
|
||||
json!({
|
||||
"tracks": tracks,
|
||||
"logged_in_admin": logged_in_admin(&ctx, &jar).await,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn admin_albums(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
@@ -623,12 +635,17 @@ async fn admin_albums(
|
||||
rows.push(json!({ "album": album, "track_count": track_count }));
|
||||
}
|
||||
|
||||
format::view(&v, "admin/audio/albums.html", json!({ "albums": rows }))
|
||||
format::view(
|
||||
&v,
|
||||
"admin/audio/albums.html",
|
||||
json!({ "albums": rows, "lang": current_lang(&jar) }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn admin_tracks(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
@@ -638,18 +655,34 @@ async fn admin_tracks(
|
||||
.all(&ctx.db)
|
||||
.await?;
|
||||
|
||||
format::view(&v, "admin/audio/songs.html", json!({ "tracks": tracks }))
|
||||
format::view(
|
||||
&v,
|
||||
"admin/audio/songs.html",
|
||||
json!({ "tracks": tracks, "lang": current_lang(&jar) }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn admin_album_new(auth: auth::JWT, ViewEngine(v): ViewEngine<TeraView>, State(ctx): State<AppContext>) -> Result<Response> {
|
||||
async fn admin_album_new(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
admin::current_admin(auth, &ctx).await?;
|
||||
let available_tracks = audio_tracks::Entity::find()
|
||||
.filter(audio_tracks::Column::AlbumId.is_null())
|
||||
.order_by_asc(audio_tracks::Column::Title)
|
||||
.all(&ctx.db)
|
||||
.await?;
|
||||
format::view(&v, "admin/audio/new_album.html", json!({ "available_tracks": available_tracks }))
|
||||
format::view(
|
||||
&v,
|
||||
"admin/audio/new_album.html",
|
||||
json!({
|
||||
"available_tracks": available_tracks,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
@@ -713,6 +746,7 @@ async fn admin_album_create(
|
||||
#[debug_handler]
|
||||
async fn admin_album_tracks(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
Path(album_id): Path<Uuid>,
|
||||
State(ctx): State<AppContext>,
|
||||
@@ -734,7 +768,12 @@ async fn admin_album_tracks(
|
||||
format::view(
|
||||
&v,
|
||||
"admin/audio/tracks.html",
|
||||
json!({ "album": album, "tracks": tracks, "available_tracks": available_tracks }),
|
||||
json!({
|
||||
"album": album,
|
||||
"tracks": tracks,
|
||||
"available_tracks": available_tracks,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -784,6 +823,7 @@ async fn admin_track_remove_from_album(
|
||||
#[debug_handler]
|
||||
async fn admin_track_upload_form(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
Path(album_id): Path<Uuid>,
|
||||
State(ctx): State<AppContext>,
|
||||
@@ -792,18 +832,23 @@ async fn admin_track_upload_form(
|
||||
format::view(
|
||||
&v,
|
||||
"admin/audio/upload_track.html",
|
||||
json!({ "album": album_by_id(&ctx, album_id).await? }),
|
||||
json!({ "album": album_by_id(&ctx, album_id).await?, "lang": current_lang(&jar) }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn admin_song_upload_form(
|
||||
auth: auth::JWT,
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
admin::current_admin(auth, &ctx).await?;
|
||||
format::view(&v, "admin/audio/upload_track.html", json!({ "album": null }))
|
||||
format::view(
|
||||
&v,
|
||||
"admin/audio/upload_track.html",
|
||||
json!({ "album": null, "lang": current_lang(&jar) }),
|
||||
)
|
||||
}
|
||||
|
||||
async fn create_uploaded_track(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod admin;
|
||||
pub mod auth;
|
||||
pub mod blog;
|
||||
pub mod i18n;
|
||||
pub mod frontend;
|
||||
pub mod media;
|
||||
pub mod pages;
|
||||
|
||||
@@ -25,7 +25,7 @@ impl Initializer for ViewEngineInitializer {
|
||||
async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
|
||||
let tera_engine = if std::path::Path::new(I18N_DIR).exists() {
|
||||
let arc = std::sync::Arc::new(
|
||||
ArcLoader::builder(&I18N_DIR, unic_langid::langid!("en-US"))
|
||||
ArcLoader::builder(&I18N_DIR, unic_langid::langid!("sk"))
|
||||
.shared_resources(Some(&[I18N_SHARED.into()]))
|
||||
.customize(|bundle| bundle.set_use_isolating(false))
|
||||
.build()
|
||||
|
||||
Reference in New Issue
Block a user