diff --git a/packages/gallery/src/interface/components/albumPhotoTemplate.js b/packages/gallery/src/interface/components/albumPhotoTemplate.js index 48f8ae6..e0cee7a 100644 --- a/packages/gallery/src/interface/components/albumPhotoTemplate.js +++ b/packages/gallery/src/interface/components/albumPhotoTemplate.js @@ -35,7 +35,8 @@ export function AlbumPhotoTemplate(vm, { doc }) { _data: doc }, [ - AttachmentImageView(doc, { + AttachmentImageView({ + src: doc.sizes.thumbnail || doc.sizes.full, css: { transform: isSelected ? 'translateZ(-50px)' : null } diff --git a/packages/gallery/src/interface/components/attachmentImage.js b/packages/gallery/src/interface/components/attachmentImage.js index 87f13c6..9681176 100644 --- a/packages/gallery/src/interface/components/attachmentImage.js +++ b/packages/gallery/src/interface/components/attachmentImage.js @@ -9,46 +9,35 @@ import { DEFAULT_TRANSITION } from '../styles.js'; const srcMap = new Map(); -async function loadImageFromBlob(doc, evt, node, vm) { - const { sizes, _id } = doc; - const options = ['thumbnail', 'preview', 'full'].filter(o => sizes.hasOwnProperty(o)); - - for (let attempt of options) { - try { - const data = await FileType.getFromURL(sizes[attempt]); - let src = evt.target.src; - if (src.startsWith('blob:')) { - URL.revokeObjectURL(src); - } - src = URL.createObjectURL(data); - node.patch({ src }); - srcMap.set(_id, src); - // node.data = attempt; - break; - } catch (err) { - continue; - } +async function loadImageFromBlob(srcUrl, evt, node, vm) { + try { + const src = URL.createObjectURL(await FileType.getFromURL(srcUrl)); + node.patch({ src }); + srcMap.set(srcUrl, src); + } catch (e) { + // src is not a saved file source } } function cleanup(node) { - const src = node.el.src; - if (src.startsWith('blob:')) { + const { src } = node.el; + if (src.startsWith('blob:') && srcMap.has(node.key)) { URL.revokeObjectURL(src); srcMap.delete(node.key); } } -export function AttachmentImageView(doc, props) { - const { sizes, _id } = doc; - const src = srcMap.get(_id) || sizes.thumbnail || sizes.preview || sizes.full; +export function AttachmentImageView(props) { + const { src } = props; + const cachedSrc = srcMap.get(src); + const _src = cachedSrc || src; + delete props.src; return image( Object.assign( { - src, - onerror: [loadImageFromBlob, doc], - _key: _id, + src: _src, + onerror: !cachedSrc ? [loadImageFromBlob, _src] : null, _hooks: { willRemove: cleanup } diff --git a/packages/gallery/src/sw.js b/packages/gallery/src/sw.js index d2fb136..a79b7ad 100644 --- a/packages/gallery/src/sw.js +++ b/packages/gallery/src/sw.js @@ -1,4 +1,14 @@ import { FileType } from './data/file.js'; +import { log } from './services/console.js'; + +const http404 = url => () => { + log(`ServiceWorker could not find ${url}`); + return new Response(null, { + status: 404, + statusText: 'NOT FOUND', + headers: {} + }); +}; self.addEventListener('fetch', event => { const requestUrl = new URL(event.request.url); @@ -6,30 +16,24 @@ self.addEventListener('fetch', event => { if (requestUrl.pathname && requestUrl.pathname.startsWith('/file/')) { event.respondWith( FileType.getFromURL(requestUrl.pathname) - .then( - data => - data - ? new Response(data, { - status: 200, - statusText: 'OK', - headers: { - 'Content-Type': data.mimetype - } - }) - : new Response(null, { - status: 404, - statusText: 'NOT FOUND', - headers: {} - }) - ) - .catch( - () => - new Response(null, { - status: 404, - statusText: 'NOT FOUND', - headers: {} - }) - ) + .then(data => { + if (data) { + log( + `ServiceWorker serving ${requestUrl.pathname} ${data.type} ${(data.size / 1024).toFixed( + 2 + )}kb` + ); + return new Response(data, { + status: 200, + statusText: 'OK', + headers: { + 'Content-Type': data.type + } + }); + } + return http404(requestUrl.pathname)(); + }) + .catch(http404(requestUrl.pathname)) ); } });