diff options
author | Lauri Ojansivu <x@xet7.org> | 2019-02-01 16:54:41 +0200 |
---|---|---|
committer | Lauri Ojansivu <x@xet7.org> | 2019-02-01 16:54:41 +0200 |
commit | d08bee68171a42374d121201d2e4f21d3f650a70 (patch) | |
tree | 0db20b2fb43b1367a7d0d0f62ccb6d5f29774ea5 | |
parent | 1b11123797a8da92e478ea257cd24ebadf084a24 (diff) | |
parent | 4fc96904d6f6f372ebc0b7b409cb8366cc181d0c (diff) | |
download | wekan-d08bee68171a42374d121201d2e4f21d3f650a70.tar.gz wekan-d08bee68171a42374d121201d2e4f21d3f650a70.tar.bz2 wekan-d08bee68171a42374d121201d2e4f21d3f650a70.zip |
Merge branch 'bentiss-infinite-scrolling' into edge
-rw-r--r-- | client/components/lists/list.styl | 3 | ||||
-rw-r--r-- | client/components/lists/listBody.jade | 12 | ||||
-rw-r--r-- | client/components/lists/listBody.js | 81 |
3 files changed, 95 insertions, 1 deletions
diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl index 51ade73c..70502083 100644 --- a/client/components/lists/list.styl +++ b/client/components/lists/list.styl @@ -211,6 +211,9 @@ max-height: 250px overflow: hidden +.sk-spinner-list + margin-top: unset !important + list-header-color(background, color...) border-bottom: 6px solid background diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index c6c9b204..f030833b 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -4,7 +4,7 @@ template(name="listBody") if cards.count +inlinedForm(autoclose=false position="top") +addCardForm(listId=_id position="top") - each (cards (idOrNull ../../_id)) + each (cardsWithLimit (idOrNull ../../_id)) a.minicard-wrapper.js-minicard(href=absoluteUrl class="{{#if cardIsSelected}}is-selected{{/if}}" class="{{#if MultiSelection.isSelected _id}}is-checked{{/if}}") @@ -12,6 +12,16 @@ template(name="listBody") .materialCheckBox.multi-selection-checkbox.js-toggle-multi-selection( class="{{#if MultiSelection.isSelected _id}}is-checked{{/if}}") +minicard(this) + if (showSpinner (idOrNull ../../_id)) + .sk-spinner.sk-spinner-wave.sk-spinner-list( + class=currentBoard.colorClass + id="showMoreResults") + .sk-rect1 + .sk-rect2 + .sk-rect3 + .sk-rect4 + .sk-rect5 + if canSeeAddCard +inlinedForm(autoclose=false position="bottom") +addCardForm(listId=_id position="bottom") 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(); }, |