tag/path queueing

This commit is contained in:
Ondrej Zara 2020-03-13 16:52:24 +01:00
parent aca1f44a60
commit c3871fa486
16 changed files with 62 additions and 161 deletions

View file

@ -1,6 +1,4 @@
.art {
margin-right: var(--icon-spacing);
.icon, img {
vertical-align: top;
}
.icon, img { display: block; }
}

View file

@ -1,58 +0,0 @@
.component {
header {
.flex-row;
padding: var(--spacing);
button {
font-size: var(--font-size-large);
font-weight: bold;
.icon { margin-right: var(--icon-spacing); }
overflow: hidden;
}
}
ul {
flex-grow: 1;
overflow: auto;
list-style: none;
margin: 0;
padding: 0;
}
li {
.flex-row;
.info {
flex-grow: 1;
overflow: hidden;
.icon {
color: var(--primary);
margin-right: var(--icon-spacing);
filter: drop-shadow(var(--text-shadow));
}
h2 {
font-size: var(--font-size-large);
margin: 0;
}
// h2, div { .long-line; }
}
&.has-art {
}
&:not(.has-art) {
padding: 8px;
}
button .icon { width: 32px; }
}
li:nth-child(odd) {
background-color: var(--bg-alt);
}
}

View file

@ -65,9 +65,6 @@ select {
@import "font.less";
@import "icons.less";
@import "mixins.less";
@import "component.less";
@import "library.less";
@import "fs.less";
@import "search.less";
@import "art.less";
@import "variables.less";

View file

@ -1,3 +1,16 @@
cyp-tag {
.item;
padding: 0;
.art {
img, .icon {
width: 64px;
height: 64px;
}
.icon {
filter: drop-shadow(var(--text-shadow));
}
}
}

View file

@ -1,6 +1,4 @@
cyp-yt {
.component;
header {
border-bottom: 1px solid var(--fg);

View file

@ -1,20 +0,0 @@
#fs {
.component;
header {
white-space: pre; // separator
}
.search {
order: 1;
&.open ~ * { display: none; }
}
.group {
cursor: pointer;
}
.info {
// .multiline; FIXME
}
}

View file

@ -1,6 +1,6 @@
.icon {
width: 24px;
// flex-shrink: 0;
flex: none;
path, polygon, circle {
&:not([fill]) {

View file

@ -1,43 +0,0 @@
#library {
.component;
header {
white-space: pre; // separator
}
.search {
order: 1;
&.open ~ * { display: none; }
}
.art img, .art .icon {
width: 64px;
}
.art .icon {
filter: drop-shadow(var(--text-shadow));
}
.group {
cursor: pointer;
h2 { font-weight: normal; }
}
.tiles {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 2px;
li {
text-align: center;
cursor: pointer;
background-color: rgba(255, 255, 255, 0.08);
height: 200px;
h2 {
font-size: 150%;
margin: 4px 0;
}
}
}
}

View file

@ -14,22 +14,33 @@
text-overflow: ellipsis;
}
/*
.multiline {
.flex-row;
h2 { font-weight: normal; }
}
*/
.selectable {
border-left: var(--border-width) solid transparent;
cursor: pointer;
position: relative; // kotva pro selected::before
&.selected {
border-left-color: var(--primary);
xbackground-color: var(--primary-tint); // FIXME jak zvyraznovat?
&::before {
content: "";
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: var(--border-width);
background-color: var(--primary);
}
&::after {
content: "";
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
background-color: var(--primary-tint);
}
}
}
.item {
@ -37,14 +48,12 @@
.selectable;
padding: 8px;
padding-left: calc(8px - var(--border-width));
&:nth-child(odd) { // FIXME nutno poresit lepe s ohledem na search
&:nth-child(odd) {
background-color: var(--bg-alt);
}
> .icon {
flex: none;
margin-right: var(--icon-spacing);
filter: drop-shadow(var(--text-shadow));
}
@ -61,5 +70,4 @@
&:first-of-type { margin-left: auto; }
.icon { width: 32px; }
}
}

File diff suppressed because one or more lines are too long

View file

@ -14,7 +14,7 @@ export default class Component extends HasApp {
connectedCallback() {
this._app.addEventListener("load", _ => this._onAppLoad());
this._app.addEventListener("component-change", _ => {
const component = this._app.getAttribute("component");
const component = this._app.component;
const isThis = (this.nodeName.toLowerCase() == `cyp-${component}`);
this._onComponentChange(component, isThis);
});

View file

@ -42,8 +42,8 @@ class App extends HTMLElement {
this.dispatchEvent(new CustomEvent("load"));
const onHashChange = () => {
const hash = location.hash.substring(1);
this.setAttribute("component", hash || "queue");
const component = location.hash.substring(1) || "queue";
if (component != this.component) { this.component = component; }
}
window.addEventListener("hashchange", onHashChange);
onHashChange();
@ -58,6 +58,9 @@ class App extends HTMLElement {
break;
}
}
get component() { return this.getAttribute("component"); }
set component(component) { return this.setAttribute("component", component); }
}
customElements.define("cyp-app", App);

View file

@ -9,14 +9,18 @@ import { escape, serializeFilter } from "../mpd.js";
const SORT = "-Track";
function nonempty(str) { return (str.length > 0); }
function createEnqueueCommand(node) {
if (node instanceof Song) {
return `add "${escape(node.data["file"])}"`;
} else if (node instanceof Path) {
return `add "${escape(node.file)}"`;
} else if (node instanceof Tag) {
return [
"findadd",
serializeFilter(node.createChildFilter()),
`sort ${SORT}`
// `sort ${SORT}` // MPD >= 0.22, not yet released
].join(" ");
} else {
throw new Error(`Cannot create enqueue command for "${node.nodeName}"`);
@ -37,7 +41,7 @@ class Library extends Component {
const wasHidden = this.hidden;
this.hidden = !isThis;
if (!wasHidden) { this._showRoot(); }
if (!wasHidden && isThis) { this._showRoot(); }
}
_showRoot() {
@ -58,7 +62,7 @@ class Library extends Component {
html.clear(this);
if ("AlbumArtist" in filter) { this._buildBack(filter); }
values.forEach(value => this._buildTag(tag, value, filter));
values.filter(nonempty).forEach(value => this._buildTag(tag, value, filter));
}
async _listPath(path) {

View file

@ -9,19 +9,21 @@ function baseName(path) {
export default class Path extends Item {
constructor(data) {
super();
this.data = data;
// FIXME spis ._data a .url
this._data = data;
if ("directory" in this._data) {
this.file = data["directory"];
} else {
this.file = data["file"];
}
}
connectedCallback() {
let path;
if ("directory" in this.data) {
if ("directory" in this._data) {
this.appendChild(html.icon("folder"));
path = this.data["directory"];
} else {
this.appendChild(html.icon("music"));
path = this.data["file"];
}
this._buildTitle(baseName(path));
this._buildTitle(baseName(this.file));
}
}

View file

@ -120,7 +120,7 @@ class Player extends Component {
let artistOld = this._current["AlbumArtist"] || this._current["Artist"];
if (artistNew != artistOld || data["Album"] != this._current["Album"]) { // changed album (art)
html.clear(DOM.art);
art.get(artistNew, data["Album"], data["file"]).then(src => {
art.get(this._mpd, artistNew, data["Album"], data["file"]).then(src => {
if (src) {
html.node("img", {src}, "", DOM.art);
} else {

View file

@ -8,7 +8,6 @@ const ICONS = {
"Album": "album"
}
export default class Tag extends Item {
constructor(type, value, filter) {
super();