UX: Restore scroll position in albums & labels #896
This commit is contained in:
parent
bc0bde4771
commit
67e655f6d0
|
@ -111,6 +111,19 @@ const router = new Router({
|
|||
routes: Routes,
|
||||
mode: "history",
|
||||
saveScrollPosition: true,
|
||||
scrollBehavior: (to, from, savedPosition) => {
|
||||
if (savedPosition) {
|
||||
return new Promise((resolve) => {
|
||||
Notify.ajaxWait().then(() => {
|
||||
setTimeout(() => {
|
||||
resolve(savedPosition);
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return { x: 0, y: 0 };
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
|
|
|
@ -31,6 +31,9 @@ https://docs.photoprism.org/developer-guide/
|
|||
import Event from "pubsub-js";
|
||||
import { $gettext } from "./vm";
|
||||
|
||||
let ajaxPending = 0;
|
||||
let ajaxCallbacks = [];
|
||||
|
||||
const Notify = {
|
||||
info: function (message) {
|
||||
Event.publish("notify.info", { message });
|
||||
|
@ -49,10 +52,34 @@ const Notify = {
|
|||
Event.publish("session.logout", { message });
|
||||
},
|
||||
ajaxStart: function () {
|
||||
ajaxPending++;
|
||||
Event.publish("ajax.start");
|
||||
},
|
||||
ajaxEnd: function () {
|
||||
ajaxPending--;
|
||||
Event.publish("ajax.end");
|
||||
|
||||
if (!this.ajaxBusy()) {
|
||||
ajaxCallbacks.forEach((resolve) => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
},
|
||||
ajaxBusy: function () {
|
||||
if (ajaxPending < 0) {
|
||||
ajaxPending = 0;
|
||||
}
|
||||
|
||||
return ajaxPending > 0;
|
||||
},
|
||||
ajaxWait: function () {
|
||||
return new Promise((resolve) => {
|
||||
if (this.ajaxBusy()) {
|
||||
ajaxCallbacks.push(resolve);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
blockUI: function () {
|
||||
const el = document.getElementById("busy-overlay");
|
||||
|
|
|
@ -283,6 +283,19 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
searchCount() {
|
||||
const offset = parseInt(window.localStorage.getItem("albums_offset"));
|
||||
|
||||
if(this.offset > 0 || !offset) {
|
||||
return this.batchSize;
|
||||
}
|
||||
|
||||
return offset + this.batchSize;
|
||||
},
|
||||
setOffset(offset) {
|
||||
this.offset = offset;
|
||||
window.localStorage.setItem("albums_offset", offset);
|
||||
},
|
||||
share(album) {
|
||||
this.model = album;
|
||||
this.dialog.share = true;
|
||||
|
@ -382,19 +395,19 @@ export default {
|
|||
Object.assign(params, this.staticFilter);
|
||||
}
|
||||
|
||||
Album.search(params).then(response => {
|
||||
this.results = this.dirty ? response.models : this.results.concat(response.models);
|
||||
Album.search(params).then(resp => {
|
||||
this.results = this.dirty ? resp.models : this.results.concat(resp.models);
|
||||
|
||||
this.scrollDisabled = (response.models.length < count);
|
||||
this.scrollDisabled = (resp.count < resp.limit);
|
||||
|
||||
if (this.scrollDisabled) {
|
||||
this.offset = offset;
|
||||
this.setOffset(resp.offset);
|
||||
|
||||
if (this.results.length > 1) {
|
||||
this.$notify.info(this.$gettextInterpolate(this.$gettext("All %{n} albums loaded"), {n: this.results.length}));
|
||||
}
|
||||
} else {
|
||||
this.offset = offset + count;
|
||||
this.setOffset(resp.offset + resp.limit);
|
||||
this.page++;
|
||||
|
||||
this.$nextTick(() => {
|
||||
|
@ -434,7 +447,7 @@ export default {
|
|||
},
|
||||
searchParams() {
|
||||
const params = {
|
||||
count: this.batchSize,
|
||||
count: this.searchCount(),
|
||||
offset: this.offset,
|
||||
};
|
||||
|
||||
|
@ -464,12 +477,11 @@ export default {
|
|||
|
||||
const params = this.searchParams();
|
||||
|
||||
Album.search(params).then(response => {
|
||||
this.offset = this.batchSize;
|
||||
Album.search(params).then(resp => {
|
||||
this.offset = resp.limit;
|
||||
this.results = resp.models;
|
||||
|
||||
this.results = response.models;
|
||||
|
||||
this.scrollDisabled = (response.models.length < this.batchSize);
|
||||
this.scrollDisabled = (resp.count < resp.limit);
|
||||
|
||||
if (this.scrollDisabled) {
|
||||
if (!this.results.length) {
|
||||
|
|
|
@ -196,6 +196,19 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
searchCount() {
|
||||
const offset = parseInt(window.localStorage.getItem("labels_offset"));
|
||||
|
||||
if(this.offset > 0 || !offset) {
|
||||
return this.batchSize;
|
||||
}
|
||||
|
||||
return offset + this.batchSize;
|
||||
},
|
||||
setOffset(offset) {
|
||||
this.offset = offset;
|
||||
window.localStorage.setItem("labels_offset", offset);
|
||||
},
|
||||
selectRange(rangeEnd, models) {
|
||||
if (!models || !models[rangeEnd] || !(models[rangeEnd] instanceof RestModel)) {
|
||||
console.warn("selectRange() - invalid arguments:", rangeEnd, models);
|
||||
|
@ -332,18 +345,18 @@ export default {
|
|||
Object.assign(params, this.staticFilter);
|
||||
}
|
||||
|
||||
Label.search(params).then(response => {
|
||||
this.results = this.dirty ? response.models : this.results.concat(response.models);
|
||||
Label.search(params).then(resp => {
|
||||
this.results = this.dirty ? resp.models : this.results.concat(resp.models);
|
||||
|
||||
this.scrollDisabled = (response.models.length < count);
|
||||
this.scrollDisabled = (resp.count < resp.limit);
|
||||
|
||||
if (this.scrollDisabled) {
|
||||
this.offset = offset;
|
||||
this.setOffset(resp.offset);
|
||||
if (this.results.length > 1) {
|
||||
this.$notify.info(this.$gettextInterpolate(this.$gettext("All %{n} labels loaded"), {n: this.results.length}));
|
||||
}
|
||||
} else {
|
||||
this.offset = offset + count;
|
||||
this.setOffset(resp.offset + resp.limit);
|
||||
this.page++;
|
||||
|
||||
this.$nextTick(() => {
|
||||
|
@ -383,7 +396,7 @@ export default {
|
|||
},
|
||||
searchParams() {
|
||||
const params = {
|
||||
count: this.batchSize,
|
||||
count: this.searchCount(),
|
||||
offset: this.offset,
|
||||
};
|
||||
|
||||
|
@ -421,12 +434,11 @@ export default {
|
|||
|
||||
const params = this.searchParams();
|
||||
|
||||
Label.search(params).then(response => {
|
||||
this.offset = this.batchSize;
|
||||
Label.search(params).then(resp => {
|
||||
this.offset = resp.limit;
|
||||
this.results = resp.models;
|
||||
|
||||
this.results = response.models;
|
||||
|
||||
this.scrollDisabled = (response.models.length < this.batchSize);
|
||||
this.scrollDisabled = (resp.count < resp.limit);
|
||||
|
||||
if (this.scrollDisabled) {
|
||||
this.$notify.info(this.$gettextInterpolate(this.$gettext("%{n} labels found"), {n: this.results.length}));
|
||||
|
|
|
@ -110,6 +110,19 @@ const router = new Router({
|
|||
routes: Routes,
|
||||
mode: "history",
|
||||
saveScrollPosition: true,
|
||||
scrollBehavior: (to, from, savedPosition) => {
|
||||
if (savedPosition) {
|
||||
return new Promise((resolve) => {
|
||||
Notify.ajaxWait().then(() => {
|
||||
setTimeout(() => {
|
||||
resolve(savedPosition);
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return { x: 0, y: 0 };
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
|
|
|
@ -195,6 +195,19 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
searchCount() {
|
||||
const offset = parseInt(window.localStorage.getItem("share_albums_offset"));
|
||||
|
||||
if(this.offset > 0 || !offset) {
|
||||
return this.batchSize;
|
||||
}
|
||||
|
||||
return offset + this.batchSize;
|
||||
},
|
||||
setOffset(offset) {
|
||||
this.offset = offset;
|
||||
window.localStorage.setItem("share_albums_offset", offset);
|
||||
},
|
||||
showUpload() {
|
||||
Event.publish("dialog.upload");
|
||||
},
|
||||
|
@ -282,19 +295,19 @@ export default {
|
|||
Object.assign(params, this.staticFilter);
|
||||
}
|
||||
|
||||
Album.search(params).then(response => {
|
||||
this.results = this.dirty ? response.models : this.results.concat(response.models);
|
||||
Album.search(params).then(resp => {
|
||||
this.results = this.dirty ? resp.models : this.results.concat(resp.models);
|
||||
|
||||
this.scrollDisabled = (response.models.length < count);
|
||||
this.scrollDisabled = (resp.count < resp.limit);
|
||||
|
||||
if (this.scrollDisabled) {
|
||||
this.offset = offset;
|
||||
this.setOffset(resp.offset);
|
||||
|
||||
if (this.results.length > 1) {
|
||||
this.$notify.info(this.$gettextInterpolate(this.$gettext("All %{n} albums loaded"), {n: this.results.length}));
|
||||
}
|
||||
} else {
|
||||
this.offset = offset + count;
|
||||
this.setOffset(resp.offset + resp.limit);
|
||||
this.page++;
|
||||
|
||||
this.$nextTick(() => {
|
||||
|
@ -334,7 +347,7 @@ export default {
|
|||
},
|
||||
searchParams() {
|
||||
const params = {
|
||||
count: this.batchSize,
|
||||
count: this.searchCount(),
|
||||
offset: this.offset,
|
||||
};
|
||||
|
||||
|
@ -364,12 +377,11 @@ export default {
|
|||
|
||||
const params = this.searchParams();
|
||||
|
||||
Album.search(params).then(response => {
|
||||
this.offset = this.batchSize;
|
||||
Album.search(params).then(resp => {
|
||||
this.offset = resp.limit;
|
||||
this.results = resp.models;
|
||||
|
||||
this.results = response.models;
|
||||
|
||||
this.scrollDisabled = (response.models.length < this.batchSize);
|
||||
this.scrollDisabled = (resp.count < resp.limit);
|
||||
|
||||
if (this.scrollDisabled) {
|
||||
if (!this.results.length) {
|
||||
|
|
Loading…
Reference in a new issue