summaryrefslogtreecommitdiffstats
path: root/client/components/lists/listBody.js
diff options
context:
space:
mode:
authorLauri Ojansivu <x@xet7.org>2019-02-01 16:54:41 +0200
committerLauri Ojansivu <x@xet7.org>2019-02-01 16:54:41 +0200
commitd08bee68171a42374d121201d2e4f21d3f650a70 (patch)
tree0db20b2fb43b1367a7d0d0f62ccb6d5f29774ea5 /client/components/lists/listBody.js
parent1b11123797a8da92e478ea257cd24ebadf084a24 (diff)
parent4fc96904d6f6f372ebc0b7b409cb8366cc181d0c (diff)
downloadwekan-d08bee68171a42374d121201d2e4f21d3f650a70.tar.gz
wekan-d08bee68171a42374d121201d2e4f21d3f650a70.tar.bz2
wekan-d08bee68171a42374d121201d2e4f21d3f650a70.zip
Merge branch 'bentiss-infinite-scrolling' into edge
Diffstat (limited to 'client/components/lists/listBody.js')
-rw-r--r--client/components/lists/listBody.js81
1 files changed, 81 insertions, 0 deletions
diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js
index 1001f3bc..fdea3bae 100644
--- a/client/components/lists/listBody.js
+++ b/client/components/lists/listBody.js
@@ -1,6 +1,34 @@
const subManager = new SubsManager();
+const InfiniteScrollIter = 10;
BlazeComponent.extendComponent({
+ onCreated() {
+ // for infinite scrolling
+ this.cardlimit = new ReactiveVar(InfiniteScrollIter);
+ },
+
+ onRendered() {
+ const domElement = this.find('.js-perfect-scrollbar');
+
+ this.$(domElement).on('scroll', () => this.updateList(domElement));
+ $(window).on(`resize.${this.data().listId}`, () => this.updateList(domElement));
+
+ // we add a Mutation Observer to allow propagations of cardlimit
+ // when the spinner stays in the current view (infinite scrolling)
+ this.mutationObserver = new MutationObserver(() => this.updateList(domElement));
+
+ this.mutationObserver.observe(domElement, {
+ childList: true,
+ });
+
+ this.updateList(domElement);
+ },
+
+ onDestroyed() {
+ $(window).off(`resize.${this.data().listId}`);
+ this.mutationObserver.disconnect();
+ },
+
mixins() {
return [Mixins.PerfectScrollbar];
},
@@ -60,6 +88,13 @@ BlazeComponent.extendComponent({
type: 'cardType-card',
});
+ // if the displayed card count is less than the total cards in the list,
+ // we need to increment the displayed card count to prevent the spinner
+ // to appear
+ const cardCount = this.data().cards(this.idOrNull(swimlaneId)).count();
+ if (this.cardlimit.get() < cardCount) {
+ this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter);
+ }
// In case the filter is active we need to add the newly inserted card in
// the list of exceptions -- cards that are not filtered. Otherwise the
@@ -119,6 +154,52 @@ BlazeComponent.extendComponent({
return undefined;
},
+ cardsWithLimit(swimlaneId) {
+ const limit = this.cardlimit.get();
+ const selector = {
+ listId: this.currentData()._id,
+ archived: false,
+ };
+ if (swimlaneId)
+ selector.swimlaneId = swimlaneId;
+ return Cards.find(Filter.mongoSelector(selector), {
+ sort: ['sort'],
+ limit,
+ });
+ },
+
+ spinnerInView(container) {
+ const parentViewHeight = container.clientHeight;
+ const bottomViewPosition = container.scrollTop + parentViewHeight;
+
+ const spinner = this.find('.sk-spinner-list');
+
+ const threshold = spinner.offsetTop;
+
+ return bottomViewPosition > threshold;
+ },
+
+ showSpinner(swimlaneId) {
+ const list = Template.currentData();
+ return list.cards(swimlaneId).count() > this.cardlimit.get();
+ },
+
+ updateList(container) {
+ // first, if the spinner is not rendered, we have reached the end of
+ // the list of cards, so skip and disable firing the events
+ const target = this.find('.sk-spinner-list');
+ if (!target) {
+ this.$(container).off('scroll');
+ $(window).off(`resize.${this.data().listId}`);
+ return;
+ }
+
+ if (this.spinnerInView(container)) {
+ this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter);
+ Ps.update(container);
+ }
+ },
+
canSeeAddCard() {
return !this.reachedWipLimit() && Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
},