1
0
Fork 0
photos/web/manage/src/Photo.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: -->