98 lines
3.0 KiB
Svelte
98 lines
3.0 KiB
Svelte
<script>
|
|
import { createEventDispatcher, onMount } from 'svelte';
|
|
import { fetcher, request } from './http.js';
|
|
|
|
const dispatch = createEventDispatcher();
|
|
|
|
export let photo;
|
|
$: raw = request('GET', photo).url;
|
|
|
|
let title = '';
|
|
|
|
let size = { width: 1, height: 1 };
|
|
$: ar = size.width / size.height;
|
|
|
|
let tags = [];
|
|
|
|
async function getPhotoMetadataTitle() {
|
|
const objectBase = photo.replace('photo/', 'photometadata/');
|
|
const resp = await fetcher(request('GET', objectBase + '/title'));
|
|
return resp.text();
|
|
}
|
|
onMount(async () => {
|
|
try {
|
|
title = await getPhotoMetadataTitle();
|
|
} catch (e) {
|
|
// We can ignore missing titles
|
|
}
|
|
});
|
|
async function getPhotoMetadataSize() {
|
|
const objectBase = photo.replace('photo/', 'photometadata/');
|
|
const resp = await fetcher(request('GET', objectBase + '/size'));
|
|
return resp.json();
|
|
}
|
|
onMount(async () => {
|
|
try {
|
|
size = await getPhotoMetadataSize();
|
|
dispatch('sizechange');
|
|
} catch (e) {
|
|
// TODO: Emit error
|
|
}
|
|
});
|
|
async function getPhotoMetadataTags() {
|
|
const objectBase = photo.replace('photo/', 'photometadata/');
|
|
const resp = await fetcher(request('GET', objectBase + '/tags'));
|
|
const str = await resp.text();
|
|
return str.split(",");
|
|
}
|
|
onMount(async () => {
|
|
try {
|
|
tags = await getPhotoMetadataTags();
|
|
} catch (e) {
|
|
// We can ignore missing tags
|
|
}
|
|
});
|
|
|
|
function preview(height, format, quality) {
|
|
const objectBase = photo.replace('photo/', 'preview/');
|
|
const extIndex = objectBase.lastIndexOf(".");
|
|
const base = objectBase.substring(0, extIndex);
|
|
const res = base + `_h${height}q${quality}`;
|
|
const ext = extensionByType(format)
|
|
return request('GET', res + ext).url;
|
|
}
|
|
|
|
function extensionByType(format) {
|
|
return {
|
|
"image/webp": ".webp",
|
|
"image/jpeg": ".jpg",
|
|
}[format];
|
|
}
|
|
</script>
|
|
|
|
<div class="gallery-item preloaded-thumbnail" title="{title}" data-ar="{ar}">
|
|
<picture style="display: none;">
|
|
<source srcset="{preview(320, 'image/webp', 70)} 2x, {preview(160, 'image/webp', 70)} 1x" type="image/webp" media="(max-width: 900px)">
|
|
<source srcset="{preview(640, 'image/webp', 70)} 2x, {preview(320, 'image/webp', 70)} 1x" type="image/webp">
|
|
<source srcset="{preview(320, 'image/jpeg', 70)} 2x, {preview(160, 'image/jpeg', 70)} 1x" media="(max-width: 900px)">
|
|
<source srcset="{preview(640, 'image/jpeg', 70)} 2x, {preview(320, 'image/jpeg', 70)} 1x">
|
|
<img src="{preview(320, 'image/jpeg', 70)}"
|
|
alt=""
|
|
width="{ar * 320}"
|
|
height="320"
|
|
loading="lazy"
|
|
data-enlarge-preload-for="{photo}">
|
|
</picture>
|
|
<picture class="preloaded-thumbnail-image">
|
|
<source srcset="{preview(30, 'image/webp', 34)} 1x" type="image/webp" media="(max-width: 900px)">
|
|
<source srcset="{preview(60, 'image/webp', 34)} 1x" type="image/webp">
|
|
<source srcset="{preview(30, 'image/jpeg', 34)} 1x" media="(max-width: 900px)">
|
|
<source srcset="{preview(60, 'image/jpeg', 34)} 1x">
|
|
<img src="{preview(30, 'image/jpeg', 34)}"
|
|
alt=""
|
|
width="{ar * 320}"
|
|
height="320">
|
|
</picture>
|
|
</div>
|
|
<!-- vim: set ft=html: -->
|