import * as sfw from 'sfw'; const { Div, Img } = sfw.element.native; import Month from '../../month.js'; import Image from '../../widgets/image/index.js'; const css = await sfw.css(import.meta.url, './index.css') export default class ImageViewer extends sfw.element.Container { #container #subtitle #images #current_month constructor() { super({ css }); this.#current_month = null; this.#images = []; this.body.append( this.#container = Div.new({ id: 'container', onscroll: () => this.preload_all(), children: [ this.#subtitle = Div.new({ id: 'subtitle', innerHTML: 'Powered by Memora' }) ], }) ); } add(metadata) { const month = Month.from_unix(metadata.timestamp); if (month != this.#current_month && !(month?.is_same(this.#current_month))) { const content = month == null ? 'No Date' : `${month.name} ${month.year}`; this.#current_month = month; const title = Div.new({ id: 'date', innerText: content, }) this.#container.insertBefore(title, this.#subtitle); } const image = Image.new({ metadata }); this.#images.push(image); this.#container.insertBefore(image, this.#subtitle); } clear() { this.#container.innerHTML = ''; this.#container.append(this.#subtitle); } jump_to(month) { const image = this.#images.find(i => i.month == month || i.month.is_same(month)); image.scrollIntoView({ behavior: 'instant' }) } preload_all() { this.#images.forEach(image => this.#preload(image)) } #preload(image) { const loading_zone_after = (this.#container.scrollTop + this.#container.offsetHeight) * 2; const loading_zone_before = this.#container.scrollTop - image.offsetHeight * 2; if (loading_zone_before < image.offsetTop && image.offsetTop < loading_zone_after) { image.load(); } } }