This commit is contained in:
Ondrej Zara 2019-04-16 09:03:42 +02:00
parent 87a7c5680a
commit 1f5dd9d618
6 changed files with 33 additions and 22 deletions

View file

@ -2,6 +2,7 @@
CYP is a web-based frontend for [MPD](https://www.musicpd.org/), the Music Player Daemon. You can use it to control the playback without having to install native application(s). It works in modern web browsers, both desktop and mobile. CYP is a web-based frontend for [MPD](https://www.musicpd.org/), the Music Player Daemon. You can use it to control the playback without having to install native application(s). It works in modern web browsers, both desktop and mobile.
## Features ## Features
- Control the playback, queue, volume - Control the playback, queue, volume
- Save and load playlists - Save and load playlists
@ -9,6 +10,7 @@ CYP is a web-based frontend for [MPD](https://www.musicpd.org/), the Music Playe
- Display album art via native MPD calls (no need to access the library; requires MPD >= 0.21) - Display album art via native MPD calls (no need to access the library; requires MPD >= 0.21)
- [Youtube-dl](https://ytdl-org.github.io/youtube-dl/index.html) intergration - [Youtube-dl](https://ytdl-org.github.io/youtube-dl/index.html) intergration
## Installation ## Installation
Make sure you have a working MPD setup first. Make sure you have a working MPD setup first.
@ -21,16 +23,21 @@ node .
Point your browser to http://localhost:8080 to open the interface. Point your browser to http://localhost:8080 to open the interface.
## Technology ## Technology
- Connected to MPD via WebSockets (using the [ws2mpd](https://github.com/ondras/ws2mpd/) bridge) - Connected to MPD via WebSockets (using the [ws2mpd](https://github.com/ondras/ws2mpd/) bridge)
- Token-based access to the WebSocket endpoint (better than an `Origin` check)
- Modern ES6+ (modules, async/await) - Modern ES6+ (modules, async/await)
- Responsive layout via Flexbox - Responsive layout via Flexbox
- CSS Custom Properties
- SVG icons (Material Design) - SVG icons (Material Design)
- Dark/Light theme available - Dark/Light theme available
- Album art downloaded directly from MPD (and cached via localStorage) - Can spawn Youtube-dl to download audio files
- Album art retrieved directly from MPD (and cached via localStorage)
## TODO ## TODO
- [ ] Bundling - [ ] Bundling
- [ ] Range styling - [ ] Range styling
- [ ] Browser testing

View file

@ -14,15 +14,16 @@ body {
line-height: 1.25; line-height: 1.25;
background-color: var(--bg); background-color: var(--bg);
color: var(--fg); color: var(--fg);
text-shadow: var(--shadow); text-shadow: var(--text-shadow);
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
overflow: hidden; overflow: hidden;
height: 100vh; height: 100vh;
} }
body > header, header,
body > footer { footer {
box-shadow: 0 0 3px #000; z-index: 1;
box-shadow: var(--box-shadow);
} }
input, input,
select, select,
@ -280,7 +281,7 @@ nav ul li.active {
.component li .info .icon { .component li .info .icon {
color: var(--primary); color: var(--primary);
margin-right: var(--icon-spacing); margin-right: var(--icon-spacing);
filter: drop-shadow(var(--shadow)); filter: drop-shadow(var(--text-shadow));
} }
.component li .info h2 { .component li .info h2 {
font-size: var(--font-size-large); font-size: var(--font-size-large);
@ -339,7 +340,7 @@ nav ul li.active {
#queue li .info .icon { #queue li .info .icon {
color: var(--primary); color: var(--primary);
margin-right: var(--icon-spacing); margin-right: var(--icon-spacing);
filter: drop-shadow(var(--shadow)); filter: drop-shadow(var(--text-shadow));
} }
#queue li .info h2 { #queue li .info h2 {
font-size: var(--font-size-large); font-size: var(--font-size-large);
@ -401,7 +402,7 @@ nav ul li.active {
#library li .info .icon { #library li .info .icon {
color: var(--primary); color: var(--primary);
margin-right: var(--icon-spacing); margin-right: var(--icon-spacing);
filter: drop-shadow(var(--shadow)); filter: drop-shadow(var(--text-shadow));
} }
#library li .info h2 { #library li .info h2 {
font-size: var(--font-size-large); font-size: var(--font-size-large);
@ -436,7 +437,7 @@ nav ul li.active {
width: 64px; width: 64px;
} }
#library .art .icon { #library .art .icon {
filter: drop-shadow(var(--shadow)); filter: drop-shadow(var(--text-shadow));
} }
#library .group { #library .group {
cursor: pointer; cursor: pointer;
@ -497,7 +498,7 @@ nav ul li.active {
#fs li .info .icon { #fs li .info .icon {
color: var(--primary); color: var(--primary);
margin-right: var(--icon-spacing); margin-right: var(--icon-spacing);
filter: drop-shadow(var(--shadow)); filter: drop-shadow(var(--text-shadow));
} }
#fs li .info h2 { #fs li .info h2 {
font-size: var(--font-size-large); font-size: var(--font-size-large);
@ -576,7 +577,7 @@ nav ul li.active {
#playlists li .info .icon { #playlists li .info .icon {
color: var(--primary); color: var(--primary);
margin-right: var(--icon-spacing); margin-right: var(--icon-spacing);
filter: drop-shadow(var(--shadow)); filter: drop-shadow(var(--text-shadow));
} }
#playlists li .info h2 { #playlists li .info h2 {
font-size: var(--font-size-large); font-size: var(--font-size-large);
@ -643,7 +644,7 @@ nav ul li.active {
#yt li .info .icon { #yt li .info .icon {
color: var(--primary); color: var(--primary);
margin-right: var(--icon-spacing); margin-right: var(--icon-spacing);
filter: drop-shadow(var(--shadow)); filter: drop-shadow(var(--text-shadow));
} }
#yt li .info h2 { #yt li .info h2 {
font-size: var(--font-size-large); font-size: var(--font-size-large);
@ -759,18 +760,19 @@ nav ul li.active {
--icon-spacing: 4px; --icon-spacing: 4px;
--primary: rgb(var(--primary-raw)); --primary: rgb(var(--primary-raw));
--spacing: 8px; --spacing: 8px;
--box-shadow: 0 0 3px #000;
} }
:root[data-theme=light] { :root[data-theme=light] {
--fg: #333; --fg: #333;
--bg: #f0f0f0; --bg: #f0f0f0;
--bg-alt: #e0e0e0; --bg-alt: #e0e0e0;
--shadow: none; --text-shadow: none;
} }
:root[data-theme=dark] { :root[data-theme=dark] {
--fg: #f0f0f0; --fg: #f0f0f0;
--bg: #333; --bg: #333;
--bg-alt: #555; --bg-alt: #555;
--shadow: 0 1px 1px rgba(0, 0, 0, 0.8); --text-shadow: 0 1px 1px rgba(0, 0, 0, 0.8);
} }
:root[data-color=dodgerblue] { :root[data-color=dodgerblue] {
--primary-raw: 30, 144, 255; --primary-raw: 30, 144, 255;

View file

@ -12,15 +12,16 @@ body {
line-height: 1.25; line-height: 1.25;
background-color: var(--bg); background-color: var(--bg);
color: var(--fg); color: var(--fg);
text-shadow: var(--shadow); text-shadow: var(--text-shadow);
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
overflow: hidden; overflow: hidden;
height: 100vh; height: 100vh;
}
> header, > footer { header, footer {
box-shadow: 0 0 3px #000; z-index: 1;
} box-shadow: var(--box-shadow);
} }
input, select, button { input, select, button {

View file

@ -33,7 +33,7 @@
.icon { .icon {
color: var(--primary); color: var(--primary);
margin-right: var(--icon-spacing); margin-right: var(--icon-spacing);
filter: drop-shadow(var(--shadow)); filter: drop-shadow(var(--text-shadow));
} }
h2 { h2 {

View file

@ -15,7 +15,7 @@
} }
.art .icon { .art .icon {
filter: drop-shadow(var(--shadow)); filter: drop-shadow(var(--text-shadow));
} }
.group { .group {

View file

@ -3,20 +3,21 @@
--icon-spacing: 4px; --icon-spacing: 4px;
--primary: rgb(var(--primary-raw)); --primary: rgb(var(--primary-raw));
--spacing: 8px; --spacing: 8px;
--box-shadow: 0 0 3px #000;
} }
:root[data-theme=light] { :root[data-theme=light] {
--fg: #333; --fg: #333;
--bg: #f0f0f0; --bg: #f0f0f0;
--bg-alt: #e0e0e0; --bg-alt: #e0e0e0;
--shadow: none; --text-shadow: none;
} }
:root[data-theme=dark] { :root[data-theme=dark] {
--fg: #f0f0f0; --fg: #f0f0f0;
--bg: #333; --bg: #333;
--bg-alt: #555; --bg-alt: #555;
--shadow: 0 1px 1px rgba(0, 0, 0, 0.8); --text-shadow: 0 1px 1px rgba(0, 0, 0, 0.8);
} }
:root[data-color=dodgerblue] { :root[data-color=dodgerblue] {