mm.site/src/views/images.js

131 lines
2.8 KiB
JavaScript

import { LitElement, css, html, unsafeCSS } from 'lit'
import { Task } from '@lit-labs/task'
import Router from '../api/Router.js'
import MainCSS from '../assets/styles/main.scss?inline'
import '../components/HorizontalScroller.js'
import '../components/VerticalCard.js'
import '../components/ImageViewer.js'
import '../components/ImageCarousel.js'
class ImageView extends LitElement {
static properties = {
images: { state: true },
selected: { state: true }
}
constructor() {
super()
this.images = []
}
_getImages = new Task(
this,
async () => {
try {
const res = await fetch('/data/images.json')
const json = await res.json()
json.forEach(i => i.path = `/media${Router.route.path}/${i.media}`)
this.images = json
} catch (err) {
console.error(err)
}
},
() => []
)
selectImage({ target }) {
console.log(target.details)
const event = new CustomEvent('single-fullscreen-image', {
bubbles: true, composed: true,
detail: { ...target.details, src: `/media${Router.route.path}/${target.details.section}/${target.details.media}` }
})
this.dispatchEvent(event)
}
render() {
return html`
<!-- <mm-img-carousel .images=${this.images}></mm-img-carousel> -->
${this.images.length > 0 ?
html`
<div class="gallery">
${this._getImages.render({ complete: () => this.images.map(
section => html`
<header class="section-header">
<h3>${section.title}</h3>
</header>
<main>
${section.images.map(
i => html`
<mm-vcard
@click=${this.selectImage}
.details=${ { ...i, section: section.media } }
?selected=${i.title == this.selected?.title}
>
</mm-vcard>
`)}
</main>
`
) })}
</div>
` :
html`<h2>No images added to the gallery</h2>`
}
`
}
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
:host {
flex-grow: 1;
height: 100%;
overflow: auto;
padding-inline: 1em;
padding-block: 1em;
}
mm-hscroller {
--col-width: 7.5em;
--gap: 0.75em;
}
mm-vcard {
--color: var(--green-400, lime);
}
header {
padding-block-start: 1.5em;
padding-block-end: 1em;
font-size: 1.25em;
border-bottom: 1px solid var(--green-400);
margin-block-end: 1em;
}
main {
display: grid;
gap: 0.75em;
grid-template-columns: repeat(7, 1fr);
grid-auto-rows: 10em;
}
.image {
position: relative;
inline-margin: auto;
height: 100%;
}
mm-image-carousel {
position: absolute;
inset: 0;
}
` ]
}
customElements.define('mm-images', ImageView)