aboutsummaryrefslogtreecommitdiff
path: root/client/js/views/endless_page_view.js
diff options
context:
space:
mode:
authorrr-2016-05-09 11:17:04 +0200
committerrr-2016-05-09 11:17:26 +0200
commit29b0fde9a794b836c16671b238d3c26c083105dd (patch)
tree9570cf88f2ff55cd9f36a30c9c543aa583814644 /client/js/views/endless_page_view.js
parentf39e58b1bcc8a7f8460aa15620df5b228fc69e82 (diff)
client/paging: improve endless paging
- Change page number indicator - Remove most of the scrolling cruft as it has no chance of working anyway, thanks to our benevolent browsers - Scroll to page header if the page is not the first one (I'm surprised this even works) - Use promises rather than timers - Simplify top page detection using .elementFromPoint rather than iterating over all pages. Coincidentally, this seems to work slightly better
Diffstat (limited to 'client/js/views/endless_page_view.js')
-rw-r--r--client/js/views/endless_page_view.js113
1 files changed, 58 insertions, 55 deletions
diff --git a/client/js/views/endless_page_view.js b/client/js/views/endless_page_view.js
index 2b00fe8..17282f0 100644
--- a/client/js/views/endless_page_view.js
+++ b/client/js/views/endless_page_view.js
@@ -18,6 +18,7 @@ class EndlessPageView {
views.listenToMessages(target);
views.showView(target, source);
this.active = true;
+ this.working = 0;
let headerRendererCtx = ctx;
headerRendererCtx.target = pageHeaderHolder;
@@ -25,47 +26,39 @@ class EndlessPageView {
const threshold = window.innerHeight / 3;
- if (ctx.state && ctx.state.html) {
- this.minPageShown = ctx.state.minPageShown;
- this.maxPageShown = ctx.state.maxPageShown;
- this.totalPages = ctx.state.totalPages;
- this.currentPage = ctx.state.currentPage;
- } else {
- this.minPageShown = null;
- this.maxPageShown = null;
- this.totalPages = null;
- this.currentPage = null;
- }
- this.fetching = false;
+ this.minPageShown = null;
+ this.maxPageShown = null;
+ this.totalPages = null;
+ this.currentPage = null;
this.updater = () => {
- let topPage = null;
- let allPageNodes =
- pagesHolder.querySelectorAll('.page');
- for (let pageNode of allPageNodes) {
- if (pageNode.getBoundingClientRect().bottom >= 0) {
- topPage = parseInt(pageNode.getAttribute('data-page'));
+ if (this.working) {
+ return;
+ }
+
+ let topPageNode = null;
+ var element = document.elementFromPoint(window.innerWidth / 2, 1);
+ while (element.parentNode !== null) {
+ if (element.classList.contains('page')) {
+ topPageNode = element;
break;
}
+ element = element.parentNode;
+ }
+ if (!topPageNode) {
+ return;
}
- if (topPage !== this.currentPage) {
+ let topPageNumber = parseInt(topPageNode.getAttribute('data-page'));
+ if (topPageNumber !== this.currentPage) {
page.replace(
- ctx.clientUrl.format({page: topPage}),
- {
- minPageShown: this.minPageShown,
- maxPageShown: this.maxPageShown,
- totalPages: this.totalPages,
- currentPage: this.currentPage,
- html: pagesHolder.innerHTML,
- scrollX: window.scrollX,
- scrollY: window.scrollY,
- },
+ ctx.clientUrl.format({page: topPageNumber}),
+ null,
false,
false);
- this.currentPage = topPage;
+ this.currentPage = topPageNumber;
}
- if (this.fetching || this.totalPages === null) {
+ if (this.totalPages === null) {
return;
}
let scrollHeight =
@@ -73,41 +66,42 @@ class EndlessPageView {
document.documentElement.clientHeight;
if (this.minPageShown > 1 && window.scrollY - threshold < 0) {
- this.loadPage(pagesHolder, ctx, this.minPageShown - 1, false);
+ this.loadPage(pagesHolder, ctx, this.minPageShown - 1, false)
+ .then(() => this.updater());
} else if (this.maxPageShown < this.totalPages &&
window.scrollY + threshold > scrollHeight) {
- this.loadPage(pagesHolder, ctx, this.maxPageShown + 1, true);
+ this.loadPage(pagesHolder, ctx, this.maxPageShown + 1, true)
+ .then(() => this.updater());
}
};
- if (ctx.state && ctx.state.html) {
- pagesHolder.innerHTML = ctx.state.html;
- window.scroll(ctx.state.scrollX, ctx.state.scrollY);
- this.updater();
- } else {
- this.loadPage(pagesHolder, ctx, ctx.searchQuery.page, true);
- }
+ this.loadPage(pagesHolder, ctx, ctx.searchQuery.page, true)
+ .then(pageNode => {
+ if (ctx.searchQuery.page > 1) {
+ window.scroll(0, pageNode.getBoundingClientRect().top);
+ }
+ this.updater();
+ });
window.addEventListener('scroll', this.updater, true);
+ window.addEventListener('unload', this.scrollToTop, true);
}
unrender() {
this.active = false;
window.removeEventListener('scroll', this.updater, true);
+ window.removeEventListener('unload', this.scrollToTop, true);
}
- loadPage(pagesHolder, ctx, pageNumber, append) {
- this.fetching = true;
-
- if (pageNumber < this.minPageShown || this.minPageShown === null) {
- this.minPageShown = pageNumber;
- }
- if (pageNumber > this.maxPageShown || this.maxPageShown === null) {
- this.maxPageShown = pageNumber;
- }
+ scrollToTop() {
+ window.scroll(0, 0);
+ }
- ctx.requestPage(pageNumber).then(response => {
+ loadPage(pagesHolder, ctx, pageNumber, append) {
+ this.working++;
+ return ctx.requestPage(pageNumber).then(response => {
if (!this.active) {
- return;
+ this.working--;
+ return Promise.reject();
}
this.totalPages = Math.ceil(response.total / response.pageSize);
if (response.total) {
@@ -122,6 +116,13 @@ class EndlessPageView {
'.page-content-holder');
ctx.pageRenderer.render(pageRendererCtx);
+ if (pageNumber < this.minPageShown || this.minPageShown === null) {
+ this.minPageShown = pageNumber;
+ }
+ if (pageNumber > this.maxPageShown || this.maxPageShown === null) {
+ this.maxPageShown = pageNumber;
+ }
+
if (append) {
pagesHolder.appendChild(pageNode);
} else {
@@ -134,16 +135,18 @@ class EndlessPageView {
window.scrollX,
window.scrollY + pageNode.offsetHeight);
}
+ this.working--;
+ return Promise.resolve(pageNode);
}
-
- this.fetching = false;
- window.setTimeout(() => { this.updater(); }, 10);
-
if (response.total <= (pageNumber - 1) * response.pageSize) {
events.notify(events.Info, 'No data to show');
}
+ this.working--;
+ return Promise.reject();
}, response => {
events.notify(events.Error, response.description);
+ this.working--;
+ return Promise.reject();
});
}
}

© 2015 - 2026 Jakob L. Kreuze