mini-player, header: make it persistent, add music page button and check current route
This commit is contained in:
parent
4b4044d689
commit
2ed650c3f4
11 changed files with 78 additions and 52 deletions
|
|
@ -2,7 +2,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use agahnim_web_v2::{
|
use agahnim_web_v2::{
|
||||||
domain::AppState,
|
domain::AppState,
|
||||||
templates::{home::home, miniplayer::miniplayer, music::music, notfound::notfound},
|
templates::{home::home, music::music, notfound::notfound},
|
||||||
};
|
};
|
||||||
use axum::{Router, routing::get};
|
use axum::{Router, routing::get};
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
|
|
@ -16,7 +16,6 @@ async fn main() {
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(home))
|
.route("/", get(home))
|
||||||
.route("/music", get(music))
|
.route("/music", get(music))
|
||||||
.route("/miniplayer", get(miniplayer))
|
|
||||||
.nest_service("/static", ServeDir::new("static"))
|
.nest_service("/static", ServeDir::new("static"))
|
||||||
.fallback(notfound)
|
.fallback(notfound)
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,33 @@
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use axum::{
|
use axum::{
|
||||||
|
extract::State,
|
||||||
http::HeaderMap,
|
http::HeaderMap,
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
};
|
};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::domain::AppState;
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "home.html")]
|
#[template(path = "home.html")]
|
||||||
struct HomeTemplate;
|
struct HomeTemplate {
|
||||||
|
tracks: Vec<crate::domain::Track>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "partials/home.html")]
|
#[template(path = "partials/home.html")]
|
||||||
struct HomePartialTemplate;
|
struct HomePartialTemplate;
|
||||||
|
|
||||||
pub async fn home(headers: HeaderMap) -> impl IntoResponse {
|
pub async fn home(headers: HeaderMap, state: State<Arc<AppState>>) -> impl IntoResponse {
|
||||||
if headers.contains_key("hx-request") {
|
if headers.contains_key("hx-request") {
|
||||||
Html(HomePartialTemplate.render().unwrap())
|
Html(HomePartialTemplate.render().unwrap())
|
||||||
} else {
|
} else {
|
||||||
Html(HomeTemplate.render().unwrap())
|
Html(
|
||||||
|
HomeTemplate {
|
||||||
|
tracks: state.mp_tracks.clone(),
|
||||||
|
}
|
||||||
|
.render()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
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,4 +1,3 @@
|
||||||
pub mod home;
|
pub mod home;
|
||||||
pub mod miniplayer;
|
|
||||||
pub mod music;
|
pub mod music;
|
||||||
pub mod notfound;
|
pub mod notfound;
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,33 @@
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use axum::{
|
use axum::{
|
||||||
|
extract::State,
|
||||||
http::HeaderMap,
|
http::HeaderMap,
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
};
|
};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::domain::AppState;
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "music.html")]
|
#[template(path = "music.html")]
|
||||||
struct MusicTemplate;
|
struct MusicTemplate {
|
||||||
|
tracks: Vec<crate::domain::Track>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "partials/music.html")]
|
#[template(path = "partials/music.html")]
|
||||||
struct MusicPartialTemplate;
|
struct MusicPartialTemplate;
|
||||||
|
|
||||||
pub async fn music(headers: HeaderMap) -> impl IntoResponse {
|
pub async fn music(headers: HeaderMap, state: State<Arc<AppState>>) -> impl IntoResponse {
|
||||||
if headers.contains_key("hx-request") {
|
if headers.contains_key("hx-request") {
|
||||||
Html(MusicPartialTemplate.render().unwrap())
|
Html(MusicPartialTemplate.render().unwrap())
|
||||||
} else {
|
} else {
|
||||||
Html(MusicTemplate.render().unwrap())
|
Html(
|
||||||
|
MusicTemplate {
|
||||||
|
tracks: state.p_tracks.clone(),
|
||||||
|
}
|
||||||
|
.render()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,4 +111,3 @@ function initMiniPlayer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
initMiniPlayer();
|
initMiniPlayer();
|
||||||
document.addEventListener("htmx:afterSwap", initMiniPlayer);
|
|
||||||
|
|
|
||||||
|
|
@ -79,13 +79,14 @@ navbar {
|
||||||
|
|
||||||
navbar-content {
|
navbar-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 1rem;
|
gap: 0.3rem;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
border: 2px solid black;
|
border: 2px solid black;
|
||||||
background: var(--win-bg-grey);
|
background: var(--win-bg-grey);
|
||||||
|
border-color: #ffffff #808080 #808080 #ffffff;
|
||||||
|
|
||||||
&:has(input:checked) {
|
&:has(input:checked) {
|
||||||
background: #ff75a7;
|
background: #ff75a7;
|
||||||
|
|
@ -94,8 +95,9 @@ navbar {
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
border-color: #808080 #ffffff #ffffff #808080;
|
border-color: #ffffff #808080 #808080 #ffffff;
|
||||||
padding: 5px 7px 3px 9px;
|
padding: 5px 7px 3px 9px;
|
||||||
|
border-color: #808080 #ffffff #ffffff #808080;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|
|
||||||
|
|
@ -12,20 +12,19 @@
|
||||||
<script src="/static/vendor/htmx.min.js"></script>
|
<script src="/static/vendor/htmx.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
<body hx-boost="true" hx-target="#content">
|
||||||
<crt>
|
<crt>
|
||||||
|
<persistent-ui>
|
||||||
<body hx-boost="true" hx-target="#content" {% block bodyattrs %}{% endblock %}>
|
|
||||||
{% include "partials/header.html" %}
|
{% include "partials/header.html" %}
|
||||||
<miniplayer-container id="miniplayer-container" hx-get="/miniplayer" hx-trigger="load" hx-swap="innerHTML"
|
<miniplayer-container id="miniplayer-container">
|
||||||
hx-target="#miniplayer-container">
|
{% block miniplayer %}{% endblock %}
|
||||||
<miniplayer>
|
|
||||||
<p>Chargement...</p>
|
|
||||||
</miniplayer>
|
|
||||||
</miniplayer-container>
|
</miniplayer-container>
|
||||||
|
</persistent-ui>
|
||||||
|
|
||||||
<main id="content">
|
<main id="content">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
|
</crt>
|
||||||
|
|
||||||
<script src="/static/miniplayer.js"></script>
|
<script src="/static/miniplayer.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -37,11 +36,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMiniplayerVisibility();
|
function updateNavState() {
|
||||||
|
const path = window.location.pathname;
|
||||||
|
document.querySelectorAll('navbar input[type="radio"]').forEach(radio => {
|
||||||
|
radio.checked = false;
|
||||||
|
});
|
||||||
|
if (path === '/') {
|
||||||
|
const homeRadio = document.getElementById('nav-home');
|
||||||
|
if (homeRadio) homeRadio.checked = true;
|
||||||
|
} else if (path === '/music') {
|
||||||
|
const musicRadio = document.getElementById('nav-music');
|
||||||
|
if (musicRadio) musicRadio.checked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document.body.addEventListener('htmx:afterSwap', updateMiniplayerVisibility);
|
updateMiniplayerVisibility();
|
||||||
|
updateNavState();
|
||||||
|
|
||||||
|
document.body.addEventListener('htmx:afterSwap', () => {
|
||||||
|
updateMiniplayerVisibility();
|
||||||
|
updateNavState();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</crt>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include "partials/home.html" %}
|
{% include "partials/home.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block miniplayer %}
|
||||||
|
{% include "partials/miniplayer.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,7 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include "partials/music.html" %}
|
{% include "partials/music.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block miniplayer %}
|
||||||
|
{% include "partials/miniplayer.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,9 @@
|
||||||
<input type="radio" name="nav" id="nav-home" checked>
|
<input type="radio" name="nav" id="nav-home" checked>
|
||||||
<a href="/">Accueil</a>
|
<a href="/">Accueil</a>
|
||||||
</label>
|
</label>
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="nav" id="nav-music">
|
||||||
|
<a href="/music">Music</a>
|
||||||
|
</label>
|
||||||
</navbar-content>
|
</navbar-content>
|
||||||
</navbar>
|
</navbar>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue