mm.site/src/views/videos.js

125 lines
2.9 KiB
JavaScript

import { LitElement, html, css, unsafeCSS } from 'lit'
import { Task } from '@lit-labs/task'
import MainCSS from '../assets/styles/main.scss?inline'
// components
import '../components/Header.js'
import '../components/Footer.js'
import '../components/VerticalCard.js'
import '../components/VideoPlayer.js'
import '../components/HorizontalScroller.js'
import Router from '../api/Router.js'
class VideoPage extends LitElement {
static properties = {
data: { type: Array },
fims: { type: Array, state: true },
selected: { state: true }
}
constructor() {
super()
this.data = []
this.selected = {}
}
firstUpdated() {
this.addEventListener('video-select', ({ detail }) => {
this.selected = { ...detail, media: `${Router.route.path}/${detail.media}`, autoplay: true }
})
}
_getVideos = new Task(
this,
async () => {
const res = await fetch(`/data/${Router.route.path}.json`)
this.films = await res.json()
this.selected = { ...this.films[0], media: `${Router.route.path}/${this.films[0].media}` }
},
() => [ this.data ]
)
// TODO@mx this might not be necessary
_selectVideo = new Task(
this,
{
task: () => {
// console.log(this.selected)
},
args: () => [ this.selected ],
}
)
render() {
return html`
<mm-header></mm-header>
<main>
${this._selectVideo.render({
pending: () => html`Loading...`,
complete: () => html`
<aside>
<h2>${this.selected.title}</h2>
<p class="detail">${this.selected.detail}</p>
</aside>
<mm-vplayer media='/media/${this.selected.media}' ?autoplay=${this.selected.autoplay}></mm-vplayer>
`
})}
</main>
<mm-hscroller>
${this._getVideos.render({
pending: () => html`Loading...`,
complete: () => html`${this.films.map(t => html`
<mm-vcard
.details=${t}
?selected=${t.title == this.selected.title && t.detail == this.selected.detail}
></mm-vcard>`
)}`
})}
</mm-hscroller>
<mm-footer></mm-footer>`
}
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
:host {
display: grid;
grid-template-rows: min-content 1fr min-content min-content;
gap: 0.25em;
height: 100vh;
}
mm-vcard {
--color: var(--green-400);
--background-color: var(--neutral-200);
}
main {
display: grid;
grid-template-columns: 0.4fr 1fr;
margin-inline: 0.5em;
margin-block-end: 0.5em;
gap: 0.5em;
}
aside {
font-size: 1.5em;
padding-inline-start: 0.5em;
> h2 {
max-width: 12ch;
margin-block-end: 0.2em;
}
> .detail {
line-height: 1.1;
}
}
` ]
}
customElements.define('mm-videos', VideoPage)