This commit is contained in:
Ondrej Zara 2019-03-22 16:17:10 +01:00
parent 76802bc630
commit 37fdd5413c
10 changed files with 87 additions and 14 deletions

View file

@ -4,6 +4,10 @@ body {
flex-direction: column;
height: 100vh;
}
header,
footer {
box-shadow: 0 0 3px #000;
}
main {
flex-grow: 1;
overflow-x: hidden;
@ -27,6 +31,16 @@ nav ul li:hover {
nav ul li.active {
background-color: green;
}
#player {
display: flex;
flex-direction: row;
}
#player .art img {
vertical-align: top;
}
#player .info {
flex-grow: 1;
}
#player:not([data-state=play]) .pause {
display: none;
}
@ -37,6 +51,21 @@ nav ul li.active {
#player:not([data-flags~=repeat]) .repeat {
opacity: 0.5;
}
#queue ul {
list-style: none;
margin: 0;
padding: 0;
}
#queue li {
display: flex;
flex-direction: row;
}
#queue li + li {
border-top: 1px solid #888;
}
#queue .info {
flex-grow: 1;
}
#queue .current {
font-weight: bold;
}

View file

@ -5,6 +5,10 @@ body {
height: 100vh;
}
header, footer {
box-shadow: 0 0 3px #000;
}
@import "main.less";
@import "nav.less";
@import "player.less";

View file

@ -1,7 +1,11 @@
#player {
display: flex;
flex-direction: row;
.art img { vertical-align: top; }
.info { flex-grow: 1; }
&:not([data-state=play]) .pause { display: none; }
&[data-state=play] .play { display: none; }
&:not([data-flags~=random]) .random, &:not([data-flags~=repeat]) .repeat { opacity: 0.5; }
}

View file

@ -1,3 +1,19 @@
#queue {
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
display: flex;
flex-direction: row;
+ li {
border-top: 1px solid #888;
}
}
.info { flex-grow: 1; }
.current { font-weight: bold; }
}

View file

@ -10,9 +10,10 @@
<header>
<section id="player">
<span class="art"></span>
<span class="title"></span>
<span class="artist"></span>
<span class="album"></span>
<div class="info">
<h2 class="title"></h2>
<span class="artist-album"></span>
</div>
<span class="elapsed"></span>/<span class="duration"></span>
<button class="play">⏯️▶</button>
<button class="pause">⏸️</button>

1
app/js/conf.js Normal file
View file

@ -0,0 +1 @@
export const artSize = 96;

View file

@ -1,11 +1,11 @@
import * as mpd from "./mpd.js";
import * as parser from "./parser.js";
import * as html from "./html.js";
import * as conf from "../conf.js";
let cache = {};
const SIZE = 64;
const MIME = "image/jpeg";
const STORAGE_PREFIX = `art-${SIZE}` ;
const STORAGE_PREFIX = `art-${conf.artSize}` ;
function store(key, data) {
localStorage.setItem(`${STORAGE_PREFIX}-${key}`, data);
@ -38,9 +38,9 @@ async function bytesToImage(bytes) {
}
function resize(image) {
let canvas = html.node("canvas", {width:SIZE, height:SIZE});
let canvas = html.node("canvas", {width:conf.artSize, height:conf.artSize});
let ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, SIZE, SIZE);
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
return canvas;
}

View file

@ -4,3 +4,10 @@ export function time(sec) {
let s = sec % 60;
return `${m}:${s.toString().padStart(2, "0")}`;
}
export function artistAlbum(artist, album) {
let tokens = [];
artist && tokens.push(artist);
album && tokens.push(album);
return tokens.join(" ");
}

View file

@ -17,8 +17,7 @@ function sync(data) {
if (data["file"] != current["file"]) { // changed song
DOM.duration.textContent = format.time(Number(data["duration"] || 0));
DOM.title.textContent = data["Title"] || "";
DOM.album.textContent = data["Album"] || "";
DOM.artist.textContent = data["Artist"] || "";
DOM["artist-album"].textContent = format.artistAlbum(data["Artist"], data["Album"]);
pubsub.publish("song-change", null, data);
}

View file

@ -2,6 +2,7 @@ import * as mpd from "./lib/mpd.js";
import * as html from "./lib/html.js";
import * as player from "./player.js";
import * as pubsub from "./lib/pubsub.js";
import * as format from "./lib/format.js";
let node;
let currentId;
@ -18,15 +19,26 @@ async function playSong(id) {
player.update();
}
async function deleteSong(id) {
await mpd.command(`deleteid ${id}`);
activate();
}
function buildSong(song) {
let id = Number(song["Id"]);
let node = html.node("li");
node.dataset.songId = id;
node.textContent = song["file"];
let play = html.button({}, "▶", node);
play.addEventListener("click", e => playSong(id));
html.button({className:"play"}, "▶", node).addEventListener("click", e => playSong(id));
let info = html.node("div", {className:"info"}, "", node);
html.node("h2", {className:"title"}, song["Title"], info);
html.node("span", {className:"artist-album"}, format.artistAlbum(song["Artist"], song["Album"]), info);
html.node("span", {className:"duration"}, format.time(Number(song["duration"])), info);
html.button({className:"delete"}, "🗙", node).addEventListener("click", e => deleteSong(id));
return node;
}