settings
This commit is contained in:
parent
0873dcfe11
commit
ba4b7fdc3c
9 changed files with 194 additions and 18 deletions
64
app/app.css
64
app/app.css
|
@ -45,6 +45,12 @@ button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
select {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid var(--fg);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Lato';
|
font-family: 'Lato';
|
||||||
src: url('font/LatoLatin-Regular.woff2') format('woff2');
|
src: url('font/LatoLatin-Regular.woff2') format('woff2');
|
||||||
|
@ -218,7 +224,7 @@ nav ul li.active {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
.component li:nth-child(odd) {
|
.component li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: var(--bg-alt);
|
||||||
}
|
}
|
||||||
#queue {
|
#queue {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -276,7 +282,7 @@ nav ul li.active {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
#queue li:nth-child(odd) {
|
#queue li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: var(--bg-alt);
|
||||||
}
|
}
|
||||||
#queue .current {
|
#queue .current {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
|
@ -337,7 +343,7 @@ nav ul li.active {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
#library li:nth-child(odd) {
|
#library li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: var(--bg-alt);
|
||||||
}
|
}
|
||||||
#library header {
|
#library header {
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
|
@ -432,7 +438,7 @@ nav ul li.active {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
#fs li:nth-child(odd) {
|
#fs li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: var(--bg-alt);
|
||||||
}
|
}
|
||||||
#fs header {
|
#fs header {
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
|
@ -510,7 +516,7 @@ nav ul li.active {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
#playlists li:nth-child(odd) {
|
#playlists li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: var(--bg-alt);
|
||||||
}
|
}
|
||||||
#playlists .info {
|
#playlists .info {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -578,7 +584,7 @@ nav ul li.active {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
#yt li:nth-child(odd) {
|
#yt li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: var(--bg-alt);
|
||||||
}
|
}
|
||||||
#yt .go {
|
#yt .go {
|
||||||
width: 96px;
|
width: 96px;
|
||||||
|
@ -611,6 +617,27 @@ nav ul li.active {
|
||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#settings dl {
|
||||||
|
margin: 8px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: max-content 1fr;
|
||||||
|
align-items: center;
|
||||||
|
grid-gap: 8px;
|
||||||
|
}
|
||||||
|
#settings dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
#settings dd {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
#settings label {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
.search {
|
.search {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -645,10 +672,27 @@ nav ul li.active {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
:root {
|
:root {
|
||||||
--primary: dodgerblue;
|
|
||||||
--fg: #fff;
|
|
||||||
--bg: #333;
|
|
||||||
--shadow: 0 1px 1px rgba(0, 0, 0, 0.8);
|
|
||||||
--font-size-large: 112.5%;
|
--font-size-large: 112.5%;
|
||||||
--icon-spacing: 4px;
|
--icon-spacing: 4px;
|
||||||
}
|
}
|
||||||
|
:root[data-theme=light] {
|
||||||
|
--fg: #000;
|
||||||
|
--bg: #fff;
|
||||||
|
--bg-alt: #eee;
|
||||||
|
--shadow: none;
|
||||||
|
}
|
||||||
|
:root[data-theme=dark] {
|
||||||
|
--fg: #fff;
|
||||||
|
--bg: #333;
|
||||||
|
--bg-alt: #555;
|
||||||
|
--shadow: 0 1px 1px rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
:root[data-color=dodgerblue] {
|
||||||
|
--primary: dodgerblue;
|
||||||
|
}
|
||||||
|
:root[data-color=darkorange] {
|
||||||
|
--primary: darkorange;
|
||||||
|
}
|
||||||
|
:root[data-color=limegreen] {
|
||||||
|
--primary: limegreen;
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,13 @@ button {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid var(--fg);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
@import "font.less";
|
@import "font.less";
|
||||||
@import "icons.less";
|
@import "icons.less";
|
||||||
@import "mixins.less";
|
@import "mixins.less";
|
||||||
|
@ -56,6 +63,7 @@ button {
|
||||||
@import "fs.less";
|
@import "fs.less";
|
||||||
@import "playlists.less";
|
@import "playlists.less";
|
||||||
@import "yt.less";
|
@import "yt.less";
|
||||||
|
@import "settings.less";
|
||||||
@import "search.less";
|
@import "search.less";
|
||||||
@import "art.less";
|
@import "art.less";
|
||||||
@import "variables.less";
|
@import "variables.less";
|
||||||
|
|
|
@ -55,6 +55,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
li:nth-child(odd) {
|
li:nth-child(odd) {
|
||||||
background-color: #555;
|
background-color: var(--bg-alt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
23
app/css/settings.less
Normal file
23
app/css/settings.less
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#settings {
|
||||||
|
dl {
|
||||||
|
margin: 8px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: max-content 1fr;
|
||||||
|
align-items: center;
|
||||||
|
grid-gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin: 0;
|
||||||
|
.flex-column;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
.flex-row;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,30 @@
|
||||||
:root {
|
:root {
|
||||||
--primary: dodgerblue;
|
|
||||||
--fg: #fff;
|
|
||||||
--bg: #333;
|
|
||||||
--shadow: 0 1px 1px rgba(0, 0, 0, 0.8);
|
|
||||||
|
|
||||||
--font-size-large: 112.5%;
|
--font-size-large: 112.5%;
|
||||||
--icon-spacing: 4px;
|
--icon-spacing: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:root[data-theme=light] {
|
||||||
|
--fg: #000;
|
||||||
|
--bg: #fff;
|
||||||
|
--bg-alt: #eee;
|
||||||
|
--shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme=dark] {
|
||||||
|
--fg: #fff;
|
||||||
|
--bg: #333;
|
||||||
|
--bg-alt: #555;
|
||||||
|
--shadow: 0 1px 1px rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-color=dodgerblue] {
|
||||||
|
--primary: dodgerblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-color=darkorange] {
|
||||||
|
--primary: darkorange;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-color=limegreen] {
|
||||||
|
--primary: limegreen;
|
||||||
|
}
|
||||||
|
|
|
@ -52,6 +52,32 @@
|
||||||
<button class="go" data-icon="download">Go!</button>
|
<button class="go" data-icon="download">Go!</button>
|
||||||
<p></p>
|
<p></p>
|
||||||
</section>
|
</section>
|
||||||
|
<section id="settings">
|
||||||
|
<dl>
|
||||||
|
<dt>Theme</dt>
|
||||||
|
<dd>
|
||||||
|
<select name="theme">
|
||||||
|
<option value="dark">Dark</option>
|
||||||
|
<option value="light">Light</option>
|
||||||
|
</select>
|
||||||
|
</dd>
|
||||||
|
<dt>Color</dt>
|
||||||
|
<dd>
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="color" value="dodgerblue" />
|
||||||
|
Blue
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="color" value="darkorange" />
|
||||||
|
Orange
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="color" value="limegreen" />
|
||||||
|
Green
|
||||||
|
</label>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</section>
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
<nav>
|
<nav>
|
||||||
|
|
|
@ -8,8 +8,9 @@ import * as library from "./library.js";
|
||||||
import * as fs from "./fs.js";
|
import * as fs from "./fs.js";
|
||||||
import * as playlists from "./playlists.js";
|
import * as playlists from "./playlists.js";
|
||||||
import * as yt from "./yt.js";
|
import * as yt from "./yt.js";
|
||||||
|
import * as settings from "./settings.js";
|
||||||
|
|
||||||
const components = { queue, library, fs, playlists, yt };
|
const components = { queue, library, fs, playlists, yt, settings };
|
||||||
|
|
||||||
export function activate(what) {
|
export function activate(what) {
|
||||||
location.hash = what;
|
location.hash = what;
|
||||||
|
|
|
@ -62,7 +62,10 @@ export async function command(cmd) {
|
||||||
|
|
||||||
export async function commandAndStatus(cmd) {
|
export async function commandAndStatus(cmd) {
|
||||||
let lines = await command([cmd, "status", "currentsong"]);
|
let lines = await command([cmd, "status", "currentsong"]);
|
||||||
return parser.linesToStruct(lines);
|
let status = parser.linesToStruct(lines);
|
||||||
|
// duration returned 2x => arrayfied
|
||||||
|
if ("duration" in status) { status["duration"] = status["duration"][0]; }
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function status() {
|
export async function status() {
|
||||||
|
|
50
app/js/settings.js
Normal file
50
app/js/settings.js
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
let node;
|
||||||
|
let inputs = {};
|
||||||
|
const prefix = "cyp";
|
||||||
|
|
||||||
|
function loadFromStorage(key, def) {
|
||||||
|
return localStorage.getItem(`${prefix}-${key}`) || def;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveToStorage(key, value) {
|
||||||
|
return localStorage.setItem(`${prefix}-${key}`, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function load() {
|
||||||
|
let theme = loadFromStorage("theme", "dark");
|
||||||
|
inputs.theme.value = theme;
|
||||||
|
setTheme(theme);
|
||||||
|
|
||||||
|
let color = loadFromStorage("color", "dodgerblue");
|
||||||
|
inputs.color.forEach(input => {
|
||||||
|
input.checked = (input.value == color);
|
||||||
|
input.parentNode.style.color = input.value;
|
||||||
|
});
|
||||||
|
setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTheme(theme) {
|
||||||
|
saveToStorage("theme", theme);
|
||||||
|
document.documentElement.dataset.theme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setColor(color) {
|
||||||
|
saveToStorage("color", color);
|
||||||
|
document.documentElement.dataset.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function activate() {}
|
||||||
|
|
||||||
|
export function init(n) {
|
||||||
|
node = n;
|
||||||
|
|
||||||
|
inputs.theme = n.querySelector("[name=theme]");
|
||||||
|
inputs.color = Array.from(n.querySelectorAll("[name=color]"));
|
||||||
|
|
||||||
|
load();
|
||||||
|
|
||||||
|
inputs.theme.addEventListener("change", e => setTheme(e.target.value));
|
||||||
|
inputs.color.forEach(input => {
|
||||||
|
input.addEventListener("click", e => setColor(e.target.value));
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in a new issue