simplified and removed terminal stuff

This commit is contained in:
Priec
2026-05-19 20:03:20 +02:00
parent 98a1c69582
commit c1db8358c4
20 changed files with 527 additions and 182 deletions

View File

@@ -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())

View File

@@ -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
View 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))
}

View File

@@ -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(

View File

@@ -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;

View File

@@ -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()