From 254230485ee5a573d57bf6738908460223fec1f9 Mon Sep 17 00:00:00 2001 From: heikomat Date: Sun, 28 May 2023 23:53:23 +0200 Subject: [PATCH 1/4] prevent loading already loaded images on first photo-open --- frontend/src/common/viewer.js | 81 ------------------------------ frontend/src/page/album/photos.vue | 2 +- frontend/src/page/photos.vue | 2 +- 3 files changed, 2 insertions(+), 83 deletions(-) diff --git a/frontend/src/common/viewer.js b/frontend/src/common/viewer.js index 89ea4856d79..94a83af677f 100644 --- a/frontend/src/common/viewer.js +++ b/frontend/src/common/viewer.js @@ -27,8 +27,6 @@ import PhotoSwipe from "photoswipe"; import PhotoSwipeUI_Default from "photoswipe/dist/photoswipe-ui-default.js"; import Event from "pubsub-js"; import Util from "util.js"; -import Api from "./api"; -import Thumb from "model/thumb"; const thumbs = window.__CONFIG__.thumbs; @@ -219,85 +217,6 @@ class Viewer { return "fit_7680"; } - - static show(ctx, index) { - if (ctx.loading || !ctx.listen || ctx.viewer.loading || !ctx.results[index]) { - return false; - } - - const selected = ctx.results[index]; - - if (!ctx.viewer.dirty && ctx.viewer.results && ctx.viewer.results.length > index) { - // Reuse existing viewer result if possible. - let i = -1; - - if (ctx.viewer.results[index] && ctx.viewer.results[index].UID === selected.UID) { - i = index; - } else { - i = ctx.viewer.results.findIndex((p) => p.UID === selected.UID); - } - - if ( - i > -1 && - (((ctx.viewer.complete || ctx.complete) && - ctx.viewer.results.length >= ctx.results.length) || - i + ctx.viewer.batchSize <= ctx.viewer.results.length) - ) { - ctx.$viewer.show(ctx.viewer.results, i); - return; - } - } - - // Fetch photos from server API. - ctx.viewer.loading = true; - - const params = ctx.searchParams(); - params.count = params.offset + ctx.viewer.batchSize; - params.offset = 0; - - // Fetch viewer results from API. - return Api.get("photos/view", { params }) - .then((response) => { - const count = response && response.data ? response.data.length : 0; - if (count === 0) { - ctx.$notify.warn(ctx.$gettext("No pictures found")); - ctx.viewer.dirty = true; - ctx.viewer.complete = false; - return; - } - - // Process response. - if (response.headers && response.headers["x-count"]) { - const c = parseInt(response.headers["x-count"]); - const l = parseInt(response.headers["x-limit"]); - ctx.viewer.complete = c < l; - } else { - ctx.viewer.complete = ctx.complete; - } - - let i; - - if (response.data[index] && response.data[index].UID === selected.UID) { - i = index; - } else { - i = response.data.findIndex((p) => p.UID === selected.UID); - } - - ctx.viewer.results = Thumb.wrap(response.data); - - // Show photos. - ctx.$viewer.show(ctx.viewer.results, i); - ctx.viewer.dirty = false; - }) - .catch(() => { - ctx.viewer.dirty = true; - ctx.viewer.complete = false; - }) - .finally(() => { - // Unblock. - ctx.viewer.loading = false; - }); - } } export default Viewer; diff --git a/frontend/src/page/album/photos.vue b/frontend/src/page/album/photos.vue index c310c1cd5e2..cc554abf5a1 100644 --- a/frontend/src/page/album/photos.vue +++ b/frontend/src/page/album/photos.vue @@ -248,7 +248,7 @@ export default { } else if (showMerged) { this.$viewer.show(Thumb.fromFiles([selected]), 0); } else { - Viewer.show(this, index); + this.$viewer.show(Thumb.fromPhotos(this.results), index); } return true; diff --git a/frontend/src/page/photos.vue b/frontend/src/page/photos.vue index 74919981a13..d60c551c215 100644 --- a/frontend/src/page/photos.vue +++ b/frontend/src/page/photos.vue @@ -330,7 +330,7 @@ export default { } else if (showMerged) { this.$viewer.show(Thumb.fromFiles([selected]), 0); } else { - Viewer.show(this, index); + this.$viewer.show(Thumb.fromPhotos(this.results), index); } return true; From cb996c884a91d80bae1532961b8ccc256eeb3c43 Mon Sep 17 00:00:00 2001 From: heikomat Date: Mon, 29 May 2023 21:37:51 +0200 Subject: [PATCH 2/4] make photos compatible woth viewer --- frontend/src/model/photo.js | 47 ++++++++++++++++++++++--- frontend/src/model/thumb.js | 11 ------ frontend/src/page/album/photos.vue | 5 ++- frontend/src/page/photos.vue | 5 ++- frontend/tests/unit/model/thumb_test.js | 2 +- 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/frontend/src/model/photo.js b/frontend/src/model/photo.js index d727d3d16a9..fd21df79d26 100644 --- a/frontend/src/model/photo.js +++ b/frontend/src/model/photo.js @@ -69,6 +69,7 @@ export const TimeZoneUTC = "UTC"; const num = "numeric"; const short = "short"; const long = "long"; +const thumbs = window.__CONFIG__.thumbs; export const DATE_FULL = { year: num, @@ -94,6 +95,38 @@ export let BatchSize = 120; export class Photo extends RestModel { constructor(values) { super(values); + this.Thumbs = this.generateThumbs(); + this.DownloadUrl = this.getDownloadUrl(); + } + + generateThumbs() { + let sourceWidth = this.Width; + let sourceHeight = this.Height; + if (this.Files) { + const mainFile = this.mainFile(); + if (mainFile) { + sourceWidth = mainFile.Width; + sourceHeight = mainFile.Height; + } + } + + if (!this.Hash) { + return {}; + } + + const result = {}; + for (let i = 0; i < thumbs.length; i++) { + let t = thumbs[i]; + let size = this.calculateSizeFromProps(t.w, t.h, sourceWidth, sourceHeight); + + result[t.size] = { + src: this.thumbnailUrl(t.size), + w: size.width, + h: size.height, + }; + } + + return result; } getDefaults() { @@ -189,6 +222,8 @@ export class Photo extends RestModel { EditedAt: null, CheckedAt: null, DeletedAt: null, + Thumbs: {}, + DownloadUrl: "", }; } @@ -662,13 +697,13 @@ export class Photo extends RestModel { }); } - calculateSize(width, height) { - if (width >= this.Width && height >= this.Height) { + calculateSizeFromProps(width, height, sourceWidth, sourceHeight) { + if (width >= sourceWidth && height >= sourceHeight) { // Smaller - return { width: this.Width, height: this.Height }; + return { width: sourceWidth, height: sourceHeight }; } - const srcAspectRatio = this.Width / this.Height; + const srcAspectRatio = sourceWidth / sourceHeight; const maxAspectRatio = width / height; let newW, newH; @@ -684,6 +719,10 @@ export class Photo extends RestModel { return { width: newW, height: newH }; } + calculateSize(width, height) { + return this.calculateSizeFromProps(width, height, this.Width, this.Height); + } + getDateString(showTimeZone) { return this.generateDateString( showTimeZone, diff --git a/frontend/src/model/thumb.js b/frontend/src/model/thumb.js index 3d2f9aeb803..df625a387f9 100644 --- a/frontend/src/model/thumb.js +++ b/frontend/src/model/thumb.js @@ -95,17 +95,6 @@ export class Thumb extends Model { return result; } - static fromPhotos(photos) { - let result = []; - const n = photos.length; - - for (let i = 0; i < n; i++) { - result.push(this.fromPhoto(photos[i])); - } - - return result; - } - static fromPhoto(photo) { if (photo.Files) { return this.fromFile(photo, photo.mainFile()); diff --git a/frontend/src/page/album/photos.vue b/frontend/src/page/album/photos.vue index cc554abf5a1..cd0a520c5a9 100644 --- a/frontend/src/page/album/photos.vue +++ b/frontend/src/page/album/photos.vue @@ -53,7 +53,6 @@ import {Photo, MediaLive, MediaRaw, MediaVideo, MediaAnimated} from "model/photo import Album from "model/album"; import Thumb from "model/thumb"; import Event from "pubsub-js"; -import Viewer from "common/viewer"; export default { name: 'PPageAlbumPhotos', @@ -243,12 +242,12 @@ export default { if (selected.isPlayable()) { this.$viewer.play({video: selected, album: this.album}); } else { - this.$viewer.show(Thumb.fromPhotos(this.results), index); + this.$viewer.show(this.results, index); } } else if (showMerged) { this.$viewer.show(Thumb.fromFiles([selected]), 0); } else { - this.$viewer.show(Thumb.fromPhotos(this.results), index); + this.$viewer.show(this.results, index); } return true; diff --git a/frontend/src/page/photos.vue b/frontend/src/page/photos.vue index d60c551c215..75692702bbb 100644 --- a/frontend/src/page/photos.vue +++ b/frontend/src/page/photos.vue @@ -47,7 +47,6 @@