class Media { constructor(data) { this.date = new Date(data.date); this.md5sum = data.md5sum; this.path = data.path; this.fileName = data.fileName; this.meta = data.meta || {}; this.tags = data.tags || []; this.thumbnail = `/api/media/thumbnail/${data.md5sum}.jpg`; this.original = `/api/media/original/${data.md5sum}`; this.ui = null; for (let i in this.meta) { if (this.meta[i].type === 'date') this.meta[i].value = new Date(parseInt(this.meta[i].value)); else if (this.meta[i].type === 'number' || this.meta[i].type === 'octet') this.meta[i].value = parseInt(this.meta[i].value); else if (this.meta[i].type === 'string') this.meta[i].value = '' + this.meta[i].value; } } resize(maxWidth, maxHeight) { let ratio = Math.min(1, Math.max( maxWidth / (this.meta?.width || maxWidth), maxHeight / (this.meta?.height || maxHeight))); return { width: Math.floor(this.meta.width *ratio), height: Math.floor(this.meta.height *ratio), }; } } function tryLoadMedia(md5sum) { return new Promise((ok, ko) => { $.get("/api/media/" +md5sum, data => { let item = new Media(data); MediaStorage.Instance.pushAll([item], true); ok(item); }).fail(err => { console.error("Trying to get media with md5sum " +md5sum +" failed:", err.responseText); ok(null); }); }); } class MediaStorage extends EventTarget { constructor() { super(); this.medias = []; this.oldest = null; this.newest = null; } pushAll(arr, partialLoad) { let result = []; let reorder = false; for (let i of arr) { if (this.medias.find(x => x.md5sum === i.md5sum)) continue; if (this.medias.length && this.medias[this.medias.length -1].date.getTime() < i.date.getTime()) reorder = true; this.medias.push(i); if (partialLoad !== true) { this.oldest = !this.oldest || this.oldest.date.getTime() > i.date.getTime() ? i : this.oldest; this.newest = !this.newest || this.newest.date.getTime() < i.date.getTime() ? i : this.newest; } result.push(i); } for (let i of result) this.dispatchEvent(new CustomEvent("newMedia", { detail: i })); if (reorder) { this.medias.sort((a, b) => b.date.getTime() - a.date.getTime()); this.dispatchEvent(new CustomEvent("rebuildMedia")); } } getMediaIndex(media) { return this.medias.indexOf(media); } nextMedia(current) { return this.medias[this.getMediaIndex(current) +1]; } previousMedia(current) { return this.medias[this.getMediaIndex(current) -1]; } getMediaBetweenIndexes(a, b) { if (a > b) return this.getMediaBetweenIndexes(b, a); return this.medias.slice(a, b +1); } getMediaBetween(a, b) { let aIndex = this.medias.indexOf(a); let bIndex = this.medias.indexOf(b); if (aIndex < 0 || bIndex < 0 || aIndex === bIndex) return []; return this.getMediaBetweenIndexes(aIndex, bIndex); } async getMedia(md5sum) { let media = this.medias.find(x => x.md5sum === md5sum); if (media) return media; return await tryLoadMedia(md5sum); } } MediaStorage.Instance = new MediaStorage();