Frontend: Improve photo viewer loading #309 #370

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-07-02 11:39:19 +02:00
parent 2635df7f06
commit 7c07e42b55
3 changed files with 169 additions and 106 deletions

View file

@ -88,6 +88,7 @@
subscriptions: [],
listen: false,
dirty: false,
complete: false,
model: new Album(),
uid: uid,
results: [],
@ -164,9 +165,13 @@
this.$viewer.show(Thumb.fromFiles([selected]), 0)
} else {
this.viewerResults().then((results) => {
const thumbs = Thumb.fromPhotos(results);
const thumbsIndex = thumbs.findIndex(t => t.uid === selected.UID);
this.$viewer.show(thumbs, thumbsIndex ? thumbsIndex : 0);
const thumbsIndex = results.findIndex(result => result.UID === selected.UID);
if(thumbsIndex < 0) {
this.$viewer.show(Thumb.fromPhotos(this.results), index);
} else {
this.$viewer.show(Thumb.fromPhotos(results), thumbsIndex);
}
});
}
@ -177,11 +182,11 @@
return Promise.reject();
}
if (this.scrollDisabled) {
if (this.complete) {
return Promise.resolve(this.results);
}
if (this.viewer.results.length > 0) {
if (this.viewer.results.length >= this.results.length) {
return Promise.resolve(this.viewer.results);
}
@ -240,14 +245,10 @@
Photo.search(params).then(response => {
this.results = Photo.mergeResponse(this.results, response);
this.complete = (response.count < count);
this.scrollDisabled = this.complete;
if(offset === 0) {
this.viewer.results = [];
}
this.scrollDisabled = (response.count < count);
if (this.scrollDisabled) {
if (this.complete) {
this.offset = offset;
if (this.results.length > 1) {
@ -256,6 +257,7 @@
} else if (this.results.length >= Photo.limit()) {
this.offset = offset;
this.scrollDisabled = true;
this.complete = true;
this.$notify.warn(this.$gettext("Can't load more, limit reached"));
} else {
this.offset = offset + count;
@ -267,6 +269,10 @@
this.dirty = false;
this.loading = false;
this.listen = true;
if(offset === 0) {
this.viewerResults();
}
});
},
updateQuery() {
@ -306,11 +312,16 @@
return params;
},
refresh() {
if (this.loading) return;
if (this.loading) {
return;
}
this.loading = true;
this.page = 0;
this.dirty = true;
this.complete = false;
this.scrollDisabled = false;
this.loadMore();
},
search() {
@ -328,18 +339,17 @@
this.page = 0;
this.loading = true;
this.listen = false;
this.complete = false;
const params = this.searchParams();
Photo.search(params).then(response => {
this.offset = this.pageSize;
this.results = response.models;
this.viewer.results = [];
this.complete = (response.count < this.pageSize);
this.scrollDisabled = this.complete;
this.scrollDisabled = (response.count < this.pageSize);
if (this.scrollDisabled) {
if (this.complete) {
if (!this.results.length) {
this.$notify.warn(this.$gettext("No entries found"));
} else if (this.results.length === 1) {
@ -356,6 +366,8 @@
this.dirty = false;
this.loading = false;
this.listen = true;
this.viewerResults();
});
},
findAlbum() {
@ -388,6 +400,7 @@
window.document.title = `${this.$config.get("siteTitle")}: ${this.model.Title}`
this.dirty = true;
this.complete = false;
this.scrollDisabled = false;
if (this.filter.order !== this.model.Order) {
@ -401,6 +414,24 @@
}
}
},
updateResult(results, values) {
const model = results.find((m) => m.UID === values.UID);
if (model) {
for (let key in values) {
if (values.hasOwnProperty(key) && values[key] != null && typeof values[key] !== "object") {
model[key] = values[key];
}
}
}
},
removeResult(results, uid) {
const index = results.findIndex((m) => m.UID === uid);
if (index >= 0) {
results.splice(index, 1);
}
},
onUpdate(ev, data) {
if (!this.listen) return;
@ -408,43 +439,33 @@
return
}
this.viewer.results = [];
const type = ev.split('.')[1];
switch (type) {
case 'updated':
for (let i = 0; i < data.entities.length; i++) {
const values = data.entities[i];
const model = this.results.find((m) => m.UID === values.UID);
if (model) {
for (let key in values) {
if (values.hasOwnProperty(key) && values[key] != null && typeof values[key] !== "object") {
model[key] = values[key];
}
}
}
this.updateResult(this.results, values);
this.updateResult(this.viewer.results, values);
}
break;
case 'restored':
this.dirty = true;
this.scrollDisabled = false;
this.complete = false;
this.loadMore();
break;
case 'archived':
this.dirty = true;
this.complete = false;
for (let i = 0; i < data.entities.length; i++) {
const uid = data.entities[i];
const index = this.results.findIndex((m) => m.UID === uid);
if (index >= 0) {
this.results.splice(index, 1);
}
this.removeResult(this.results, uid);
this.removeResult(this.viewer.results, uid);
this.$clipboard.removeId(uid);
}

View file

@ -105,6 +105,7 @@
subscriptions: [],
listen: false,
dirty: false,
complete: false,
results: [],
scrollDisabled: true,
pageSize: 60,
@ -204,9 +205,13 @@
this.$viewer.show(Thumb.fromFiles([selected]), 0)
} else {
this.viewerResults().then((results) => {
const thumbs = Thumb.fromPhotos(results);
const thumbsIndex = thumbs.findIndex(t => t.uid === selected.UID);
this.$viewer.show(thumbs, thumbsIndex ? thumbsIndex : 0);
const thumbsIndex = results.findIndex(result => result.UID === selected.UID);
if(thumbsIndex < 0) {
this.$viewer.show(Thumb.fromPhotos(this.results), index);
} else {
this.$viewer.show(Thumb.fromPhotos(results), thumbsIndex);
}
});
}
},
@ -215,17 +220,17 @@
return Promise.reject();
}
if (this.scrollDisabled) {
if (this.complete) {
return Promise.resolve(this.results);
}
if (this.viewer.results.length > 0) {
if (this.viewer.results.length > (this.results.length + this.pageSize)) {
return Promise.resolve(this.viewer.results);
}
this.viewer.loading = true;
const count = Photo.limit();
const count = this.pageSize*(this.page + 6);
const offset = 0;
const params = {
@ -275,14 +280,10 @@
Photo.search(params).then(response => {
this.results = Photo.mergeResponse(this.results, response);
this.complete = (response.count < count);
this.scrollDisabled = this.complete;
if(offset === 0) {
this.viewer.results = [];
}
this.scrollDisabled = (response.count < count);
if (this.scrollDisabled) {
if (this.complete) {
this.offset = offset;
if (this.results.length > 1) {
@ -290,6 +291,7 @@
}
} else if (this.results.length >= Photo.limit()) {
this.offset = offset;
this.complete = true;
this.scrollDisabled = true;
this.$notify.warn(this.$gettext("Can't load more, limit reached"));
} else {
@ -302,6 +304,10 @@
this.dirty = false;
this.loading = false;
this.listen = true;
if(offset === 0) {
this.viewerResults();
}
});
},
updateQuery() {
@ -339,11 +345,16 @@
return params;
},
refresh() {
if (this.loading) return;
if (this.loading) {
return;
}
this.loading = true;
this.page = 0;
this.dirty = true;
this.complete = false;
this.scrollDisabled = false;
this.loadMore();
},
search() {
@ -361,18 +372,17 @@
this.page = 0;
this.loading = true;
this.listen = false;
this.complete = false;
const params = this.searchParams();
Photo.search(params).then(response => {
this.offset = this.pageSize;
this.results = response.models;
this.viewer.results = [];
this.complete = (response.count < this.pageSize);
this.scrollDisabled = this.complete;
this.scrollDisabled = (response.count < this.pageSize);
if (this.scrollDisabled) {
if (this.complete) {
if (!this.results.length) {
this.$notify.warn(this.$gettext("No photos found"));
} else if (this.results.length === 1) {
@ -389,6 +399,8 @@
this.dirty = false;
this.loading = false;
this.listen = true;
this.viewerResults();
});
},
onImportCompleted() {
@ -396,6 +408,24 @@
this.loadMore();
},
updateResult(results, values) {
const model = results.find((m) => m.UID === values.UID);
if (model) {
for (let key in values) {
if (values.hasOwnProperty(key) && values[key] != null && typeof values[key] !== "object") {
model[key] = values[key];
}
}
}
},
removeResult(results, uid) {
const index = results.findIndex((m) => m.UID === uid);
if (index >= 0) {
results.splice(index, 1);
}
},
onUpdate(ev, data) {
if (!this.listen) return;
@ -403,52 +433,42 @@
return
}
this.viewer.results = [];
const type = ev.split('.')[1];
switch (type) {
case 'updated':
for (let i = 0; i < data.entities.length; i++) {
const values = data.entities[i];
const model = this.results.find((m) => m.UID === values.UID);
if (model) {
for (let key in values) {
if (values.hasOwnProperty(key) && values[key] != null && typeof values[key] !== "object") {
model[key] = values[key];
}
}
}
this.updateResult(this.results, values);
this.updateResult(this.viewer.results, values);
}
break;
case 'restored':
this.dirty = true;
this.complete = false;
if (this.context !== "archive") break;
for (let i = 0; i < data.entities.length; i++) {
const uid = data.entities[i];
const index = this.results.findIndex((m) => m.UID === uid);
if (index >= 0) {
this.results.splice(index, 1);
}
this.removeResult(this.results, uid);
this.removeResult(this.viewer.results, uid);
}
break;
case 'archived':
this.dirty = true;
this.complete = false;
if (this.context === "archive") break;
for (let i = 0; i < data.entities.length; i++) {
const uid = data.entities[i];
const index = this.results.findIndex((m) => m.UID === uid);
if (index >= 0) {
this.results.splice(index, 1);
}
this.removeResult(this.results, uid);
this.removeResult(this.viewer.results, uid);
this.$clipboard.removeId(uid);
}
@ -456,6 +476,7 @@
case 'created':
this.dirty = true;
this.scrollDisabled = false;
this.complete = false;
break;
default:

View file

@ -126,6 +126,7 @@
subscriptions: [],
listen: false,
dirty: false,
complete: false,
model: new Album(),
uid: uid,
results: [],
@ -207,9 +208,13 @@
this.$viewer.show(Thumb.fromFiles([selected]), 0)
} else {
this.viewerResults().then((results) => {
const thumbs = Thumb.fromPhotos(results);
const thumbsIndex = thumbs.findIndex(t => t.uid === selected.UID);
this.$viewer.show(thumbs, thumbsIndex ? thumbsIndex : 0);
const thumbsIndex = results.findIndex(result => result.UID === selected.UID);
if(thumbsIndex < 0) {
this.$viewer.show(Thumb.fromPhotos(this.results), index);
} else {
this.$viewer.show(Thumb.fromPhotos(results), thumbsIndex);
}
});
}
@ -220,11 +225,11 @@
return Promise.reject();
}
if(this.scrollDisabled) {
if (this.complete) {
return Promise.resolve(this.results);
}
if (this.viewer.results.length > 0) {
if (this.viewer.results.length >= this.results.length) {
return Promise.resolve(this.viewer.results);
}
@ -283,14 +288,10 @@
Photo.search(params).then(response => {
this.results = Photo.mergeResponse(this.results, response);
this.complete = (response.count < count);
this.scrollDisabled = this.complete;
if(offset === 0) {
this.viewer.results = [];
}
this.scrollDisabled = (response.count < count);
if (this.scrollDisabled) {
if (this.complete) {
this.offset = offset;
if (this.results.length > 1) {
@ -299,6 +300,7 @@
} else if (this.results.length >= Photo.limit()) {
this.offset = offset;
this.scrollDisabled = true;
this.complete = true;
this.$notify.warn(this.$gettext("Can't load more, limit reached"));
} else {
this.offset = offset + count;
@ -310,6 +312,10 @@
this.dirty = false;
this.loading = false;
this.listen = true;
if(offset === 0) {
this.viewerResults();
}
});
},
updateQuery() {
@ -349,11 +355,16 @@
return params;
},
refresh() {
if (this.loading) return;
if (this.loading) {
return;
}
this.loading = true;
this.page = 0;
this.dirty = true;
this.complete = false;
this.scrollDisabled = false;
this.loadMore();
},
search() {
@ -371,18 +382,17 @@
this.page = 0;
this.loading = true;
this.listen = false;
this.complete = false;
const params = this.searchParams();
Photo.search(params).then(response => {
this.offset = this.pageSize;
this.results = response.models;
this.viewer.results = [];
this.complete = (response.count < this.pageSize);
this.scrollDisabled = this.complete;
this.scrollDisabled = (response.count < this.pageSize);
if (this.scrollDisabled) {
if (this.complete) {
if (!this.results.length) {
this.$notify.warn(this.$gettext("No entries found"));
} else if (this.results.length === 1) {
@ -399,6 +409,8 @@
this.dirty = false;
this.loading = false;
this.listen = true;
this.viewerResults();
});
},
findAlbum() {
@ -431,6 +443,7 @@
window.document.title = `${this.$config.get("siteTitle")}: ${this.model.Title}`
this.dirty = true;
this.complete = false;
this.scrollDisabled = false;
if (this.filter.order !== this.model.Order) {
@ -444,6 +457,24 @@
}
}
},
updateResult(results, values) {
const model = results.find((m) => m.UID === values.UID);
if (model) {
for (let key in values) {
if (values.hasOwnProperty(key) && values[key] != null && typeof values[key] !== "object") {
model[key] = values[key];
}
}
}
},
removeResult(results, uid) {
const index = results.findIndex((m) => m.UID === uid);
if (index >= 0) {
results.splice(index, 1);
}
},
onUpdate(ev, data) {
if (!this.listen) return;
@ -451,43 +482,33 @@
return
}
this.viewer.results = [];
const type = ev.split('.')[1];
switch (type) {
case 'updated':
for (let i = 0; i < data.entities.length; i++) {
const values = data.entities[i];
const model = this.results.find((m) => m.UID === values.UID);
if (model) {
for (let key in values) {
if (values.hasOwnProperty(key) && values[key] != null && typeof values[key] !== "object") {
model[key] = values[key];
}
}
}
this.updateResult(this.results, values);
this.updateResult(this.viewer.results, values);
}
break;
case 'restored':
this.dirty = true;
this.scrollDisabled = false;
this.complete = false;
this.loadMore();
break;
case 'archived':
this.dirty = true;
this.complete = false;
for (let i = 0; i < data.entities.length; i++) {
const uid = data.entities[i];
const index = this.results.findIndex((m) => m.UID === uid);
if (index >= 0) {
this.results.splice(index, 1);
}
this.removeResult(this.results, uid);
this.removeResult(this.viewer.results, uid);
this.$clipboard.removeId(uid);
}