| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- 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.fixedTags = data.fixedTags || [];
- this.tags = data.tags || [];
- this.writeAccess = data.accessType === 2;
- this.thumbnail = `/api/media/thumbnail/${data.md5sum}.jpg`;
- this.original = `/api/media/original/${data.md5sum}`;
- this.ui = null;
- this.tags = this.tags.reduce((acc, tag) => { acc.add(tag.replaceAll(/\/\/+/gi, '/')); return acc; }, new Set());
- this.fixedTags = this.fixedTags.reduce((acc, tag) => { acc.add(tag.replaceAll(/\/\/+/gi, '/')); return acc; }, new Set());
- 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),
- };
- }
- allTags() {
- return Array.from(new Set([...this.fixedTags, ...this.tags])).sort();
- }
- }
- 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.allMeta = {};
- this.allMetaTypes = {};
- this.allTags = new Set();
- this.medias = [];
- this.oldest = null;
- this.newest = null;
- }
- #pushMeta(metaKey, metaVal) {
- if (metaKey === 'dateTime')
- return;
- if (!this.allMeta[metaKey])
- this.allMeta[metaKey] = new Set();
- this.allMeta[metaKey].add(metaVal.value);
- if (!this.allMetaTypes[metaKey])
- this.allMetaTypes[metaKey] = { type: metaVal.type, canBeEmpty: !!this.medias.length };
- }
- #pushTag(tag, first) {
- while (tag.length && tag.endsWith('/'))
- tag = tag.substr(0, tag.length -1);
- this.allTags.add(tag);
- let index = tag.lastIndexOf('/');
- if (index >= 0)
- this.#pushTag(tag.substr(0, index));
- }
- #pushUnique(media) {
- for (let i of media.tags)
- this.#pushTag(i, true);
- for (let i of media.fixedTags)
- this.#pushTag(i, true);
- for (let key in media.meta)
- this.#pushMeta(key, media.meta[key]);
- for (let key in this.allMetaTypes)
- if (!media.meta[key])
- this.allMetaTypes[key].canBeEmpty = true;
- this.medias.push(media);
- media.md5sum === 'b1bc7614d67333cacb60af149ed5ee1f' && console.log(this);
- }
- pushAll(arr, partialLoad) {
- let result = [];
- let reorder = false;
- for (let i of arr) {
- 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;
- }
- if (this.medias.length && this.medias[this.medias.length -1].date.getTime() < i.date.getTime())
- reorder = true;
- if (this.medias.find(x => x.md5sum === i.md5sum))
- continue;
- this.#pushUnique(i);
- 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"));
- }
- }
- onFilterUpdated() {
- 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();
|