From adfddfc9cff15d89fa987a2977003e4341500a2a Mon Sep 17 00:00:00 2001 From: Sijmen Date: Tue, 25 Apr 2023 16:32:51 +0200 Subject: [PATCH] Implement "now playing" card --- src/main.rs | 36 +++++++++ templates/current.html | 37 +++++++++ templates/index.html | 172 ++++++++++++++++++++++++++--------------- 3 files changed, 182 insertions(+), 63 deletions(-) create mode 100644 templates/current.html 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 - -
- -
- - -
    - {% for entry in entries %} - {% match entry %} - {% when mpd::Entry::Song with { name, path, artist } %} -
  • - music_note -
    -
    {{ name }}
    -
    {{ artist }}
    - -
  • - {% when mpd::Entry::Directory with { name, path }%} -
  • - folder - {{ name }} -
  • - {% when mpd::Entry::Playlist with { name, path } %} -
  • - playlist_play -
    -
    {{ name }}
    - -
  • - {% endmatch %} - {% endfor %} -
+
    + {% for entry in entries %} + {% match entry %} + {% when mpd::Entry::Song with { name, path, artist } %} +
  • + music_note + +
    +
    {{ name }}
    +
    {{ artist }}
    + +
  • + {% when mpd::Entry::Directory with { name, path }%} +
  • + folder + {{ name }} +
  • + {% when mpd::Entry::Playlist with { name, path } %} +
  • + playlist_play +
    +
    {{ name }}
    + +
  • + {% endmatch %} + {% endfor %} +
+ +
+
+
+