From d91a6ca8589c137e72841c0a8a7002702cab521b Mon Sep 17 00:00:00 2001 From: Ondrej Zara Date: Tue, 10 Mar 2020 22:11:36 +0100 Subject: [PATCH] song playback in queue, item style --- Makefile | 2 +- app/css/cyp.less | 3 +- app/css/elements/settings.less | 2 + app/css/mixins.less | 9 + app/css/variables.less | 7 - app/cyp.css | 861 +-------------------------------- app/js/component.js | 5 + app/js/elements/playlist.js | 4 +- app/js/elements/queue.js | 10 +- app/js/elements/song.js | 5 - app/js/mpd-mock.js | 2 +- 11 files changed, 32 insertions(+), 878 deletions(-) diff --git a/Makefile b/Makefile index fb6d038..5e35d38 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ $(ICONS): $(APP)/icons/* $(APP)/svg2js.sh $(APP)/icons > $@ $(CSS): $(APP)/css/* $(APP)/css/elements/* - $(LESS) $(APP)/css/cyp.less > $@ + $(LESS) -x $(APP)/css/cyp.less > $@ service: $(SERVICE) systemctl --user enable $(PWD)/$(SERVICE) diff --git a/app/css/cyp.less b/app/css/cyp.less index 1cb12bb..aa27959 100644 --- a/app/css/cyp.less +++ b/app/css/cyp.less @@ -20,7 +20,8 @@ header, footer { } footer { - position: relative; + position: relative; // kotva pro cyp-commands + overflow: hidden; // vyjizdenici cyp-commands height: 56px; @media (max-width: @breakpoint-menu) { height: 40px; diff --git a/app/css/elements/settings.less b/app/css/elements/settings.less index 98594f6..79baf07 100644 --- a/app/css/elements/settings.less +++ b/app/css/elements/settings.less @@ -1,4 +1,6 @@ cyp-settings { + --spacing: 8px; + font-size: var(--font-size-large); dl { diff --git a/app/css/mixins.less b/app/css/mixins.less index 627b1b1..c270869 100644 --- a/app/css/mixins.less +++ b/app/css/mixins.less @@ -34,6 +34,7 @@ .item { .flex-row; .selectable; + padding: 8px; padding-left: calc(8px - var(--border-width)); @@ -41,5 +42,13 @@ background-color: var(--bg-alt); } + > .icon { margin-right: var(--icon-spacing); } + + .title { + font-size: var(--font-size-large); + flex-grow: 1; + min-width: 0; // bez tohoto se odmita zmensit + } + button .icon { width: 32px; } } diff --git a/app/css/variables.less b/app/css/variables.less index 42f8414..50567ba 100644 --- a/app/css/variables.less +++ b/app/css/variables.less @@ -4,7 +4,6 @@ cyp-app { --font-size-large: 112.5%; --icon-spacing: 4px; --primary: rgb(var(--primary-raw)); - --spacing: 8px; --box-shadow: 0 0 3px #000; --border-width: 4px; } @@ -45,9 +44,3 @@ cyp-app[color=darkorange] { cyp-app[color=limegreen] { --primary-raw: 50, 205, 50; } - -@media (max-width: @breakpoint-menu) { - :root { - --spacing: var(--icon-spacing); - } -} diff --git a/app/cyp.css b/app/cyp.css index 8825a76..76dc76f 100644 --- a/app/cyp.css +++ b/app/cyp.css @@ -1,860 +1 @@ -*, -*::before, -*::after { - box-sizing: inherit; -} -html { - background-color: var(--fg); -} -body { - margin: 0; -} -main { - flex-grow: 1; - overflow: auto; -} -header, -footer { - flex-shrink: 0; - z-index: 1; - box-shadow: var(--box-shadow); -} -footer { - position: relative; - height: 56px; -} -@media (max-width: 480px) { - footer { - height: 40px; - } -} -input, -select, -button { - color: inherit; - font: inherit; -} -button { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - flex-direction: row; - align-items: center; - display: inline-flex; - flex-shrink: 0; - background-color: transparent; - padding: 0; - border: none; - line-height: 1; - cursor: pointer; -} -button:not([hidden]) { - display: flex; -} -@media (hover: hover) { - button:not(:disabled):not(:hover):not(.-thumb) { - opacity: 0.9; - } -} -select { - background-color: transparent; - border: 1px solid var(--fg); - border-radius: 4px; - padding: 2px 4px; -} -@font-face { - font-family: "Lato"; - src: url("font/LatoLatin-Regular.woff2") format("woff2"); - font-style: normal; - font-weight: normal; -} -@font-face { - font-family: "Lato"; - src: url("font/LatoLatin-Bold.woff2") format("woff2"); - font-style: bold; - font-weight: normal; -} -.icon { - width: 24px; -} -.icon path:not([fill]), -.icon polygon:not([fill]), -.icon circle:not([fill]) { - fill: currentColor; -} -.flex-row { - flex-direction: row; - align-items: center; -} -.flex-row:not([hidden]) { - display: flex; -} -.flex-column { - flex-direction: column; -} -.flex-column:not([hidden]) { - display: flex; -} -.ellipsis { - overflow: hidden; - text-overflow: ellipsis; -} -/* -.multiline { - .flex-row; - - h2 { font-weight: normal; } -} -*/ -.selectable { - border-left: var(--border-width) solid transparent; - cursor: pointer; -} -.selectable.selected { - border-left-color: var(--primary); -} -.item { - flex-direction: row; - align-items: center; - border-left: var(--border-width) solid transparent; - cursor: pointer; - padding: 8px; - padding-left: calc(8px - var(--border-width)); -} -.item:not([hidden]) { - display: flex; -} -.item.selected { - border-left-color: var(--primary); -} -.item:nth-child(odd) { - background-color: var(--bg-alt); -} -.item button .icon { - width: 32px; -} -.component header { - flex-direction: row; - align-items: center; - padding: var(--spacing); -} -.component header:not([hidden]) { - display: flex; -} -.component header button { - font-size: var(--font-size-large); - font-weight: bold; - overflow: hidden; -} -.component header button .icon { - margin-right: var(--icon-spacing); -} -.component ul { - flex-grow: 1; - overflow: auto; - list-style: none; - margin: 0; - padding: 0; -} -.component li { - flex-direction: row; - align-items: center; -} -.component li:not([hidden]) { - display: flex; -} -.component li .info { - flex-grow: 1; - overflow: hidden; -} -.component li .info .icon { - color: var(--primary); - margin-right: var(--icon-spacing); - filter: drop-shadow(var(--text-shadow)); -} -.component li .info h2 { - font-size: var(--font-size-large); - margin: 0; -} -.component li:not(.has-art) { - padding: 8px; -} -.component li button .icon { - width: 32px; -} -.component li:nth-child(odd) { - background-color: var(--bg-alt); -} -#library header { - flex-direction: row; - align-items: center; - padding: var(--spacing); -} -#library header:not([hidden]) { - display: flex; -} -#library header button { - font-size: var(--font-size-large); - font-weight: bold; - overflow: hidden; -} -#library header button .icon { - margin-right: var(--icon-spacing); -} -#library ul { - flex-grow: 1; - overflow: auto; - list-style: none; - margin: 0; - padding: 0; -} -#library li { - flex-direction: row; - align-items: center; -} -#library li:not([hidden]) { - display: flex; -} -#library li .info { - flex-grow: 1; - overflow: hidden; -} -#library li .info .icon { - color: var(--primary); - margin-right: var(--icon-spacing); - filter: drop-shadow(var(--text-shadow)); -} -#library li .info h2 { - font-size: var(--font-size-large); - margin: 0; -} -#library li:not(.has-art) { - padding: 8px; -} -#library li button .icon { - width: 32px; -} -#library li:nth-child(odd) { - background-color: var(--bg-alt); -} -#library header { - white-space: pre; -} -#library .search { - order: 1; -} -#library .search.open ~ * { - display: none; -} -#library .art img, -#library .art .icon { - width: 64px; -} -#library .art .icon { - filter: drop-shadow(var(--text-shadow)); -} -#library .group { - cursor: pointer; -} -#library .group h2 { - font-weight: normal; -} -#library .tiles { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - grid-gap: 2px; -} -#library .tiles li { - 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 header { - flex-direction: row; - align-items: center; - padding: var(--spacing); -} -#fs header:not([hidden]) { - display: flex; -} -#fs header button { - font-size: var(--font-size-large); - font-weight: bold; - overflow: hidden; -} -#fs header button .icon { - margin-right: var(--icon-spacing); -} -#fs ul { - flex-grow: 1; - overflow: auto; - list-style: none; - margin: 0; - padding: 0; -} -#fs li { - flex-direction: row; - align-items: center; -} -#fs li:not([hidden]) { - display: flex; -} -#fs li .info { - flex-grow: 1; - overflow: hidden; -} -#fs li .info .icon { - color: var(--primary); - margin-right: var(--icon-spacing); - filter: drop-shadow(var(--text-shadow)); -} -#fs li .info h2 { - font-size: var(--font-size-large); - margin: 0; -} -#fs li:not(.has-art) { - padding: 8px; -} -#fs li button .icon { - width: 32px; -} -#fs li:nth-child(odd) { - background-color: var(--bg-alt); -} -#fs header { - white-space: pre; -} -#fs .search { - order: 1; -} -#fs .search.open ~ * { - display: none; -} -#fs .group { - cursor: pointer; -} -.search { - flex-direction: row; - align-items: center; - margin-left: auto; - transition: all 300ms; - width: 32px; - max-width: 20ch; -} -.search:not([hidden]) { - display: flex; -} -.search .icon { - width: 32px; - cursor: pointer; -} -.search input { - border: none; - outline: none; - color: inherit; - background-color: inherit; - border-bottom: 1px solid var(--fg); - width: 0; - padding: 0; - flex-grow: 1; -} -.search.open { - flex: 1; -} -.art { - margin-right: var(--icon-spacing); -} -.art .icon, -.art img { - vertical-align: top; -} -cyp-app { - --font-size-large: 112.5%; - --icon-spacing: 4px; - --primary: rgb(var(--primary-raw)); - --spacing: 8px; - --box-shadow: 0 0 3px #000; - --border-width: 4px; -} -cyp-app[theme=light] { - --fg: #333; - --bg: #f0f0f0; - --bg-alt: #e0e0e0; - --text-shadow: none; -} -cyp-app[theme=dark] { - --fg: #f0f0f0; - --bg: #333; - --bg-alt: #555; - --text-shadow: 0 1px 1px rgba(0, 0, 0, 0.8); -} -@media (prefers-color-scheme: dark) { - cyp-app[theme=auto] { - --fg: #f0f0f0; - --bg: #333; - --bg-alt: #555; - --text-shadow: 0 1px 1px rgba(0, 0, 0, 0.8); - } -} -@media (prefers-color-scheme: light) { - cyp-app[theme=auto] { - --fg: #333; - --bg: #f0f0f0; - --bg-alt: #e0e0e0; - --text-shadow: none; - } -} -cyp-app[color=dodgerblue] { - --primary-raw: 30, 144, 255; -} -cyp-app[color=darkorange] { - --primary-raw: 255, 140, 0; -} -cyp-app[color=limegreen] { - --primary-raw: 50, 205, 50; -} -@media (max-width: 480px) { - :root { - --spacing: var(--icon-spacing); - } -} -cyp-app { - flex-direction: column; - box-sizing: border-box; - margin: 0 auto; - max-width: 800px; - height: 100vh; - font-family: lato, sans-serif; - line-height: 1.25; - background-color: var(--bg); - color: var(--fg); - text-shadow: var(--text-shadow); - white-space: nowrap; -} -cyp-app:not([hidden]) { - display: flex; -} -cyp-menu, -cyp-commands { - flex-direction: row; - align-items: center; - height: 100%; -} -cyp-menu:not([hidden]), -cyp-commands:not([hidden]) { - display: flex; -} -cyp-menu button, -cyp-commands button { - height: 100%; - flex-direction: column; - align-items: center; - justify-content: center; -} -cyp-menu button:not([hidden]), -cyp-commands button:not([hidden]) { - display: flex; -} -@media (max-width: 480px) { - cyp-menu button, - cyp-commands button { - flex-direction: row; - } - cyp-menu button span:not([id]), - cyp-commands button span:not([id]) { - display: none; - } -} -cyp-menu button { - flex: 1 0 0; - border-top: var(--border-width) solid transparent; - border-bottom: var(--border-width) solid transparent; -} -cyp-menu button .icon { - margin-right: var(--icon-spacing); -} -cyp-menu button.active { - border-top-color: var(--primary); - color: var(--primary); - background-color: rgb(var(--primary-raw), 0.1); -} -cyp-commands { - position: absolute; - left: 0; - top: 0; - width: 100%; - transition: top 300ms; - background-color: var(--bg); -} -cyp-commands[hidden] { - display: flex; - top: 100%; -} -cyp-commands button { - flex: 0 1 80px; -} -cyp-commands button.last { - order: 1; - margin-left: auto; -} -cyp-song { - flex-direction: row; - align-items: center; - border-left: var(--border-width) solid transparent; - cursor: pointer; - padding: 8px; - padding-left: calc(8px - var(--border-width)); -} -cyp-song:not([hidden]) { - display: flex; -} -cyp-song.selected { - border-left-color: var(--primary); -} -cyp-song:nth-child(odd) { - background-color: var(--bg-alt); -} -cyp-song button .icon { - width: 32px; -} -cyp-song .info { - flex-grow: 1; - min-width: 0; -} -cyp-song .info .icon { - color: var(--primary); - margin-right: var(--icon-spacing); - filter: drop-shadow(var(--text-shadow)); -} -cyp-song .info h2 { - font-size: var(--font-size-large); - margin: 0; -} -cyp-song .info h2, -cyp-song .info div { - overflow: hidden; - text-overflow: ellipsis; -} -cyp-player { - flex-direction: row; - align-items: center; - align-items: stretch; -} -cyp-player:not([hidden]) { - display: flex; -} -cyp-player:not([data-state=play]) .pause { - display: none; -} -cyp-player[data-state=play] .play { - display: none; -} -cyp-player:not([data-flags~=random]) .random, -cyp-player:not([data-flags~=repeat]) .repeat { - opacity: 0.5; -} -cyp-player x-range { - flex-grow: 1; - --elapsed-color: var(--primary); -} -cyp-player .art { - margin-right: 0; - height: 96px; -} -cyp-player .art img, -cyp-player .art .icon { - width: 96px; -} -cyp-player .info { - flex-grow: 2; - flex-basis: 0; - padding: 0 var(--icon-spacing); - overflow: hidden; - flex-direction: column; - justify-content: space-around; -} -cyp-player .info:not([hidden]) { - display: flex; -} -cyp-player .info h2 { - font-size: 125%; - margin: 0; -} -cyp-player .info .title, -cyp-player .info .subtitle { - overflow: hidden; - text-overflow: ellipsis; -} -cyp-player .timeline { - flex-direction: row; - align-items: center; -} -cyp-player .timeline:not([hidden]) { - display: flex; -} -cyp-player .timeline .duration, -cyp-player .timeline .elapsed { - flex-basis: 5ch; - text-align: center; -} -cyp-player .controls { - flex-grow: 1; - flex-basis: 0; - max-width: 220px; - flex-direction: column; - justify-content: space-around; -} -cyp-player .controls:not([hidden]) { - display: flex; -} -cyp-player .controls .playback { - flex-direction: row; - align-items: center; - justify-content: space-around; -} -cyp-player .controls .playback:not([hidden]) { - display: flex; -} -cyp-player .controls .playback .icon { - width: 40px; -} -cyp-player .controls .playback .icon-play, -cyp-player .controls .playback .icon-pause { - width: 64px; -} -cyp-player .controls .volume { - flex-direction: row; - align-items: center; -} -cyp-player .controls .volume:not([hidden]) { - display: flex; -} -cyp-player .controls .volume .mute { - margin-right: 4px; -} -cyp-player .misc { - display: flex; - flex-direction: column; - align-self: stretch; - justify-content: space-around; -} -cyp-player .misc .icon { - width: 32px; -} -@media (max-width: 519px) { - cyp-player { - flex-wrap: wrap; - justify-content: space-between; - } - cyp-player .info { - order: 1; - flex-basis: 100%; - height: 96px; - } -} -cyp-queue .current { - color: var(--primary); -} -cyp-settings { - font-size: var(--font-size-large); -} -cyp-settings dl { - margin: var(--spacing); - display: grid; - grid-template-columns: max-content 1fr; - align-items: center; - grid-gap: var(--spacing); -} -cyp-settings dt { - font-weight: bold; -} -cyp-settings dd { - margin: 0; - flex-direction: column; - align-items: start; -} -cyp-settings dd:not([hidden]) { - display: flex; -} -cyp-settings label { - flex-direction: row; - align-items: center; -} -cyp-settings label:not([hidden]) { - display: flex; -} -cyp-settings label [type=radio], -cyp-settings label [type=checkbox] { - margin: 0 4px 0 0; -} -cyp-yt header { - flex-direction: row; - align-items: center; - padding: var(--spacing); -} -cyp-yt header:not([hidden]) { - display: flex; -} -cyp-yt header button { - font-size: var(--font-size-large); - font-weight: bold; - overflow: hidden; -} -cyp-yt header button .icon { - margin-right: var(--icon-spacing); -} -cyp-yt ul { - flex-grow: 1; - overflow: auto; - list-style: none; - margin: 0; - padding: 0; -} -cyp-yt li { - flex-direction: row; - align-items: center; -} -cyp-yt li:not([hidden]) { - display: flex; -} -cyp-yt li .info { - flex-grow: 1; - overflow: hidden; -} -cyp-yt li .info .icon { - color: var(--primary); - margin-right: var(--icon-spacing); - filter: drop-shadow(var(--text-shadow)); -} -cyp-yt li .info h2 { - font-size: var(--font-size-large); - margin: 0; -} -cyp-yt li:not(.has-art) { - padding: 8px; -} -cyp-yt li button .icon { - width: 32px; -} -cyp-yt li:nth-child(odd) { - background-color: var(--bg-alt); -} -cyp-yt header { - border-bottom: 1px solid var(--fg); -} -cyp-yt header button + button { - margin-left: 16px; -} -cyp-yt .clear { - margin-left: auto; -} -cyp-yt pre { - margin: 0.5em 0.5ch; - flex-grow: 1; - overflow: auto; - white-space: pre-wrap; -} -cyp-yt.pending header { - background-image: linear-gradient(var(--primary), var(--primary)); - background-repeat: no-repeat; - background-size: 25% 4px; - animation: bar ease-in-out 3s alternate infinite; -} -@keyframes bar { - 0% { - background-position: 0 100%; - } - 100% { - background-position: 100% 100%; - } -} -x-range { - --thumb-size: 8px; - --thumb-color: #ddd; - --thumb-shadow: #000; - --thumb-hover-color: #fff; - --track-size: 4px; - --track-color: #888; - --track-shadow: #000; - --elapsed-color: #ddd; - --remaining-color: transparent; - --radius: calc(var(--track-size)/2); - display: inline-block; - position: relative; - width: 192px; - height: 16px; -} -x-range .-track, -x-range .-elapsed, -x-range .-remaining { - position: absolute; - top: calc(50% - var(--track-size)/2); - height: var(--track-size); - border-radius: var(--radius); -} -x-range .-track { - width: 100%; - left: 0; - background-color: var(--track-color); - box-shadow: 0 0 1px var(--thumb-shadow); -} -x-range .-elapsed { - left: 0; - background-color: var(--elapsed-color); -} -x-range .-remaining { - right: 0; - background-color: var(--remaining-color); -} -x-range .-inner { - position: absolute; - left: var(--thumb-size); - right: var(--thumb-size); - top: 0; - bottom: 0; -} -x-range .-thumb { - all: unset; - position: absolute; - top: 50%; - transform: translate(-50%, -50%); - border-radius: 50%; - width: calc(2*var(--thumb-size)); - height: calc(2*var(--thumb-size)); - background-color: var(--thumb-color); - box-shadow: 0 0 2px var(--thumb-shadow); -} -x-range[disabled] { - opacity: 0.5; -} -x-range:not([disabled]) .-thumb:hover { - background-color: var(--thumb-hover-color); -} -cyp-playlist { - flex-direction: row; - align-items: center; - border-left: var(--border-width) solid transparent; - cursor: pointer; - padding: 8px; - padding-left: calc(8px - var(--border-width)); -} -cyp-playlist:not([hidden]) { - display: flex; -} -cyp-playlist.selected { - border-left-color: var(--primary); -} -cyp-playlist:nth-child(odd) { - background-color: var(--bg-alt); -} -cyp-playlist button .icon { - width: 32px; -} -cyp-playlist:nth-child(odd) { - background-color: var(--bg-alt); -} +*,*::before,*::after{box-sizing:inherit}html{background-color:var(--fg)}body{margin:0}main{flex-grow:1;overflow:auto}header,footer{flex-shrink:0;z-index:1;box-shadow:var(--box-shadow)}footer{position:relative;overflow:hidden;height:56px}@media (max-width:480px){footer{height:40px}}input,select,button{color:inherit;font:inherit}button{-webkit-appearance:none;-moz-appearance:none;appearance:none;flex-direction:row;align-items:center;display:inline-flex;flex-shrink:0;background-color:transparent;padding:0;border:none;line-height:1;cursor:pointer}button:not([hidden]){display:flex}@media (hover:hover){button:not(:disabled):not(:hover):not(.-thumb){opacity:.9}}select{background-color:transparent;border:1px solid var(--fg);border-radius:4px;padding:2px 4px}@font-face{font-family:"Lato";src:url("font/LatoLatin-Regular.woff2") format("woff2");font-style:normal;font-weight:normal}@font-face{font-family:"Lato";src:url("font/LatoLatin-Bold.woff2") format("woff2");font-style:bold;font-weight:normal}.icon{width:24px}.icon path:not([fill]),.icon polygon:not([fill]),.icon circle:not([fill]){fill:currentColor}.flex-row{flex-direction:row;align-items:center}.flex-row:not([hidden]){display:flex}.flex-column{flex-direction:column}.flex-column:not([hidden]){display:flex}.ellipsis{overflow:hidden;text-overflow:ellipsis}.selectable{border-left:var(--border-width) solid transparent;cursor:pointer}.selectable.selected{border-left-color:var(--primary)}.item{flex-direction:row;align-items:center;border-left:var(--border-width) solid transparent;cursor:pointer;padding:8px;padding-left:calc(8px - var(--border-width))}.item:not([hidden]){display:flex}.item.selected{border-left-color:var(--primary)}.item:nth-child(odd){background-color:var(--bg-alt)}.item>.icon{margin-right:var(--icon-spacing)}.item .title{font-size:var(--font-size-large);flex-grow:1;min-width:0}.item button .icon{width:32px}.component header{flex-direction:row;align-items:center;padding:var(--spacing)}.component header:not([hidden]){display:flex}.component header button{font-size:var(--font-size-large);font-weight:bold;overflow:hidden}.component header button .icon{margin-right:var(--icon-spacing)}.component ul{flex-grow:1;overflow:auto;list-style:none;margin:0;padding:0}.component li{flex-direction:row;align-items:center}.component li:not([hidden]){display:flex}.component li .info{flex-grow:1;overflow:hidden}.component li .info .icon{color:var(--primary);margin-right:var(--icon-spacing);filter:drop-shadow(var(--text-shadow))}.component li .info h2{font-size:var(--font-size-large);margin:0}.component li:not(.has-art){padding:8px}.component li button .icon{width:32px}.component li:nth-child(odd){background-color:var(--bg-alt)}#library header{flex-direction:row;align-items:center;padding:var(--spacing)}#library header:not([hidden]){display:flex}#library header button{font-size:var(--font-size-large);font-weight:bold;overflow:hidden}#library header button .icon{margin-right:var(--icon-spacing)}#library ul{flex-grow:1;overflow:auto;list-style:none;margin:0;padding:0}#library li{flex-direction:row;align-items:center}#library li:not([hidden]){display:flex}#library li .info{flex-grow:1;overflow:hidden}#library li .info .icon{color:var(--primary);margin-right:var(--icon-spacing);filter:drop-shadow(var(--text-shadow))}#library li .info h2{font-size:var(--font-size-large);margin:0}#library li:not(.has-art){padding:8px}#library li button .icon{width:32px}#library li:nth-child(odd){background-color:var(--bg-alt)}#library header{white-space:pre}#library .search{order:1}#library .search.open~*{display:none}#library .art img,#library .art .icon{width:64px}#library .art .icon{filter:drop-shadow(var(--text-shadow))}#library .group{cursor:pointer}#library .group h2{font-weight:normal}#library .tiles{display:grid;grid-template-columns:repeat(auto-fill, minmax(200px, 1fr));grid-gap:2px}#library .tiles li{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 header{flex-direction:row;align-items:center;padding:var(--spacing)}#fs header:not([hidden]){display:flex}#fs header button{font-size:var(--font-size-large);font-weight:bold;overflow:hidden}#fs header button .icon{margin-right:var(--icon-spacing)}#fs ul{flex-grow:1;overflow:auto;list-style:none;margin:0;padding:0}#fs li{flex-direction:row;align-items:center}#fs li:not([hidden]){display:flex}#fs li .info{flex-grow:1;overflow:hidden}#fs li .info .icon{color:var(--primary);margin-right:var(--icon-spacing);filter:drop-shadow(var(--text-shadow))}#fs li .info h2{font-size:var(--font-size-large);margin:0}#fs li:not(.has-art){padding:8px}#fs li button .icon{width:32px}#fs li:nth-child(odd){background-color:var(--bg-alt)}#fs header{white-space:pre}#fs .search{order:1}#fs .search.open~*{display:none}#fs .group{cursor:pointer}.search{flex-direction:row;align-items:center;margin-left:auto;transition:all 300ms;width:32px;max-width:20ch}.search:not([hidden]){display:flex}.search .icon{width:32px;cursor:pointer}.search input{border:none;outline:none;color:inherit;background-color:inherit;border-bottom:1px solid var(--fg);width:0;padding:0;flex-grow:1}.search.open{flex:1}.art{margin-right:var(--icon-spacing)}.art .icon,.art img{vertical-align:top}cyp-app{--font-size-large:112.5%;--icon-spacing:4px;--primary:rgb(var(--primary-raw));--box-shadow:0 0 3px #000;--border-width:4px}cyp-app[theme=light]{--fg:#333;--bg:#f0f0f0;--bg-alt:#e0e0e0;--text-shadow:none}cyp-app[theme=dark]{--fg:#f0f0f0;--bg:#333;--bg-alt:#555;--text-shadow:0 1px 1px rgba(0,0,0,0.8)}@media (prefers-color-scheme:dark){cyp-app[theme=auto]{--fg:#f0f0f0;--bg:#333;--bg-alt:#555;--text-shadow:0 1px 1px rgba(0,0,0,0.8)}}@media (prefers-color-scheme:light){cyp-app[theme=auto]{--fg:#333;--bg:#f0f0f0;--bg-alt:#e0e0e0;--text-shadow:none}}cyp-app[color=dodgerblue]{--primary-raw:30, 144, 255}cyp-app[color=darkorange]{--primary-raw:255, 140, 0}cyp-app[color=limegreen]{--primary-raw:50, 205, 50}cyp-app{flex-direction:column;box-sizing:border-box;margin:0 auto;max-width:800px;height:100vh;font-family:lato,sans-serif;line-height:1.25;background-color:var(--bg);color:var(--fg);text-shadow:var(--text-shadow);white-space:nowrap}cyp-app:not([hidden]){display:flex}cyp-menu,cyp-commands{flex-direction:row;align-items:center;height:100%}cyp-menu:not([hidden]),cyp-commands:not([hidden]){display:flex}cyp-menu button,cyp-commands button{height:100%;flex-direction:column;align-items:center;justify-content:center}cyp-menu button:not([hidden]),cyp-commands button:not([hidden]){display:flex}@media (max-width:480px){cyp-menu button,cyp-commands button{flex-direction:row}cyp-menu button span:not([id]),cyp-commands button span:not([id]){display:none}}cyp-menu button{flex:1 0 0;border-top:var(--border-width) solid transparent;border-bottom:var(--border-width) solid transparent}cyp-menu button .icon{margin-right:var(--icon-spacing)}cyp-menu button.active{border-top-color:var(--primary);color:var(--primary);background-color:rgb(var(--primary-raw), .1)}cyp-commands{position:absolute;left:0;top:0;width:100%;transition:top 300ms;background-color:var(--bg)}cyp-commands[hidden]{display:flex;top:100%}cyp-commands button{flex:0 1 80px}cyp-commands button.last{order:1;margin-left:auto}cyp-song{flex-direction:row;align-items:center;border-left:var(--border-width) solid transparent;cursor:pointer;padding:8px;padding-left:calc(8px - var(--border-width))}cyp-song:not([hidden]){display:flex}cyp-song.selected{border-left-color:var(--primary)}cyp-song:nth-child(odd){background-color:var(--bg-alt)}cyp-song>.icon{margin-right:var(--icon-spacing)}cyp-song .title{font-size:var(--font-size-large);flex-grow:1;min-width:0}cyp-song button .icon{width:32px}cyp-song .info{flex-grow:1;min-width:0}cyp-song .info .icon{color:var(--primary);margin-right:var(--icon-spacing);filter:drop-shadow(var(--text-shadow))}cyp-song .info h2{font-size:var(--font-size-large);margin:0}cyp-song .info h2,cyp-song .info div{overflow:hidden;text-overflow:ellipsis}cyp-player{flex-direction:row;align-items:center;align-items:stretch}cyp-player:not([hidden]){display:flex}cyp-player:not([data-state=play]) .pause{display:none}cyp-player[data-state=play] .play{display:none}cyp-player:not([data-flags~=random]) .random,cyp-player:not([data-flags~=repeat]) .repeat{opacity:.5}cyp-player x-range{flex-grow:1;--elapsed-color:var(--primary)}cyp-player .art{margin-right:0;height:96px}cyp-player .art img,cyp-player .art .icon{width:96px}cyp-player .info{flex-grow:2;flex-basis:0;padding:0 var(--icon-spacing);overflow:hidden;flex-direction:column;justify-content:space-around}cyp-player .info:not([hidden]){display:flex}cyp-player .info h2{font-size:125%;margin:0}cyp-player .info .title,cyp-player .info .subtitle{overflow:hidden;text-overflow:ellipsis}cyp-player .timeline{flex-direction:row;align-items:center}cyp-player .timeline:not([hidden]){display:flex}cyp-player .timeline .duration,cyp-player .timeline .elapsed{flex-basis:5ch;text-align:center}cyp-player .controls{flex-grow:1;flex-basis:0;max-width:220px;flex-direction:column;justify-content:space-around}cyp-player .controls:not([hidden]){display:flex}cyp-player .controls .playback{flex-direction:row;align-items:center;justify-content:space-around}cyp-player .controls .playback:not([hidden]){display:flex}cyp-player .controls .playback .icon{width:40px}cyp-player .controls .playback .icon-play,cyp-player .controls .playback .icon-pause{width:64px}cyp-player .controls .volume{flex-direction:row;align-items:center}cyp-player .controls .volume:not([hidden]){display:flex}cyp-player .controls .volume .mute{margin-right:4px}cyp-player .misc{display:flex;flex-direction:column;align-self:stretch;justify-content:space-around}cyp-player .misc .icon{width:32px}@media (max-width:519px){cyp-player{flex-wrap:wrap;justify-content:space-between}cyp-player .info{order:1;flex-basis:100%;height:96px}}cyp-queue .current{color:var(--primary)}cyp-settings{--spacing:8px;font-size:var(--font-size-large)}cyp-settings dl{margin:var(--spacing);display:grid;grid-template-columns:max-content 1fr;align-items:center;grid-gap:var(--spacing)}cyp-settings dt{font-weight:bold}cyp-settings dd{margin:0;flex-direction:column;align-items:start}cyp-settings dd:not([hidden]){display:flex}cyp-settings label{flex-direction:row;align-items:center}cyp-settings label:not([hidden]){display:flex}cyp-settings label [type=radio],cyp-settings label [type=checkbox]{margin:0 4px 0 0}cyp-yt header{flex-direction:row;align-items:center;padding:var(--spacing)}cyp-yt header:not([hidden]){display:flex}cyp-yt header button{font-size:var(--font-size-large);font-weight:bold;overflow:hidden}cyp-yt header button .icon{margin-right:var(--icon-spacing)}cyp-yt ul{flex-grow:1;overflow:auto;list-style:none;margin:0;padding:0}cyp-yt li{flex-direction:row;align-items:center}cyp-yt li:not([hidden]){display:flex}cyp-yt li .info{flex-grow:1;overflow:hidden}cyp-yt li .info .icon{color:var(--primary);margin-right:var(--icon-spacing);filter:drop-shadow(var(--text-shadow))}cyp-yt li .info h2{font-size:var(--font-size-large);margin:0}cyp-yt li:not(.has-art){padding:8px}cyp-yt li button .icon{width:32px}cyp-yt li:nth-child(odd){background-color:var(--bg-alt)}cyp-yt header{border-bottom:1px solid var(--fg)}cyp-yt header button+button{margin-left:16px}cyp-yt .clear{margin-left:auto}cyp-yt pre{margin:.5em .5ch;flex-grow:1;overflow:auto;white-space:pre-wrap}cyp-yt.pending header{background-image:linear-gradient(var(--primary), var(--primary));background-repeat:no-repeat;background-size:25% 4px;animation:bar ease-in-out 3s alternate infinite}@keyframes bar{0%{background-position:0 100%}100%{background-position:100% 100%}}x-range{--thumb-size:8px;--thumb-color:#ddd;--thumb-shadow:#000;--thumb-hover-color:#fff;--track-size:4px;--track-color:#888;--track-shadow:#000;--elapsed-color:#ddd;--remaining-color:transparent;--radius:calc(var(--track-size)/2);display:inline-block;position:relative;width:192px;height:16px}x-range .-track,x-range .-elapsed,x-range .-remaining{position:absolute;top:calc(50% - var(--track-size)/2);height:var(--track-size);border-radius:var(--radius)}x-range .-track{width:100%;left:0;background-color:var(--track-color);box-shadow:0 0 1px var(--thumb-shadow)}x-range .-elapsed{left:0;background-color:var(--elapsed-color)}x-range .-remaining{right:0;background-color:var(--remaining-color)}x-range .-inner{position:absolute;left:var(--thumb-size);right:var(--thumb-size);top:0;bottom:0}x-range .-thumb{all:unset;position:absolute;top:50%;transform:translate(-50%, -50%);border-radius:50%;width:calc(2*var(--thumb-size));height:calc(2*var(--thumb-size));background-color:var(--thumb-color);box-shadow:0 0 2px var(--thumb-shadow)}x-range[disabled]{opacity:.5}x-range:not([disabled]) .-thumb:hover{background-color:var(--thumb-hover-color)}cyp-playlist{flex-direction:row;align-items:center;border-left:var(--border-width) solid transparent;cursor:pointer;padding:8px;padding-left:calc(8px - var(--border-width))}cyp-playlist:not([hidden]){display:flex}cyp-playlist.selected{border-left-color:var(--primary)}cyp-playlist:nth-child(odd){background-color:var(--bg-alt)}cyp-playlist>.icon{margin-right:var(--icon-spacing)}cyp-playlist .title{font-size:var(--font-size-large);flex-grow:1;min-width:0}cyp-playlist button .icon{width:32px}cyp-playlist:nth-child(odd){background-color:var(--bg-alt)} \ No newline at end of file diff --git a/app/js/component.js b/app/js/component.js index 69f1870..4249b31 100644 --- a/app/js/component.js +++ b/app/js/component.js @@ -1,3 +1,4 @@ +import * as html from "./html.js"; import Selection from "./selection.js"; export class HasApp extends HTMLElement { @@ -10,6 +11,10 @@ export class Item extends HasApp { super(); this.addEventListener("click", _ => this.parentNode.selection.toggle(this)); } + + _buildTitle(title) { + return html.node("span", {className:"title"}, title, this); + } } export default class Component extends HasApp { diff --git a/app/js/elements/playlist.js b/app/js/elements/playlist.js index 3054ca7..a03855e 100644 --- a/app/js/elements/playlist.js +++ b/app/js/elements/playlist.js @@ -8,8 +8,8 @@ export default class Playlist extends Item { } connectedCallback() { - html.icon("playlist-music", this) - html.node("h2", {}, this.name, this); + html.icon("playlist-music", this); + this._buildTitle(this.name); } } diff --git a/app/js/elements/queue.js b/app/js/elements/queue.js index c909c50..905c291 100644 --- a/app/js/elements/queue.js +++ b/app/js/elements/queue.js @@ -65,7 +65,15 @@ class Queue extends Component { html.clear(this); this.selection.clear(); - songs.forEach(song => this.appendChild(new Song(song))); + songs.forEach(song => { + const node = new Song(song); + this.appendChild(node); + + html.button({icon:"play"}, "", node).addEventListener("click", async e => { + e.stopPropagation(); // do not select + await this._mpd.command(`playid ${song["Id"]}`); + }); + }); this._updateCurrent(); } diff --git a/app/js/elements/song.js b/app/js/elements/song.js index c52d9bf..6eeeae7 100644 --- a/app/js/elements/song.js +++ b/app/js/elements/song.js @@ -15,11 +15,6 @@ export default class Song extends Item { let lines = formatSongInfo(this.data); html.node("h2", {}, lines.shift(), info); lines.length && html.node("div", {}, lines.shift(), info); - - html.button({icon:"play"}, "", this).addEventListener("click", async e => { - e.stopPropagation(); // do not select - await this._mpd.command(`playid ${this.data["Id"]}`); - }); } } diff --git a/app/js/mpd-mock.js b/app/js/mpd-mock.js index 66808d1..ea48f57 100644 --- a/app/js/mpd-mock.js +++ b/app/js/mpd-mock.js @@ -3,7 +3,7 @@ import * as mpd from "./mpd.js"; export const escape = mpd.escape; export function command(cmd) { - console.warn(`MOCK does not know "${cmd}"`); + console.warn(`mpd-mock does not know "${cmd}"`); } export function commandAndStatus(cmd) {