Skip to content

Instantly share code, notes, and snippets.

@skrat
Created April 24, 2021 19:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skrat/6cc9ede841a353df96c4fa4debc8ee7d to your computer and use it in GitHub Desktop.
Save skrat/6cc9ede841a353df96c4fa4debc8ee7d to your computer and use it in GitHub Desktop.
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