cleaned up code and added volume controller
This commit is contained in:
parent
476139bc3f
commit
99976ecc11
20
src/App.js
20
src/App.js
|
@ -1,6 +1,11 @@
|
||||||
import { LitElement } from 'lit'
|
import { LitElement, css, html, unsafeCSS } from 'lit'
|
||||||
import Router from './api/Router.js'
|
import Router from './api/Router.js'
|
||||||
|
|
||||||
|
import MainCSS from './assets/styles/main.scss?inline'
|
||||||
|
|
||||||
|
import './components/Header.js'
|
||||||
|
import './components/Footer.js'
|
||||||
|
|
||||||
// global reset
|
// global reset
|
||||||
import './assets/styles/main.scss'
|
import './assets/styles/main.scss'
|
||||||
|
|
||||||
|
@ -26,9 +31,20 @@ export class App extends LitElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return Router.render()
|
return html`
|
||||||
|
${Router.route.path == '/' ? '' : html`<mm-header title=${Router.route.title}></mm-header>`}
|
||||||
|
${Router.render()}
|
||||||
|
${Router.route.path == '/' ? '' : html`<mm-footer path=${Router.route.path}></mm-footer>`}
|
||||||
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
` ]
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('mm-app', App)
|
customElements.define('mm-app', App)
|
||||||
|
|
|
@ -5,10 +5,16 @@ import MainCSS from '../assets/styles/main.scss?inline'
|
||||||
import './SvgIcon.js'
|
import './SvgIcon.js'
|
||||||
|
|
||||||
class Footer extends LitElement {
|
class Footer extends LitElement {
|
||||||
static properties = {}
|
static properties = {
|
||||||
|
path: { type: String }
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
this.path = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -16,7 +22,7 @@ class Footer extends LitElement {
|
||||||
<footer>
|
<footer>
|
||||||
<nav>
|
<nav>
|
||||||
${Router.routes.map(r => !r.hide ? html`
|
${Router.routes.map(r => !r.hide ? html`
|
||||||
<a href=${r.path} class=${r.path == Router.route.path ? 'selected' : ''}>
|
<a href=${r.path} class=${r.path == this.path ? 'selected' : ''}>
|
||||||
<mm-icon name=${r.icon}></mm-icon>
|
<mm-icon name=${r.icon}></mm-icon>
|
||||||
${r.short}
|
${r.short}
|
||||||
</a>` : '') }
|
</a>` : '') }
|
||||||
|
|
|
@ -6,7 +6,9 @@ import './Button.js'
|
||||||
import MainCSS from '../assets/styles/main.scss?inline'
|
import MainCSS from '../assets/styles/main.scss?inline'
|
||||||
|
|
||||||
class Header extends LitElement {
|
class Header extends LitElement {
|
||||||
static properties = {}
|
static properties = {
|
||||||
|
title: { type: String }
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
@ -23,7 +25,7 @@ class Header extends LitElement {
|
||||||
<mm-button @click=${this.navHome}>back</mm-button>
|
<mm-button @click=${this.navHome}>back</mm-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1>${Router.route.title || ''}</h1>
|
<h1>${this.title || ''}</h1>
|
||||||
|
|
||||||
</header>
|
</header>
|
||||||
`
|
`
|
||||||
|
|
|
@ -2,12 +2,16 @@ import { LitElement, html, css,unsafeCSS } from 'lit'
|
||||||
import { Task } from '@lit-labs/task'
|
import { Task } from '@lit-labs/task'
|
||||||
import { formatSeconds } from '../api/utils'
|
import { formatSeconds } from '../api/utils'
|
||||||
|
|
||||||
|
import VolumeController from '../controllers/volume.js'
|
||||||
|
|
||||||
import MainCSS from '../assets/styles/main.scss?inline'
|
import MainCSS from '../assets/styles/main.scss?inline'
|
||||||
|
|
||||||
import './RangeSlider.js'
|
import './RangeSlider.js'
|
||||||
import './Loading.js'
|
import './Loading.js'
|
||||||
|
|
||||||
class ModularPlayer extends LitElement {
|
class ModularPlayer extends LitElement {
|
||||||
|
volCtrl = new VolumeController(this)
|
||||||
|
|
||||||
static properties = {
|
static properties = {
|
||||||
// property
|
// property
|
||||||
details: { type: Object },
|
details: { type: Object },
|
||||||
|
@ -16,7 +20,6 @@ class ModularPlayer extends LitElement {
|
||||||
duration: { state: true },
|
duration: { state: true },
|
||||||
position: { state: true },
|
position: { state: true },
|
||||||
playing: { state: true },
|
playing: { state: true },
|
||||||
volume: { state: true },
|
|
||||||
track: { state: true },
|
track: { state: true },
|
||||||
loading: { state: true },
|
loading: { state: true },
|
||||||
|
|
||||||
|
@ -35,7 +38,7 @@ class ModularPlayer extends LitElement {
|
||||||
this.duration = 0
|
this.duration = 0
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|
||||||
this.initAudio()
|
this._initAudio()
|
||||||
}
|
}
|
||||||
|
|
||||||
_getTrack = new Task(
|
_getTrack = new Task(
|
||||||
|
@ -60,17 +63,12 @@ class ModularPlayer extends LitElement {
|
||||||
() => [ this.track, this.details ]
|
() => [ this.track, this.details ]
|
||||||
)
|
)
|
||||||
|
|
||||||
initAudio() {
|
_initAudio() {
|
||||||
this.audio = document.createElement('audio')
|
this.audio = document.createElement('audio')
|
||||||
|
|
||||||
if (!localStorage.getItem('deviceVolume')) {
|
|
||||||
localStorage.setItem('deviceVolume', 0.6)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.audio.addEventListener('loadstart', () => {
|
this.audio.addEventListener('loadstart', () => {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.audio.volume = localStorage.getItem('deviceVolume')
|
this.audio.volume = this.volCtrl.volume
|
||||||
this.volume = this.audio.volume
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.audio.addEventListener('canplay', () => {
|
this.audio.addEventListener('canplay', () => {
|
||||||
|
@ -116,7 +114,7 @@ class ModularPlayer extends LitElement {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
togglePlay() {
|
_togglePlay() {
|
||||||
if (this.audio.paused) {
|
if (this.audio.paused) {
|
||||||
this.playing = true
|
this.playing = true
|
||||||
this.audio.play()
|
this.audio.play()
|
||||||
|
@ -126,7 +124,7 @@ class ModularPlayer extends LitElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
seekTrack({ detail }) {
|
_seekTrack({ detail }) {
|
||||||
if (detail) {
|
if (detail) {
|
||||||
const { value } = detail
|
const { value } = detail
|
||||||
this.audio.currentTime = value
|
this.audio.currentTime = value
|
||||||
|
@ -134,20 +132,20 @@ class ModularPlayer extends LitElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skipForward() {
|
_skipForward() {
|
||||||
this.audio.currentTime = this.audio.currentTime + 15
|
this.audio.currentTime = this.audio.currentTime + 15
|
||||||
}
|
}
|
||||||
|
|
||||||
skipBackward() {
|
_skipBackward() {
|
||||||
this.audio.currentTime = this.audio.currentTime - 15
|
this.audio.currentTime = this.audio.currentTime - 15
|
||||||
}
|
}
|
||||||
|
|
||||||
selectTrack(evt) {
|
_selectTrack(evt) {
|
||||||
const trackNumber = evt.target.dataset.trackNumber
|
const trackNumber = evt.target.dataset.trackNumber
|
||||||
this.track = parseInt(trackNumber)
|
this.track = parseInt(trackNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
nextTrack() {
|
_nextTrack() {
|
||||||
if (this.details.tracks) {
|
if (this.details.tracks) {
|
||||||
if (this.track + 1 < this.details.tracks.length) {
|
if (this.track + 1 < this.details.tracks.length) {
|
||||||
this.track += 1
|
this.track += 1
|
||||||
|
@ -157,7 +155,7 @@ class ModularPlayer extends LitElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prevTrack() {
|
_prevTrack() {
|
||||||
if (this.details.tracks) {
|
if (this.details.tracks) {
|
||||||
if (this.track - 1 >= 0) {
|
if (this.track - 1 >= 0) {
|
||||||
this.track -= 1
|
this.track -= 1
|
||||||
|
@ -167,14 +165,13 @@ class ModularPlayer extends LitElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
volHandler(evt) {
|
_volHandler(evt) {
|
||||||
if (evt.detail) {
|
if (evt.detail) {
|
||||||
this.audio.volume = evt.detail.value
|
this.volCtrl.update(evt.detail.value)
|
||||||
localStorage.setItem('deviceVolume', evt.detail.value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progressCalc() {
|
_progressCalc() {
|
||||||
let percentage = 0
|
let percentage = 0
|
||||||
|
|
||||||
if (this.position && this.duration) {
|
if (this.position && this.duration) {
|
||||||
|
@ -195,7 +192,7 @@ ${ this.details ?
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<ul>
|
<ul>
|
||||||
${this.details.tracks.map((t, i) => html`
|
${this.details.tracks.map((t, i) => html`
|
||||||
<li class="${this.track === i ? 'selected' : ''}" data-track-number=${i} @click=${this.selectTrack}>
|
<li class="${this.track === i ? 'selected' : ''}" data-track-number=${i} @click=${this._selectTrack}>
|
||||||
<mm-icon name="notes" class=${this.playing ? 'playing' : ''}></mm-icon>
|
<mm-icon name="notes" class=${this.playing ? 'playing' : ''}></mm-icon>
|
||||||
<span>${t}</span>
|
<span>${t}</span>
|
||||||
</li>`)}
|
</li>`)}
|
||||||
|
@ -219,7 +216,7 @@ ${ this.details ?
|
||||||
value=${this.position}
|
value=${this.position}
|
||||||
max=${this.duration}
|
max=${this.duration}
|
||||||
step="0.1"
|
step="0.1"
|
||||||
@input=${this.seekTrack}
|
@input=${this._seekTrack}
|
||||||
></mm-range>`
|
></mm-range>`
|
||||||
: html`
|
: html`
|
||||||
<div class="waveform">
|
<div class="waveform">
|
||||||
|
@ -227,7 +224,7 @@ ${ this.details ?
|
||||||
value=${this.position}
|
value=${this.position}
|
||||||
max=${this.duration}
|
max=${this.duration}
|
||||||
step="0.1"
|
step="0.1"
|
||||||
@input=${this.seekTrack}
|
@input=${this._seekTrack}
|
||||||
class="progress"
|
class="progress"
|
||||||
></mm-range>
|
></mm-range>
|
||||||
<img class="wav-img" loading="eager" src="/media${this.details.media}.png">
|
<img class="wav-img" loading="eager" src="/media${this.details.media}.png">
|
||||||
|
@ -245,18 +242,18 @@ ${ this.details ?
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<mm-icon name="skip-prev" @click=${this.prevTrack} ?disabled=${!this.duration || this.getAudio?.status == 1}></mm-icon>
|
<mm-icon name="skip-prev" @click=${this._prevTrack} ?disabled=${!this.duration || this.getAudio?.status == 1}></mm-icon>
|
||||||
<mm-icon name="skip-b15" @click=${this.skipBackward} ?disabled=${!this.duration || this.getAudio?.status == 1} class="skip15"></mm-icon>
|
<mm-icon name="skip-b15" @click=${this._skipBackward} ?disabled=${!this.duration || this.getAudio?.status == 1} class="skip15"></mm-icon>
|
||||||
<mm-icon name="${this.playing ? 'pause' : 'play'}" @click=${this.togglePlay} ?disabled=${!this.duration || this.getAudio?.status == 1} class=${this.playing ? 'pause' : 'play'}></mm-icon>
|
<mm-icon name="${this.playing ? 'pause' : 'play'}" @click=${this._togglePlay} ?disabled=${!this.duration || this.getAudio?.status == 1} class=${this.playing ? 'pause' : 'play'}></mm-icon>
|
||||||
<mm-icon name="skip-f15" @click=${this.skipForward} ?disabled=${!this.duration || this.getAudio?.status == 1} class="skip15"></mm-icon>
|
<mm-icon name="skip-f15" @click=${this._skipForward} ?disabled=${!this.duration || this.getAudio?.status == 1} class="skip15"></mm-icon>
|
||||||
<mm-icon name="skip-next" @click=${this.nextTrack} ?disabled=${!this.duration || this.getAudio?.status == 1}></mm-icon>
|
<mm-icon name="skip-next" @click=${this._nextTrack} ?disabled=${!this.duration || this.getAudio?.status == 1}></mm-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="volume">
|
<div class="volume">
|
||||||
<mm-icon name="volume"></mm-icon>
|
<mm-icon name="volume"></mm-icon>
|
||||||
<mm-range
|
<mm-range
|
||||||
value=${this.volume}
|
value=${this.volCtrl.volume}
|
||||||
@input=${this.volHandler}
|
@input=${this._volHandler}
|
||||||
?disabled=${!this.duration || this.getAudio?.status == 1}
|
?disabled=${!this.duration || this.getAudio?.status == 1}
|
||||||
></mm-range>
|
></mm-range>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
import { LitElement, css, html } from 'lit'
|
import { LitElement, css, html } from 'lit'
|
||||||
|
|
||||||
|
import VolumeController from '../controllers/volume.js'
|
||||||
|
|
||||||
import './RangeSlider.js'
|
import './RangeSlider.js'
|
||||||
import './SvgIcon.js'
|
import './SvgIcon.js'
|
||||||
import { formatSeconds } from '../api/utils.js'
|
import { formatSeconds } from '../api/utils.js'
|
||||||
|
|
||||||
class VideoPlayer extends LitElement {
|
class VideoPlayer extends LitElement {
|
||||||
|
volCtrl = new VolumeController(this)
|
||||||
|
|
||||||
static properties = {
|
static properties = {
|
||||||
media: { type: String },
|
media: { type: String },
|
||||||
autoplay: { type: Boolean },
|
autoplay: { type: Boolean },
|
||||||
|
@ -14,7 +18,8 @@ class VideoPlayer extends LitElement {
|
||||||
ctrlTimer: { state: true },
|
ctrlTimer: { state: true },
|
||||||
position: { state: true },
|
position: { state: true },
|
||||||
duration: { state: true },
|
duration: { state: true },
|
||||||
remain: { state: true }
|
remain: { state: true },
|
||||||
|
volumeOpen: { state: true },
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -28,6 +33,7 @@ class VideoPlayer extends LitElement {
|
||||||
this.position = 0
|
this.position = 0
|
||||||
this.duration = 0
|
this.duration = 0
|
||||||
this.remain = true
|
this.remain = true
|
||||||
|
this.volumeOpen = false
|
||||||
this.autoplay = false
|
this.autoplay = false
|
||||||
this.videoEl = document.createElement('video')
|
this.videoEl = document.createElement('video')
|
||||||
this.videoEl.playsInline = true
|
this.videoEl.playsInline = true
|
||||||
|
@ -42,6 +48,8 @@ class VideoPlayer extends LitElement {
|
||||||
this.videoEl.addEventListener('timeupdate', () => {
|
this.videoEl.addEventListener('timeupdate', () => {
|
||||||
this.position = this.videoEl.currentTime
|
this.position = this.videoEl.currentTime
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.videoEl.volume = this.volCtrl.volume
|
||||||
}
|
}
|
||||||
|
|
||||||
willUpdate(att) {
|
willUpdate(att) {
|
||||||
|
@ -76,6 +84,7 @@ class VideoPlayer extends LitElement {
|
||||||
// timeout
|
// timeout
|
||||||
this.ctrlTimer = setTimeout(() => {
|
this.ctrlTimer = setTimeout(() => {
|
||||||
if (this.playing) {
|
if (this.playing) {
|
||||||
|
this.volumeOpen = false
|
||||||
this.controls = false
|
this.controls = false
|
||||||
}
|
}
|
||||||
}, 2000)
|
}, 2000)
|
||||||
|
@ -113,6 +122,20 @@ class VideoPlayer extends LitElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_toggleVolume() {
|
||||||
|
this.interact()
|
||||||
|
|
||||||
|
this.volumeOpen = !this.volumeOpen
|
||||||
|
}
|
||||||
|
|
||||||
|
_volHandler(evt) {
|
||||||
|
this.interact()
|
||||||
|
|
||||||
|
if (evt.detail) {
|
||||||
|
this.volCtrl.update(evt.detail.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="videoContainer">
|
<div class="videoContainer">
|
||||||
|
@ -126,7 +149,19 @@ class VideoPlayer extends LitElement {
|
||||||
|
|
||||||
<div class="controls ${this.controls ? '' : 'invisible'}">
|
<div class="controls ${this.controls ? '' : 'invisible'}">
|
||||||
|
|
||||||
<mm-icon @click=${this.toggleFullscreen} class="fullscreen" name="fullscreen"></mm-icon>
|
<div class="buttons">
|
||||||
|
<div class="volume-container">
|
||||||
|
<mm-icon name="volume" @click=${this._toggleVolume}></mm-icon>
|
||||||
|
<div class="popout ${this.volumeOpen ? 'open' : ''}">
|
||||||
|
<mm-range
|
||||||
|
value=${this.volCtrl.volume}
|
||||||
|
step="0.01"
|
||||||
|
@input=${this._volHandler}
|
||||||
|
></mm-range>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mm-icon @click=${this.toggleFullscreen} class="fullscreen" name="fullscreen"></mm-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
<mm-range
|
<mm-range
|
||||||
value="${this.position}"
|
value="${this.position}"
|
||||||
|
@ -170,6 +205,45 @@ class VideoPlayer extends LitElement {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
transition: opacity 0.25s ease;
|
transition: opacity 0.25s ease;
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.75em;
|
||||||
|
padding-block-start: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
& mm-icon {
|
||||||
|
font-size: 1.25em;
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.volume-container {
|
||||||
|
position: relative;
|
||||||
|
margin-inline-start: auto;
|
||||||
|
margin-block-end: 0.75em;
|
||||||
|
|
||||||
|
& .popout {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
width: 6em;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
transform: translateX(calc(calc(100% + 0.5em) * -1));
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
& mm-range {
|
||||||
|
transform: translateX(calc(100% + 1em));
|
||||||
|
transition: transform 0.125s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open mm-range {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.time {
|
.time {
|
||||||
|
@ -189,13 +263,6 @@ class VideoPlayer extends LitElement {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
mm-icon.fullscreen {
|
|
||||||
font-size: 1.25em;
|
|
||||||
width: 1em;
|
|
||||||
margin-inline-start: auto;
|
|
||||||
margin-block-end: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
mm-range {
|
mm-range {
|
||||||
--track-height: 0.3em;
|
--track-height: 0.3em;
|
||||||
--thumb-size: 0.8em;
|
--thumb-size: 0.8em;
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
export default class VolumeController {
|
||||||
|
volume = 0
|
||||||
|
|
||||||
|
constructor(host) {
|
||||||
|
this.host = host
|
||||||
|
this.host.addController(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
hostConnected() {
|
||||||
|
if (!localStorage.getItem('deviceVolume')) {
|
||||||
|
localStorage.setItem('deviceVolume', 0.6)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.volume = localStorage.getItem('deviceVolume')
|
||||||
|
}
|
||||||
|
|
||||||
|
update(val) {
|
||||||
|
console.log(val)
|
||||||
|
this.volume = val
|
||||||
|
localStorage.setItem('deviceVolume', val)
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,8 +4,6 @@ import { Task } from '@lit-labs/task'
|
||||||
import Photo from '/images/Meredith Monk (1974) Photo Lauretta Harris.jpg'
|
import Photo from '/images/Meredith Monk (1974) Photo Lauretta Harris.jpg'
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import '../components/Header.js'
|
|
||||||
import '../components/Footer.js'
|
|
||||||
import '../components/Loading.js'
|
import '../components/Loading.js'
|
||||||
import '../components/AudioCard.js'
|
import '../components/AudioCard.js'
|
||||||
import '../components/ModularPlayer.js'
|
import '../components/ModularPlayer.js'
|
||||||
|
@ -68,50 +66,38 @@ class AudioView extends LitElement {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<mm-header></mm-header>
|
<nav class="tracks">
|
||||||
|
<div class="scroll-items">
|
||||||
<main>
|
${this._getAudio.render({
|
||||||
<nav class="tracks">
|
pending: () => html`<mm-loading style="--fill-color: grey"></mm-loading>`,
|
||||||
<div class="scroll-items">
|
complete: () => html`${this.tracks.map((t, i) => html`
|
||||||
${this._getAudio.render({
|
<mm-acard
|
||||||
pending: () => html`<mm-loading style="--fill-color: grey"></mm-loading>`,
|
idx=${i}
|
||||||
complete: () => html`${this.tracks.map((t, i) => html`
|
icon=${t.album ? 'album' : 'play-circle'}
|
||||||
<mm-acard
|
?selected=${t.title == this.selected.title && t.details == this.selected.details}
|
||||||
idx=${i}
|
.details=${t}
|
||||||
icon=${t.album ? 'album' : 'play-circle'}
|
></mm-acard>`)}`,
|
||||||
?selected=${t.title == this.selected.title && t.details == this.selected.details}
|
error: (err) => html`Error: ${err}`
|
||||||
.details=${t}
|
})}
|
||||||
></mm-acard>`)}`,
|
|
||||||
error: (err) => html`Error: ${err}`
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="player">
|
|
||||||
<div>
|
|
||||||
${this.selected.tracks ? '' : html`<img class="bg-img" src=${Photo} />` }
|
|
||||||
<mm-audio-player .details=${this.selected}></mm-audio-player>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</nav>
|
||||||
|
|
||||||
<mm-footer></mm-footer>
|
<div class="player">
|
||||||
|
<div>
|
||||||
|
${this.selected?.tracks ? '' : html`<img class="bg-img" src=${Photo} />` }
|
||||||
|
<mm-audio-player .details=${this.selected}></mm-audio-player>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = css`
|
static styles = css`
|
||||||
:host {
|
:host {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100vh;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 0.7fr 1fr;
|
grid-template-columns: 0.7fr 1fr;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracks {
|
.tracks {
|
||||||
|
@ -161,7 +147,6 @@ class AudioView extends LitElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mm-audio-player {
|
mm-audio-player {
|
||||||
transition: opacity 0.125s 0.125s ease-in-out;
|
transition: opacity 0.125s 0.125s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
import { LitElement, html, css } from 'lit'
|
import { LitElement, html, css } from 'lit'
|
||||||
|
|
||||||
import '../components/Header.js'
|
|
||||||
import '../components/Footer.js'
|
|
||||||
|
|
||||||
class FourOhFour extends LitElement {
|
class FourOhFour extends LitElement {
|
||||||
static properties = {}
|
static properties = {}
|
||||||
|
|
||||||
|
@ -12,34 +9,22 @@ class FourOhFour extends LitElement {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<mm-header></mm-header>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<h1>404</h1>
|
<h1>404</h1>
|
||||||
<p>The page you're looking for cannot be found</p>
|
<p>The page you're looking for cannot be found</p>
|
||||||
</main>
|
|
||||||
|
|
||||||
<mm-footer></mm-footer>
|
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = css`
|
static styles = css`
|
||||||
:host {
|
:host {
|
||||||
display: grid;
|
|
||||||
grid-template-rows: auto 1fr auto;
|
|
||||||
gap: 0.5em;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 0em 0em 10em;
|
padding: 0em 0em 10em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
main > * {
|
:host > * {
|
||||||
margin: 0.25em;
|
margin: 0.25em;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
|
@ -36,15 +36,14 @@ class Home extends LitElement {
|
||||||
|
|
||||||
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
|
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
|
||||||
:host {
|
:host {
|
||||||
--margin: 0.75em;
|
|
||||||
display: block;
|
display: block;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: calc(100vh - calc(var(--margin) * 2));
|
|
||||||
background-image: url('/images/home-bg.png');
|
background-image: url('/images/home-bg.png');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
margin: var(--margin);
|
border: 0.75em white solid;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
div {
|
div {
|
||||||
|
|
|
@ -4,8 +4,6 @@ import Router from '../api/Router.js'
|
||||||
|
|
||||||
import MainCSS from '../assets/styles/main.scss?inline'
|
import MainCSS from '../assets/styles/main.scss?inline'
|
||||||
|
|
||||||
import '../components/Header.js'
|
|
||||||
import '../components/Footer.js'
|
|
||||||
import '../components/HorizontalScroller.js'
|
import '../components/HorizontalScroller.js'
|
||||||
import '../components/VerticalCard.js'
|
import '../components/VerticalCard.js'
|
||||||
import '../components/ImageViewer.js'
|
import '../components/ImageViewer.js'
|
||||||
|
@ -47,8 +45,6 @@ class ImageView extends LitElement {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<mm-header></mm-header>
|
|
||||||
<main>
|
|
||||||
<div class="image">
|
<div class="image">
|
||||||
<mm-imageviewer .details=${this.selected}></mm-imageviewer>
|
<mm-imageviewer .details=${this.selected}></mm-imageviewer>
|
||||||
</div>
|
</div>
|
||||||
|
@ -58,17 +54,15 @@ class ImageView extends LitElement {
|
||||||
<mm-vcard @click=${this.selectImage} .details=${i} ?selected=${i.title == this.selected?.title}></mm-vcard>
|
<mm-vcard @click=${this.selectImage} .details=${i} ?selected=${i.title == this.selected?.title}></mm-vcard>
|
||||||
`) })}
|
`) })}
|
||||||
</mm-hscroller>
|
</mm-hscroller>
|
||||||
</main>
|
|
||||||
<mm-footer></mm-footer>
|
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
|
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
|
||||||
:host {
|
:host {
|
||||||
|
flex-grow: 1;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: min-content 1fr min-content;
|
grid-template-rows: 1fr auto;
|
||||||
gap: 0.25em;
|
gap: 0.5em;
|
||||||
height: 100vh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mm-hscroller {
|
mm-hscroller {
|
||||||
|
@ -80,12 +74,6 @@ class ImageView extends LitElement {
|
||||||
--color: var(--green-400, lime);
|
--color: var(--green-400, lime);
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: 1fr auto;
|
|
||||||
gap: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
position: relative;
|
position: relative;
|
||||||
inline-margin: auto;
|
inline-margin: auto;
|
||||||
|
|
|
@ -4,8 +4,6 @@ import { Task } from '@lit-labs/task'
|
||||||
import MainCSS from '../assets/styles/main.scss?inline'
|
import MainCSS from '../assets/styles/main.scss?inline'
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import '../components/Header.js'
|
|
||||||
import '../components/Footer.js'
|
|
||||||
import '../components/VerticalCard.js'
|
import '../components/VerticalCard.js'
|
||||||
import '../components/VideoPlayer.js'
|
import '../components/VideoPlayer.js'
|
||||||
import '../components/HorizontalScroller.js'
|
import '../components/HorizontalScroller.js'
|
||||||
|
@ -43,8 +41,6 @@ class VideoView extends LitElement {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<mm-header></mm-header>
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<aside>
|
<aside>
|
||||||
<h2>${this.selected.title}</h2>
|
<h2>${this.selected.title}</h2>
|
||||||
|
@ -64,14 +60,14 @@ class VideoView extends LitElement {
|
||||||
)}`
|
)}`
|
||||||
})}
|
})}
|
||||||
</mm-hscroller>
|
</mm-hscroller>
|
||||||
|
`
|
||||||
<mm-footer></mm-footer>`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
|
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
|
||||||
:host {
|
:host {
|
||||||
|
flex-grow: 1;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: min-content 1fr min-content min-content;
|
grid-template-rows: 1fr min-content;
|
||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
@ -83,6 +79,7 @@ class VideoView extends LitElement {
|
||||||
|
|
||||||
main {
|
main {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
height: 100%;
|
||||||
grid-template-columns: 0.4fr 1fr;
|
grid-template-columns: 0.4fr 1fr;
|
||||||
margin-inline: 0.5em;
|
margin-inline: 0.5em;
|
||||||
margin-block-end: 0.5em;
|
margin-block-end: 0.5em;
|
||||||
|
|
Loading…
Reference in New Issue