icons
This commit is contained in:
parent
e291f0feca
commit
f8442348ad
17 changed files with 151 additions and 114 deletions
113
app/app.css
113
app/app.css
|
@ -38,6 +38,7 @@ button {
|
||||||
border: none;
|
border: none;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Lato';
|
font-family: 'Lato';
|
||||||
|
@ -71,6 +72,9 @@ nav ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
nav ul .icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
nav ul li {
|
nav ul li {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
flex: 1 0 0;
|
flex: 1 0 0;
|
||||||
|
@ -85,15 +89,7 @@ nav ul li.active {
|
||||||
#player {
|
#player {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
align-items: center;
|
||||||
#player .art img {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
#player .info {
|
|
||||||
flex-grow: 1;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
#player:not([data-state=play]) .pause {
|
#player:not([data-state=play]) .pause {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -105,7 +101,20 @@ nav ul li.active {
|
||||||
#player:not([data-flags~=repeat]) .repeat {
|
#player:not([data-flags~=repeat]) .repeat {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
#player .icon {
|
#player .art img {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
#player .info {
|
||||||
|
flex-grow: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
#player .controls {
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#player .controls .icon {
|
||||||
width: 64px;
|
width: 64px;
|
||||||
}
|
}
|
||||||
#player .misc {
|
#player .misc {
|
||||||
|
@ -135,7 +144,7 @@ nav ul li.active {
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.component .grid li h2 {
|
.component .grid h2 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
@ -143,17 +152,17 @@ nav ul li.active {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
.component .grid li button {
|
.component .grid h2 .icon {
|
||||||
flex-shrink: 0;
|
margin-right: 4px;
|
||||||
}
|
|
||||||
@media (pointer: coarse) {
|
|
||||||
.component .grid li button .icon {
|
|
||||||
width: 32px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.component .grid li:nth-child(odd) {
|
.component .grid li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
@media (pointer: coarse) {
|
||||||
|
.component .grid .icon {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
#queue {
|
#queue {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -173,7 +182,7 @@ nav ul li.active {
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
#queue .grid li h2 {
|
#queue .grid h2 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
@ -181,19 +190,19 @@ nav ul li.active {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
#queue .grid li button {
|
#queue .grid h2 .icon {
|
||||||
flex-shrink: 0;
|
margin-right: 4px;
|
||||||
}
|
|
||||||
@media (pointer: coarse) {
|
|
||||||
#queue .grid li button .icon {
|
|
||||||
width: 32px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#queue .grid li:nth-child(odd) {
|
#queue .grid li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
#queue .current {
|
@media (pointer: coarse) {
|
||||||
font-weight: bold;
|
#queue .grid .icon {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#queue .current * {
|
||||||
|
font-weight: bold !important;
|
||||||
}
|
}
|
||||||
#library {
|
#library {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -214,7 +223,7 @@ nav ul li.active {
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
#library .grid li h2 {
|
#library .grid h2 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
@ -222,17 +231,17 @@ nav ul li.active {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
#library .grid li button {
|
#library .grid h2 .icon {
|
||||||
flex-shrink: 0;
|
margin-right: 4px;
|
||||||
}
|
|
||||||
@media (pointer: coarse) {
|
|
||||||
#library .grid li button .icon {
|
|
||||||
width: 32px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#library .grid li:nth-child(odd) {
|
#library .grid li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
@media (pointer: coarse) {
|
||||||
|
#library .grid .icon {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
#fs {
|
#fs {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -252,7 +261,7 @@ nav ul li.active {
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
#fs .grid li h2 {
|
#fs .grid h2 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
@ -260,17 +269,17 @@ nav ul li.active {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
#fs .grid li button {
|
#fs .grid h2 .icon {
|
||||||
flex-shrink: 0;
|
margin-right: 4px;
|
||||||
}
|
|
||||||
@media (pointer: coarse) {
|
|
||||||
#fs .grid li button .icon {
|
|
||||||
width: 32px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#fs .grid li:nth-child(odd) {
|
#fs .grid li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
@media (pointer: coarse) {
|
||||||
|
#fs .grid .icon {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
#playlists {
|
#playlists {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -290,7 +299,7 @@ nav ul li.active {
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
#playlists .grid li h2 {
|
#playlists .grid h2 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
@ -298,14 +307,14 @@ nav ul li.active {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
#playlists .grid li button {
|
#playlists .grid h2 .icon {
|
||||||
flex-shrink: 0;
|
margin-right: 4px;
|
||||||
}
|
|
||||||
@media (pointer: coarse) {
|
|
||||||
#playlists .grid li button .icon {
|
|
||||||
width: 32px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#playlists .grid li:nth-child(odd) {
|
#playlists .grid li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
@media (pointer: coarse) {
|
||||||
|
#playlists .grid .icon {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -37,9 +37,9 @@ button {
|
||||||
border: none;
|
border: none;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@import "font.less";
|
@import "font.less";
|
||||||
@import "icons.less";
|
@import "icons.less";
|
||||||
@import "main.less";
|
@import "main.less";
|
||||||
|
|
|
@ -18,27 +18,25 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
.icon { margin-right: 4px; }
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
@media (pointer: coarse) {
|
|
||||||
.icon { width: 32px; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
li:nth-child(odd) {
|
li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (pointer: coarse) {
|
||||||
|
.icon { width: 32px; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@ nav ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
flex: 1 0 0;
|
flex: 1 0 0;
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
#player {
|
#player {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&: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; }
|
||||||
|
|
||||||
.art img { vertical-align: top; }
|
.art img { vertical-align: top; }
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -10,12 +16,10 @@
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not([data-state=play]) .pause { display: none; }
|
.controls {
|
||||||
&[data-state=play] .play { display: none; }
|
white-space: nowrap;
|
||||||
&:not([data-flags~=random]) .random, &:not([data-flags~=repeat]) .repeat { opacity: 0.5; }
|
text-align: center;
|
||||||
|
.icon { width: 64px; }
|
||||||
.icon {
|
|
||||||
width: 64px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.misc {
|
.misc {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#queue {
|
#queue {
|
||||||
.component;
|
.component;
|
||||||
|
.current * { font-weight: bold !important; }
|
||||||
.current { font-weight: bold; }
|
|
||||||
}
|
}
|
||||||
|
|
1
app/icons/download.svg
Normal file
1
app/icons/download.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" /></svg>
|
After Width: | Height: | Size: 336 B |
1
app/icons/folder.svg
Normal file
1
app/icons/folder.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z" /></svg>
|
After Width: | Height: | Size: 388 B |
1
app/icons/library-music.svg
Normal file
1
app/icons/library-music.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M4,6H2V20A2,2 0 0,0 4,22H18V20H4M18,7H15V12.5A2.5,2.5 0 0,1 12.5,15A2.5,2.5 0 0,1 10,12.5A2.5,2.5 0 0,1 12.5,10C13.07,10 13.58,10.19 14,10.5V5H18M20,2H8A2,2 0 0,0 6,4V16A2,2 0 0,0 8,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2Z" /></svg>
|
After Width: | Height: | Size: 516 B |
1
app/icons/music.svg
Normal file
1
app/icons/music.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M21,3V15.5A3.5,3.5 0 0,1 17.5,19A3.5,3.5 0 0,1 14,15.5A3.5,3.5 0 0,1 17.5,12C18.04,12 18.55,12.12 19,12.34V6.47L9,8.6V17.5A3.5,3.5 0 0,1 5.5,21A3.5,3.5 0 0,1 2,17.5A3.5,3.5 0 0,1 5.5,14C6.04,14 6.55,14.12 7,14.34V6L21,3Z" /></svg>
|
After Width: | Height: | Size: 515 B |
|
@ -14,22 +14,26 @@
|
||||||
<h2 class="title"></h2>
|
<h2 class="title"></h2>
|
||||||
<span class="artist-album"></span>
|
<span class="artist-album"></span>
|
||||||
</div>
|
</div>
|
||||||
<span class="elapsed"></span>/<span class="duration"></span>
|
<div class="controls">
|
||||||
<button class="prev"></button>
|
<button class="prev" data-icon="rewind"></button>
|
||||||
<button class="play"></button>
|
<button class="play" data-icon="play"></button>
|
||||||
<button class="pause"></button>
|
<button class="pause" data-icon="pause"></button>
|
||||||
<button class="next"></button>
|
<button class="next" data-icon="fast-forward"></button>
|
||||||
|
<div>
|
||||||
|
<span class="elapsed"></span>/<span class="duration"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="misc">
|
<div class="misc">
|
||||||
<button class="repeat"></button>
|
<button class="repeat" data-icon="repeat"></button>
|
||||||
<button class="random"></button>
|
<button class="random" data-icon="shuffle"></button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<section id="queue">
|
<section id="queue">
|
||||||
<header>
|
<header>
|
||||||
<button class="clear" title="Clear the queue"></button>
|
<button class="clear" data-icon="close" title="Clear the queue"></button>
|
||||||
<button class="save" title="Save the queue"></button>
|
<button class="save" data-icon="content-save" title="Save the queue"></button>
|
||||||
</header>
|
</header>
|
||||||
<ul class="grid"></ul>
|
<ul class="grid"></ul>
|
||||||
</section>
|
</section>
|
||||||
|
@ -45,20 +49,20 @@
|
||||||
<ul class="grid"></ul>
|
<ul class="grid"></ul>
|
||||||
</section>
|
</section>
|
||||||
<section id="yt">
|
<section id="yt">
|
||||||
<button class="go">Go!</button>
|
<button class="go" data-icon="download">Go!</button>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
<li data-for="queue">
|
<li data-for="queue" data-icon="music">
|
||||||
Q
|
Q
|
||||||
<span id="queue-length"></span>
|
<span id="queue-length"></span>
|
||||||
</li>
|
</li>
|
||||||
<li data-for="playlists">Playlists</li>
|
<li data-for="playlists" data-icon="playlist-music">Playlists</li>
|
||||||
<li data-for="library">Library</li>
|
<li data-for="library" data-icon="library-music">Library</li>
|
||||||
<li data-for="fs">FS</li>
|
<li data-for="fs" data-icon="folder">FS</li>
|
||||||
<li data-for="yt">YouTube</li>
|
<li data-for="yt" data-icon="download">YouTube</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import * as nav from "./nav.js";
|
import * as nav from "./nav.js";
|
||||||
import * as mpd from "./lib/mpd.js";
|
import * as mpd from "./lib/mpd.js";
|
||||||
import * as player from "./player.js";
|
import * as player from "./player.js";
|
||||||
|
import * as html from "./lib/html.js";
|
||||||
|
|
||||||
import * as queue from "./queue.js";
|
import * as queue from "./queue.js";
|
||||||
import * as library from "./library.js";
|
import * as library from "./library.js";
|
||||||
|
@ -11,6 +12,8 @@ import * as yt from "./yt.js";
|
||||||
const components = { queue, library, fs, playlists, yt };
|
const components = { queue, library, fs, playlists, yt };
|
||||||
|
|
||||||
export function activate(what) {
|
export function activate(what) {
|
||||||
|
location.hash = what;
|
||||||
|
|
||||||
for (let id in components) {
|
for (let id in components) {
|
||||||
let node = document.querySelector(`#${id}`);
|
let node = document.querySelector(`#${id}`);
|
||||||
if (what == id) {
|
if (what == id) {
|
||||||
|
@ -23,7 +26,15 @@ export function activate(what) {
|
||||||
nav.active(what);
|
nav.active(what);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initIcons() {
|
||||||
|
Array.from(document.querySelectorAll("[data-icon]")).forEach(node => {
|
||||||
|
let icon = html.icon(node.dataset.icon);
|
||||||
|
node.insertBefore(icon, node.firstChild);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
|
initIcons();
|
||||||
await mpd.init();
|
await mpd.init();
|
||||||
|
|
||||||
nav.init(document.querySelector("nav"));
|
nav.init(document.querySelector("nav"));
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
let ICONS={};
|
let ICONS={};
|
||||||
|
ICONS["library-music"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
|
<path d="M4,6H2V20A2,2 0 0,0 4,22H18V20H4M18,7H15V12.5A2.5,2.5 0 0,1 12.5,15A2.5,2.5 0 0,1 10,12.5A2.5,2.5 0 0,1 12.5,10C13.07,10 13.58,10.19 14,10.5V5H18M20,2H8A2,2 0 0,0 6,4V16A2,2 0 0,0 8,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2Z"/>
|
||||||
|
</svg>`;
|
||||||
ICONS["pause"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
ICONS["pause"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
<path d="M14,19H18V5H14M6,19H10V5H6V19Z"/>
|
<path d="M14,19H18V5H14M6,19H10V5H6V19Z"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
@ -47,9 +50,15 @@ ICONS["minus-circle-outline"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:x
|
||||||
ICONS["playlist-music"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
ICONS["playlist-music"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
<path d="M15,6H3V8H15V6M15,10H3V12H15V10M3,16H11V14H3V16M17,6V14.18C16.69,14.07 16.35,14 16,14A3,3 0 0,0 13,17A3,3 0 0,0 16,20A3,3 0 0,0 19,17V8H22V6H17Z"/>
|
<path d="M15,6H3V8H15V6M15,10H3V12H15V10M3,16H11V14H3V16M17,6V14.18C16.69,14.07 16.35,14 16,14A3,3 0 0,0 13,17A3,3 0 0,0 16,20A3,3 0 0,0 19,17V8H22V6H17Z"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
ICONS["music"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
|
<path d="M21,3V15.5A3.5,3.5 0 0,1 17.5,19A3.5,3.5 0 0,1 14,15.5A3.5,3.5 0 0,1 17.5,12C18.04,12 18.55,12.12 19,12.34V6.47L9,8.6V17.5A3.5,3.5 0 0,1 5.5,21A3.5,3.5 0 0,1 2,17.5A3.5,3.5 0 0,1 5.5,14C6.04,14 6.55,14.12 7,14.34V6L21,3Z"/>
|
||||||
|
</svg>`;
|
||||||
ICONS["repeat"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
ICONS["repeat"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
<path d="M17,17H7V14L3,18L7,22V19H19V13H17M7,7H17V10L21,6L17,2V5H5V11H7V7Z"/>
|
<path d="M17,17H7V14L3,18L7,22V19H19V13H17M7,7H17V10L21,6L17,2V5H5V11H7V7Z"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
ICONS["folder"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
|
<path d="M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z"/>
|
||||||
|
</svg>`;
|
||||||
ICONS["close-circle-outline"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
ICONS["close-circle-outline"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
<path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2C6.47,2 2,6.47 2,12C2,17.53 6.47,22 12,22C17.53,22 22,17.53 22,12C22,6.47 17.53,2 12,2M14.59,8L12,10.59L9.41,8L8,9.41L10.59,12L8,14.59L9.41,16L12,13.41L14.59,16L16,14.59L13.41,12L16,9.41L14.59,8Z"/>
|
<path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2C6.47,2 2,6.47 2,12C2,17.53 6.47,22 12,22C17.53,22 22,17.53 22,12C22,6.47 17.53,2 12,2M14.59,8L12,10.59L9.41,8L8,9.41L10.59,12L8,14.59L9.41,16L12,13.41L14.59,16L16,14.59L13.41,12L16,9.41L14.59,8Z"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
@ -59,6 +68,9 @@ ICONS["pause-circle-outline"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:x
|
||||||
ICONS["plus-circle-outline"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
ICONS["plus-circle-outline"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
<path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M13,7H11V11H7V13H11V17H13V13H17V11H13V7Z"/>
|
<path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M13,7H11V11H7V13H11V17H13V13H17V11H13V7Z"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
ICONS["download"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
|
<path d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z"/>
|
||||||
|
</svg>`;
|
||||||
ICONS["play-circle"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
ICONS["play-circle"] = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
|
||||||
<path d="M10,16.5V7.5L16,12M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"/>
|
<path d="M10,16.5V7.5L16,12M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
|
|
@ -30,9 +30,7 @@ function fileName(data) {
|
||||||
function formatTitle(ctx, data) {
|
function formatTitle(ctx, data) {
|
||||||
let tokens = [];
|
let tokens = [];
|
||||||
switch (ctx) {
|
switch (ctx) {
|
||||||
case CTX_FS:
|
case CTX_FS: return fileName(data); break;
|
||||||
return `🎵 ${fileName(data)}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CTX_LIBRARY:
|
case CTX_LIBRARY:
|
||||||
data["Track"] && tokens.push(data["Track"].padStart(2, "0"));
|
data["Track"] && tokens.push(data["Track"].padStart(2, "0"));
|
||||||
|
@ -108,8 +106,11 @@ function addButton(type, what, parent) {
|
||||||
export function song(ctx, data, parent) {
|
export function song(ctx, data, parent) {
|
||||||
let node = html.node("li", {}, "", parent);
|
let node = html.node("li", {}, "", parent);
|
||||||
|
|
||||||
|
|
||||||
let title = formatTitle(ctx, data);
|
let title = formatTitle(ctx, data);
|
||||||
html.node("h2", {}, title, node);
|
let h2 = html.node("h2", {}, "", node);
|
||||||
|
if (ctx == CTX_FS || ctx == CTX_LIBRARY) { html.icon("music", h2); }
|
||||||
|
html.text(title, h2);
|
||||||
|
|
||||||
html.node("span", {className:"duration"}, format.time(Number(data["duration"])), node);
|
html.node("span", {className:"duration"}, format.time(Number(data["duration"])), node);
|
||||||
|
|
||||||
|
@ -135,8 +136,9 @@ export function song(ctx, data, parent) {
|
||||||
export function group(ctx, label, urlOrFilter, parent) {
|
export function group(ctx, label, urlOrFilter, parent) {
|
||||||
let node = html.node("li", {}, "", parent);
|
let node = html.node("li", {}, "", parent);
|
||||||
|
|
||||||
if (ctx == CTX_FS) { label = `📁 ${label}`; }
|
let h2 = html.node("h2", {}, "", node);
|
||||||
html.node("h2", {}, label, node);
|
if (ctx == CTX_FS) { html.icon("folder", h2); }
|
||||||
|
html.text(label, h2);
|
||||||
|
|
||||||
let type = (ctx == CTX_FS ? TYPE_URL : TYPE_FILTER);
|
let type = (ctx == CTX_FS ? TYPE_URL : TYPE_FILTER);
|
||||||
|
|
||||||
|
@ -149,8 +151,9 @@ export function group(ctx, label, urlOrFilter, parent) {
|
||||||
export function playlist(name, parent) {
|
export function playlist(name, parent) {
|
||||||
let node = html.node("li", {}, "", parent);
|
let node = html.node("li", {}, "", parent);
|
||||||
|
|
||||||
html.icon("playlist-music", node)
|
let h2 = html.node("h2", {}, "", node);
|
||||||
html.node("h2", {}, name, node);
|
html.icon("playlist-music", h2)
|
||||||
|
html.text(name, h2);
|
||||||
|
|
||||||
playButton(TYPE_PLAYLIST, name, node);
|
playButton(TYPE_PLAYLIST, name, node);
|
||||||
addButton(TYPE_PLAYLIST, name, node);
|
addButton(TYPE_PLAYLIST, name, node);
|
||||||
|
|
|
@ -16,7 +16,7 @@ function sync(data) {
|
||||||
|
|
||||||
if (data["file"] != current["file"]) { // changed song
|
if (data["file"] != current["file"]) { // changed song
|
||||||
DOM.duration.textContent = format.time(Number(data["duration"] || 0));
|
DOM.duration.textContent = format.time(Number(data["duration"] || 0));
|
||||||
DOM.title.textContent = data["Title"] || "";
|
DOM.title.textContent = data["Title"] || data["file"].split("/").pop();
|
||||||
DOM["artist-album"].textContent = format.artistAlbum(data["Artist"], data["Album"]);
|
DOM["artist-album"].textContent = format.artistAlbum(data["Artist"], data["Album"]);
|
||||||
pubsub.publish("song-change", null, data);
|
pubsub.publish("song-change", null, data);
|
||||||
}
|
}
|
||||||
|
@ -76,12 +76,5 @@ export function init(n) {
|
||||||
DOM.random.addEventListener("click", e => command(`random ${current["random"] == "1" ? "0" : "1"}`));
|
DOM.random.addEventListener("click", e => command(`random ${current["random"] == "1" ? "0" : "1"}`));
|
||||||
DOM.repeat.addEventListener("click", e => command(`repeat ${current["repeat"] == "1" ? "0" : "1"}`));
|
DOM.repeat.addEventListener("click", e => command(`repeat ${current["repeat"] == "1" ? "0" : "1"}`));
|
||||||
|
|
||||||
DOM.play.appendChild(html.icon("play"));
|
|
||||||
DOM.pause.appendChild(html.icon("pause"));
|
|
||||||
DOM.prev.appendChild(html.icon("rewind"));
|
|
||||||
DOM.next.appendChild(html.icon("fast-forward"));
|
|
||||||
DOM.random.appendChild(html.icon("shuffle"));
|
|
||||||
DOM.repeat.appendChild(html.icon("repeat"));
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,16 +47,12 @@ export function init(n) {
|
||||||
pubsub.subscribe("song-change", onSongChange);
|
pubsub.subscribe("song-change", onSongChange);
|
||||||
pubsub.subscribe("queue-change", onQueueChange);
|
pubsub.subscribe("queue-change", onQueueChange);
|
||||||
|
|
||||||
let clear = node.querySelector(".clear");
|
node.querySelector(".clear").addEventListener("click", async e => {
|
||||||
clear.appendChild(html.icon("close"));
|
|
||||||
clear.addEventListener("click", async e => {
|
|
||||||
await mpd.command("clear");
|
await mpd.command("clear");
|
||||||
syncQueue();
|
syncQueue();
|
||||||
});
|
});
|
||||||
|
|
||||||
let save = node.querySelector(".save");
|
node.querySelector(".save").addEventListener("click", e => {
|
||||||
save.appendChild(html.icon("content-save"));
|
|
||||||
save.addEventListener("click", e => {
|
|
||||||
let name = prompt("Save current queue as a playlist?", "name");
|
let name = prompt("Save current queue as a playlist?", "name");
|
||||||
if (name === null) { return; }
|
if (name === null) { return; }
|
||||||
mpd.command(`save "${mpd.escape(name)}"`);
|
mpd.command(`save "${mpd.escape(name)}"`);
|
||||||
|
|
|
@ -22,5 +22,5 @@ export async function activate() {}
|
||||||
export function init(n) {
|
export function init(n) {
|
||||||
node = n;
|
node = n;
|
||||||
|
|
||||||
node.querySelector(".go").addEventListener("click", onClick);
|
let button = node.querySelector(".go").addEventListener("click", onClick);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue