131 lines
2.8 KiB
JavaScript
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)
|