Created
April 24, 2021 19:51
-
-
Save skrat/6cc9ede841a353df96c4fa4debc8ee7d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const template = document.createElement('template'); | |
template.innerHTML = ` | |
<style> | |
.loading { | |
font-weight: bold; | |
animation: Pulsate 4s linear infinite; | |
} | |
@keyframes Pulsate { | |
from { opacity: 1; } | |
50% { opacity: 0.25; } | |
to { opacity: 1; } | |
} | |
</style> | |
<div class="container"> | |
<p class="loading">Loading photos....</p> | |
<div class="thumbs"></div> | |
</div> | |
`; | |
async function createSession(share) { | |
const url = new URL(share); | |
const token = url.pathname.match(/s\/([^\/]+)\//)[1] | |
url.pathname = "/api/v1/session"; | |
url.search = ""; | |
const { id, config, data } = await (await fetch( | |
url.toString(), { | |
method: 'POST', | |
headers: { | |
'Accept': 'application/json', | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({ token }) | |
} | |
)).json(); | |
const albumUid = data.shares[0]; | |
const previewToken = config.previewToken; | |
return { sessionId: id, previewToken, albumUid }; | |
} | |
function photoQuery(albumUid) { | |
return { | |
album: albumUid, | |
camera: 0, | |
count: 60, | |
country: '', | |
filter: '', | |
merged: 'true', | |
offset: 0, | |
order: 'oldest', | |
q: '' | |
}; | |
} | |
async function photoSearch(share, sessionId, params) { | |
const sparams = new URLSearchParams; | |
for (let name in params) | |
sparams.append(name, params[name]) | |
const url = new URL(share); | |
url.pathname = "/api/v1/photos"; | |
url.search = sparams.toString(); | |
return await (await fetch(url.toString(), { | |
headers: { | |
'X-Session-ID': sessionId | |
} | |
})).json() | |
} | |
function photoThumb(share, previewToken) { | |
const url = new URL(share); | |
url.search = "" | |
return function(photo) { | |
const hash = photo.Files[0].Hash | |
url.pathname = `/api/v1/t/${hash}/${previewToken}/tile_224` | |
const img = document.createElement('img') | |
img.src = url.toString() | |
return img | |
} | |
} | |
class PhotoprismAlbum extends HTMLElement { | |
constructor() { | |
super(); | |
this.share = "" | |
this._shadowRoot = this.attachShadow({ mode: 'open' }); | |
this._shadowRoot.appendChild(template.content.cloneNode(true)); | |
this.$loading = this._shadowRoot.querySelector('.loading'); | |
this.$thumbs = this._shadowRoot.querySelector('.thumbs'); | |
} | |
static get observedAttributes() { | |
return ['share']; | |
} | |
attributeChangedCallback(name, _oldVal, newVal) { | |
this[name] = newVal; | |
this.update().then((thumbs) => { this.render(thumbs) }); | |
} | |
async update() { | |
const { sessionId, previewToken, albumUid } = await createSession(this.share); | |
const photos = await photoSearch(this.share, sessionId, photoQuery(albumUid)); | |
return photos.map(photoThumb(this.share, previewToken)); | |
} | |
render(thumbs) { | |
this.$loading.style.display = 'none' | |
this.$thumbs.innerHTML = '' | |
for (let t of thumbs) { | |
this.$thumbs.appendChild(t) | |
} | |
} | |
} | |
window.customElements.define('photoprism-album', PhotoprismAlbum); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment