mini-player: wip
This commit is contained in:
parent
c4c49dee6b
commit
8b0de4bf93
13 changed files with 217 additions and 3 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
|
@ -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]]
|
||||||
|
|
|
||||||
|
|
@ -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
38
content/mp-tracks.json
Normal 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
72
content/p-tracks.json
Normal 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
30
src/domain.rs
Normal 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,
|
||||||
|
}
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
pub mod domain;
|
||||||
pub mod templates;
|
pub mod templates;
|
||||||
|
|
|
||||||
13
src/main.rs
13
src/main.rs
|
|
@ -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
21
src/state.rs
Normal 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"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/templates/miniplayer.rs
Normal file
24
src/templates/miniplayer.rs
Normal 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(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
pub mod index;
|
pub mod index;
|
||||||
|
pub mod miniplayer;
|
||||||
pub mod notfound;
|
pub mod notfound;
|
||||||
|
|
|
||||||
|
|
@ -100,4 +100,14 @@ katcenkat {
|
||||||
transform: translateY(500px);
|
transform: translateY(500px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Mini player */
|
||||||
|
miniplayer {
|
||||||
|
position: fixed;
|
||||||
|
top: 4rem;
|
||||||
|
left: 1rem;
|
||||||
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
3
templates/partials/miniplayer.html
Normal file
3
templates/partials/miniplayer.html
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<miniplayer>
|
||||||
|
<h1>Salut</h1>
|
||||||
|
</miniplayer>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue