diff --git a/src/main.rs b/src/main.rs index f2b2212..baaeb09 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,6 +49,28 @@ async fn get_queue(_req: tide::Request<()>) -> tide::Result { Ok(template.into()) } +#[derive(Template)] +#[template(path = "current.html")] +struct CurrentTemplate { + song: Option, + name: Option, +} + +async fn get_current(_req: tide::Request<()>) -> tide::Result { + let mut mpd = mpd::connect()?; + let song = mpd.currentsong()?; + + let mut template = CurrentTemplate { song: song.clone(), name: None }; + + if let Some(song) = song { + let name = song.title.unwrap_or(song.file.clone()).to_string(); + template.name = Some(name); + + } + + Ok(template.into()) +} + #[derive(Deserialize)] struct PostQueueQuery { path: String, @@ -80,6 +102,18 @@ async fn post_next(_req: tide::Request<()>) -> tide::Result { Ok("".into()) } +async fn get_art(req: tide::Request<()>) -> tide::Result { + let query: IndexQuery = req.query()?; + let resp = if let Ok(art) = mpd::connect()?.albumart(&query.path) { + tide::Response::builder(tide::StatusCode::Ok) + .body(art) + .header("cache-control", "max-age=3600") + } else { + tide::Response::builder(tide::StatusCode::NotFound) + }; + Ok(resp.into()) +} + async fn sse(_req: tide::Request<()>, sender: tide::sse::Sender) -> tide::Result<()> { // Needs to be async and all async mpd libraries suck let mut stream = TcpStream::connect(mpd::HOST).await?; @@ -120,6 +154,8 @@ async fn main() -> tide::Result<()> { app.at("/").get(index); app.at("/queue").get(get_queue); + app.at("/current").get(get_current); + app.at("/art").get(get_art); app.at("/sse").get(tide::sse::endpoint(sse)); diff --git a/templates/current.html b/templates/current.html new file mode 100644 index 0000000..7851ea9 --- /dev/null +++ b/templates/current.html @@ -0,0 +1,37 @@ +{# #} + +
+
+ {% if let Some(song) = song %} + + + + {% endif %} +
+ +
+ skip_previous + play_arrow + pause + skip_next +
+
diff --git a/templates/index.html b/templates/index.html index 5f43aa6..d91d3cd 100644 --- a/templates/index.html +++ b/templates/index.html @@ -13,6 +13,16 @@ font-family: sans; background-color: #112; color: #fff; + display: flex; + margin: 0; + } + + body > div { + padding: 1rem; + } + + .browser { + flex: 1; } a { @@ -24,12 +34,20 @@ ul { list-style: none; padding: 0; + margin: 0; + } + + ul.queue { + margin-top: 1.0rem; } ul.queue li { - padding: .5rem 0; + padding: 1.0rem 0.75rem; + border-radius: .25rem; } + ul.queue li.playing { + background-color: #334; font-weight: bold; } @@ -60,6 +78,12 @@ align-items: center; } + ul.dir li img { + width: 48px; + height: 48px; + object-fit: contain; + } + ul.dir li:hover { background-color: #334; } @@ -69,81 +93,103 @@ width: 24px; } - .song .song__name { + .song__name { font-weight: bold; } - span.control { + .player { + width: 25rem; + } + + .player .nowplaying { + flex-flow: column; + background-color: #334; + border-radius: 0.25rem; + } + + .player .controls { + display: flex; + justify-content: space-around; + padding: 0.5rem; + } + + .player .control { font-size: 40px; cursor: pointer; } + + .player .current { + display: flex; + flex-flow: row; + align-items: center; + padding: 0.5rem; + } + + .player .albumart { + width: 80px; + height: 80px; + object-fit: contain; + display: block; + margin-right: 1.0rem; + border-radius: 0.25rem; + } + + .player .metadata { + flex: 1; + } - skip_previous - play_arrow - pause - skip_next - -
- -
- - - + + +
+
+
+