library refactor

This commit is contained in:
Ondrej Zara 2019-03-30 12:57:01 +01:00
parent 9d8a81ebc8
commit 181c988649
9 changed files with 118 additions and 74 deletions

View file

@ -12,7 +12,7 @@ body {
line-height: 1;
background-color: var(--bg);
color: var(--fg);
text-shadow: 0 1px 1px #000;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.8);
max-width: 800px;
margin: 0 auto;
overflow: hidden;
@ -137,14 +137,14 @@ nav ul li.active {
margin: 0;
padding: 0;
}
.component .grid li {
.component li {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 4px;
white-space: nowrap;
}
.component .grid h2 {
.component h2 {
flex-grow: 1;
font-size: 100%;
font-weight: normal;
@ -152,15 +152,15 @@ nav ul li.active {
overflow: hidden;
text-overflow: ellipsis;
}
.component .grid h2 .icon {
.component h2 .icon {
margin-right: 4px;
color: var(--primary);
}
.component .grid li:nth-child(odd) {
.component li:nth-child(odd) {
background-color: #555;
}
@media (pointer: coarse) {
.component .grid .icon {
.component .icon {
width: 32px;
}
}
@ -176,14 +176,14 @@ nav ul li.active {
margin: 0;
padding: 0;
}
#queue .grid li {
#queue li {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 4px;
white-space: nowrap;
}
#queue .grid h2 {
#queue h2 {
flex-grow: 1;
font-size: 100%;
font-weight: normal;
@ -191,15 +191,15 @@ nav ul li.active {
overflow: hidden;
text-overflow: ellipsis;
}
#queue .grid h2 .icon {
#queue h2 .icon {
margin-right: 4px;
color: var(--primary);
}
#queue .grid li:nth-child(odd) {
#queue li:nth-child(odd) {
background-color: #555;
}
@media (pointer: coarse) {
#queue .grid .icon {
#queue .icon {
width: 32px;
}
}
@ -218,14 +218,14 @@ nav ul li.active {
margin: 0;
padding: 0;
}
#library .grid li {
#library li {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 4px;
white-space: nowrap;
}
#library .grid h2 {
#library h2 {
flex-grow: 1;
font-size: 100%;
font-weight: normal;
@ -233,26 +233,33 @@ nav ul li.active {
overflow: hidden;
text-overflow: ellipsis;
}
#library .grid h2 .icon {
#library h2 .icon {
margin-right: 4px;
color: var(--primary);
}
#library .grid li:nth-child(odd) {
#library li:nth-child(odd) {
background-color: #555;
}
@media (pointer: coarse) {
#library .grid .icon {
#library .icon {
width: 32px;
}
}
#library .tiles {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 2px;
}
#library .tiles li {
border: 3px solid lime;
text-align: center;
cursor: pointer;
background-color: rgba(255, 255, 255, 0.08);
height: 200px;
}
#library .tiles li h2 {
font-size: 150%;
margin: 4px 0;
}
#fs {
height: 100%;
display: flex;
@ -265,14 +272,14 @@ nav ul li.active {
margin: 0;
padding: 0;
}
#fs .grid li {
#fs li {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 4px;
white-space: nowrap;
}
#fs .grid h2 {
#fs h2 {
flex-grow: 1;
font-size: 100%;
font-weight: normal;
@ -280,15 +287,15 @@ nav ul li.active {
overflow: hidden;
text-overflow: ellipsis;
}
#fs .grid h2 .icon {
#fs h2 .icon {
margin-right: 4px;
color: var(--primary);
}
#fs .grid li:nth-child(odd) {
#fs li:nth-child(odd) {
background-color: #555;
}
@media (pointer: coarse) {
#fs .grid .icon {
#fs .icon {
width: 32px;
}
}
@ -307,14 +314,14 @@ nav ul li.active {
margin: 0;
padding: 0;
}
#playlists .grid li {
#playlists li {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 4px;
white-space: nowrap;
}
#playlists .grid h2 {
#playlists h2 {
flex-grow: 1;
font-size: 100%;
font-weight: normal;
@ -322,15 +329,15 @@ nav ul li.active {
overflow: hidden;
text-overflow: ellipsis;
}
#playlists .grid h2 .icon {
#playlists h2 .icon {
margin-right: 4px;
color: var(--primary);
}
#playlists .grid li:nth-child(odd) {
#playlists li:nth-child(odd) {
background-color: #555;
}
@media (pointer: coarse) {
#playlists .grid .icon {
#playlists .icon {
width: 32px;
}
}

View file

@ -10,7 +10,7 @@ body {
line-height: 1;
background-color: var(--bg);
color: var(--fg);
text-shadow: 0 1px 1px #000;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.8);
max-width: 800px;
margin: 0 auto;
overflow: hidden;

View file

@ -11,35 +11,33 @@
padding: 0;
}
.grid {
li {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 4px;
white-space: nowrap;
}
li {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 4px;
white-space: nowrap;
}
h2 {
flex-grow: 1;
font-size: 100%;
font-weight: normal;
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
h2 {
flex-grow: 1;
font-size: 100%;
font-weight: normal;
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
.icon {
margin-right: 4px;
color: var(--primary);
}
}
li:nth-child(odd) {
background-color: #555;
}
@media (pointer: coarse) {
.icon { width: 32px; }
.icon {
margin-right: 4px;
color: var(--primary);
}
}
li:nth-child(odd) {
background-color: #555;
}
@media (pointer: coarse) {
.icon { width: 32px; }
}
}

View file

@ -3,11 +3,19 @@
.tiles {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 2px;
li {
border: 3px solid lime;
text-align: center;
cursor: pointer;
background-color: rgba(255, 255, 255, 0.08);
height: 200px;
h2 {
font-size: 150%;
margin: 4px 0;
}
}
}
}

