mini-player: wip

This commit is contained in:
Agahnim 2026-03-19 19:17:53 +01:00
parent db3c7657a3
commit 4611980c23
Signed by: Agahnim
SSH key fingerprint: SHA256:Zj65PJnE0dRYye8Ltk/qDglynyXUxJngQ9qqx/VI+b4
13 changed files with 217 additions and 3 deletions

3
Cargo.lock generated
View file

@ -8,6 +8,8 @@ version = "0.1.0"
dependencies = [ dependencies = [
"askama", "askama",
"axum", "axum",
"serde",
"serde_json",
"tokio", "tokio",
"tower-http", "tower-http",
"tower-livereload", "tower-livereload",
@ -460,6 +462,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [ dependencies = [
"serde_core", "serde_core",
"serde_derive",
] ]
[[package]] [[package]]

View file

@ -6,6 +6,8 @@ edition = "2024"
[dependencies] [dependencies]
askama = { version = "0.15.4", features = ["std", "derive"] } askama = { version = "0.15.4", features = ["std", "derive"] }
axum = "0.8.8" axum = "0.8.8"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
tokio = { version = "1.50.0", features = ["full"] } tokio = { version = "1.50.0", features = ["full"] }
tower-http = { version = "0.6.8", features = ["fs"] } tower-http = { version = "0.6.8", features = ["fs"] }
tower-livereload = "0.10.3" tower-livereload = "0.10.3"

38
content/mp-tracks.json Normal file
View file

@ -0,0 +1,38 @@
[
{
"id": 1,
"title": "Good old times",
"artist": "Agahnim",
"src": "/static/music/times.mp3"
},
{
"id": 2,
"title": "Identification",
"artist": "Infinity Frequencies",
"src": "/static/music/infinity.mp3"
},
{
"id": 3,
"title": "Flip the Switch",
"artist": "Stevia Sphere",
"src": "/static/music/switch.mp3"
},
{
"id": 4,
"title": "Machines Vs Water",
"artist": "Stevia Sphere",
"src": "/static/music/machines.mp3"
},
{
"id": 5,
"title": "Elevator 1",
"artist": "Stevia Sphere",
"src": "/static/music/elevator.mp3"
},
{
"id": 6,
"title": "Somewhere Dark",
"artist": "Monodrone",
"src": "/static/music/dark.mp3"
}
]

72
content/p-tracks.json Normal file
View file

@ -0,0 +1,72 @@
[
{
"id": 1,
"title": "I'm getting tired of farewells",
"artist": "Agahnim",
"src": "/static/music/farewells.mp3",
"album": "LIFE"
},
{
"id": 2,
"title": "DAWN",
"artist": "Agahnim",
"src": "/static/music/DAWN.mp3",
"album": "DAWN"
},
{
"id": 3,
"title": "Move on",
"artist": "Agahnim",
"src": "/static/music/move_on.mp3",
"album": "DAWN"
},
{
"id": 4,
"title": "Carcer",
"artist": "Agahnim",
"src": "/static/music/carcer.mp3",
"album": "LIFE"
},
{
"id": 5,
"title": "Under listening",
"artist": "Agahnim",
"src": "/static/music/listening.mp3",
"album": "Justice"
},
{
"id": 6,
"title": "Fading away",
"artist": "Agahnim",
"src": "/static/music/fading.mp3",
"album": "LIFE"
},
{
"id": 7,
"title": "Hindsight",
"artist": "Agahnim",
"src": "/static/music/hindsight.mp3",
"album": "The End"
},
{
"id": 8,
"title": "With or without",
"artist": "Agahnim",
"src": "/static/music/without.mp3",
"album": "Extinction"
},
{
"id": 9,
"title": "Perfect Light",
"artist": "Agahnim",
"src": "/static/music/perfect_light.mp3",
"album": "Rebirth"
},
{
"id": 10,
"title": "Good old times",
"artist": "Agahnim",
"src": "/static/music/times.mp3",
"album": "Extinction"
}
]

30
src/domain.rs Normal file
View file

@ -0,0 +1,30 @@
use serde::Deserialize;
pub struct AppState {
pub mp_tracks: Vec<Track>,
pub p_tracks: Vec<Track>,
}
impl AppState {
pub async fn try_new() -> Self {
Self {
mp_tracks: serde_json::from_str(
&std::fs::read_to_string("content/mp-tracks.json")
.expect("mp-tracks.json non trouvé"),
)
.expect("JSON invalide"),
p_tracks: serde_json::from_str(
&std::fs::read_to_string("content/p-tracks.json")
.expect("p-tracks.json non trouvé"),
)
.expect("JSON invalide"),
}
}
}
#[derive(Deserialize, Clone)]
pub struct Track {
title: String,
artist: String,
src: String,
}

View file

@ -1 +1,2 @@
pub mod domain;
pub mod templates; pub mod templates;

View file

@ -1,4 +1,9 @@
use agahnim_web_v2::templates::{index::home, notfound::notfound}; use std::sync::Arc;
use agahnim_web_v2::{
domain::AppState,
templates::{index::home, miniplayer::miniplayer, notfound::notfound},
};
use axum::{Router, routing::get}; use axum::{Router, routing::get};
use tower_http::services::ServeDir; use tower_http::services::ServeDir;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
@ -6,10 +11,14 @@ use tower_livereload::LiveReloadLayer;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let state = Arc::new(AppState::try_new().await);
let app = Router::new() let app = Router::new()
.route("/", get(home)) .route("/", get(home))
.route("/miniplayer", get(miniplayer))
.nest_service("/static", ServeDir::new("static")) .nest_service("/static", ServeDir::new("static"))
.fallback(notfound); .fallback(notfound)
.with_state(state);
// We need to include this flag so that the live reload layer isn't included when the server is built // We need to include this flag so that the live reload layer isn't included when the server is built
#[cfg(debug_assertions)] #[cfg(debug_assertions)]

21
src/state.rs Normal file
View file

@ -0,0 +1,21 @@
pub struct AppState {
mp_tracks: Vec<Track>,
p_tracks: Vec<Track>,
}
impl AppState {
async fn try_new() -> Self {
Self {
mp_tracks: serde_json::from_str(
&std::fs::read_to_string("content/mp-tracks.json")
.expect("mp-tracks.json non trouvé"),
)
.expect("JSON invalide"),
p_tracks: serde_json::from_str(
&std::fs::read_to_string("content/p-tracks.json")
.expect("p-tracks.json non trouvé"),
)
.expect("JSON invalide"),
}
}
}

View file

@ -0,0 +1,24 @@
use std::sync::Arc;
use askama::Template;
use axum::{
extract::State,
response::{Html, IntoResponse},
};
use crate::domain::{AppState, Track};
#[derive(Template)]
#[template(path = "partials/miniplayer.html")]
struct MiniPlayerTemplate {
tracks: Vec<Track>,
}
pub async fn miniplayer(State(state): State<Arc<AppState>>) -> impl IntoResponse {
Html(
MiniPlayerTemplate {
tracks: state.mp_tracks.clone(),
}
.render()
.unwrap(),
)
}

View file

@ -1,2 +1,3 @@
pub mod index; pub mod index;
pub mod miniplayer;
pub mod notfound; pub mod notfound;

View file

@ -101,3 +101,13 @@ katcenkat {
} }
} }
} }
/* Mini player */
miniplayer {
position: fixed;
top: 4rem;
left: 1rem;
z-index: 100;
}

View file

@ -12,7 +12,7 @@
<body hx-boost="true" hx-target="#content"> <body hx-boost="true" hx-target="#content">
{% include "partials/header.html" %} {% include "partials/header.html" %}
<div hx-get="/miniplayer" hx-trigger="load" hx-swap="innerHtml"></div>
<main id="content"> <main id="content">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</main> </main>

View file

@ -0,0 +1,3 @@
<miniplayer>
<h1>Salut</h1>
</miniplayer>