View file

@ -35,10 +35,10 @@
<button class="clear" data-icon="close" title="Clear the queue"></button>
<button class="save" data-icon="content-save" title="Save the queue"></button>
</header>
<ul class="grid"></ul>
<ul></ul>
</section>
<section id="playlists">
<ul class="grid"></ul>
<ul></ul>
</section>
<section id="library">
<header></header>
@ -46,7 +46,7 @@
</section>
<section id="fs">
<header></header>
<ul class="grid"></ul>
<ul></ul>
</section>
<section id="yt">
<button class="go" data-icon="download">Go!</button>

View file

@ -11,6 +11,7 @@ function onMessage(e) {
if (last.startsWith("OK")) {
current.resolve(lines);
} else {
console.warn(last);
current.reject(last);
}
current = null;
@ -108,12 +109,13 @@ export async function listTags(tag, filter = null) {
}
let lines = await command(tokens.join(" "));
let parsed = parser.linesToStruct(lines);
return [].concat(parsed[tag] || []);
return [].concat(tag in parsed ? parsed[tag] : []);
}
export async function listSongs(filter) {
export async function listSongs(filter, window = null) {
let tokens = ["find"];
tokens.push(serializeFilter(filter));
if (window) { tokens.push("window", window.join(":")); }
let lines = await command(tokens.join(" "));
return parser.songList(lines);
}

View file

@ -2,6 +2,7 @@ import * as mpd from "./mpd.js";
import * as html from "./html.js";
import * as pubsub from "./pubsub.js";
import * as format from "./format.js";
import * as art from "./art.js";
import * as player from "../player.js";
export const CTX_FS = 1;
@ -15,7 +16,7 @@ const TYPE_PLAYLIST = 4;
const SORT = "-Track";
function enqueue(type, what) {
async function enqueue(type, what) {
switch (type) {
case TYPE_URL: return mpd.command(`add "${mpd.escape(what)}"`); break;
case TYPE_FILTER: return mpd.enqueueByFilter(what, SORT); break;
@ -23,6 +24,28 @@ function enqueue(type, what) {
}
}
async function fillArt(parent, filter) {
let artist = filter["Artist"];
let album = filter["Album"];
let src = null;
if (artist && album) {
src = await art.get(artist, album);
if (!src) {
let songs = await mpd.listSongs(filter, [0,1]);
if (songs.length) {
src = await art.get(artist, album, songs[0]["file"]);
}
}
}
if (src) {
html.node("img", {src}, "", parent);
} else {
html.icon("music", parent);
}
}
function fileName(data) {
return data["file"].split("/").pop();
}
@ -106,7 +129,6 @@ function addButton(type, what, parent) {
export function song(ctx, data, parent) {
let node = html.node("li", {className:"song"}, "", parent);
let title = formatTitle(ctx, data);
let h2 = html.node("h2", {}, "", node);
if (ctx == CTX_FS || ctx == CTX_LIBRARY) { html.icon("music", h2); }
@ -136,10 +158,16 @@ export function song(ctx, data, parent) {
export function group(ctx, label, urlOrFilter, parent) {
let node = html.node("li", {className:"group"}, "", parent);
if (ctx == CTX_LIBRARY) {
let art = html.node("span", {className:"art"}, "", node);
fillArt(art, urlOrFilter);
}
let h2 = html.node("h2", {}, "", node);
if (ctx == CTX_FS) { html.icon("folder", h2); }
html.text(label, h2);
let type = (ctx == CTX_FS ? TYPE_URL : TYPE_FILTER);
playButton(type, urlOrFilter, node);

View file

@ -44,8 +44,6 @@ function buildArtist(artist, filter, parent) {
function buildSongs(songs, filter) {
let ul = node.querySelector("ul");
html.clear(ul);
ul.classList.remove("tiles");
ul.classList.add("grid");
songs.map(song => ui.song(ui.CTX_LIBRARY, song, ul));
}
@ -53,8 +51,6 @@ function buildSongs(songs, filter) {
function buildAlbums(albums, filter) {
let ul = node.querySelector("ul");
html.clear(ul);
ul.classList.add("tiles");
ul.classList.remove("grid");
albums.map(album => buildAlbum(album, filter, ul));
}
@ -62,8 +58,6 @@ function buildAlbums(albums, filter) {
function buildArtists(artists, filter) {
let ul = node.querySelector("ul");
html.clear(ul);
ul.classList.add("tiles");
ul.classList.remove("grid");
artists.map(artist => buildArtist(artist, filter, ul));
}

View file

@ -15,9 +15,16 @@ function sync(data) {
DOM.elapsed.textContent = format.time(Number(data["elapsed"] || 0)); // changed time
if (data["file"] != current["file"]) { // changed song
DOM.duration.textContent = format.time(Number(data["duration"] || 0));
DOM.title.textContent = data["Title"] || data["file"].split("/").pop();
DOM["artist-album"].textContent = format.artistAlbum(data["Artist"], data["Album"]);
if (data["file"]) { // playing at all?
DOM.duration.textContent = format.time(Number(data["duration"] || 0));
DOM.title.textContent = data["Title"] || data["file"].split("/").pop();
DOM["artist-album"].textContent = format.artistAlbum(data["Artist"], data["Album"]);
} else {
DOM.duration.textContent = "";
DOM.title.textContent = "";
DOM["artist-album"].textContent = "";
}
pubsub.publish("song-change", null, data);
}