diff options
-rw-r--r-- | .github/workflows/lint.yml | 4 | ||||
-rw-r--r-- | .github/workflows/package.yml | 11 | ||||
-rw-r--r-- | .github/workflows/test.yml | 2 | ||||
-rw-r--r-- | package-lock.json | 25 | ||||
-rw-r--r-- | package.json | 3 | ||||
-rw-r--r-- | src/components/MailboxThread.vue | 2 | ||||
-rw-r--r-- | src/directives/infinite-scroll.js | 221 |
7 files changed, 241 insertions, 27 deletions
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 29625291a..f173e9fa7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -56,9 +56,9 @@ jobs: steps: - uses: actions/checkout@master - name: Set up Node - uses: actions/setup-node@v2.1.5 + uses: actions/setup-node@v2.2.0 with: - node-version: 12.x + node-version: 14.x - name: npm install run: npm ci - name: eslint diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 62b2b6e66..a89d11098 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -1,6 +1,11 @@ name: Packaging -on: [push, pull_request] +on: + pull_request: + push: + branches: + - master + - stable* jobs: release-tarball: @@ -10,9 +15,9 @@ jobs: - name: Checkout uses: actions/checkout@master - name: Set up Node - uses: actions/setup-node@v2.1.5 + uses: actions/setup-node@v2.2.0 with: - node-version: 12.x + node-version: 14.x - name: Set up php$ uses: shivammathur/setup-php@master with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7524dc6e8..017a91b51 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -150,7 +150,7 @@ jobs: steps: - uses: actions/checkout@master - name: Set up Node - uses: actions/setup-node@v2.1.5 + uses: actions/setup-node@v2.2.0 with: node-version: 12.x - name: npm install diff --git a/package-lock.json b/package-lock.json index f07356e19..671d7e009 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,10 +57,9 @@ "vue": "^2.6.14", "vue-autosize": "^1.0.2", "vue-click-outside": "^1.1.0", - "vue-infinite-scroll": "^2.0.2", "vue-material-design-icons": "^4.12.1", "vue-on-click-outside": "^1.0.3", - "vue-router": "^3.5.1", + "vue-router": "^3.5.2", "vue-scroll": "^2.1.13", "vue-shortkey": "^3.1.7", "vue-slide-up-down": "^2.0.1", @@ -19571,11 +19570,6 @@ "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", "dev": true }, - "node_modules/vue-infinite-scroll": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vue-infinite-scroll/-/vue-infinite-scroll-2.0.2.tgz", - "integrity": "sha512-n+YghR059YmciANGJh9SsNWRi1YZEBVlODtmnb/12zI+4R72QZSWd+EuZ5mW6auEo/yaJXgxzwsuhvALVnm73A==" - }, "node_modules/vue-loader": { "version": "15.9.7", "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.7.tgz", @@ -19632,9 +19626,9 @@ } }, "node_modules/vue-router": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.1.tgz", - "integrity": "sha512-RRQNLT8Mzr8z7eL4p7BtKvRaTSGdCbTy2+Mm5HTJvLGYSSeG9gDzNasJPP/yOYKLy+/cLG/ftrqq5fvkFwBJEw==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.2.tgz", + "integrity": "sha512-807gn82hTnjCYGrnF3eNmIw/dk7/GE4B5h69BlyCK9KHASwSloD1Sjcn06zg9fVG4fYH2DrsNBZkpLtb25WtaQ==" }, "node_modules/vue-scroll": { "version": "2.1.13", @@ -38101,11 +38095,6 @@ "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", "dev": true }, - "vue-infinite-scroll": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vue-infinite-scroll/-/vue-infinite-scroll-2.0.2.tgz", - "integrity": "sha512-n+YghR059YmciANGJh9SsNWRi1YZEBVlODtmnb/12zI+4R72QZSWd+EuZ5mW6auEo/yaJXgxzwsuhvALVnm73A==" - }, "vue-loader": { "version": "15.9.7", "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.7.tgz", @@ -38143,9 +38132,9 @@ } }, "vue-router": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.1.tgz", - "integrity": "sha512-RRQNLT8Mzr8z7eL4p7BtKvRaTSGdCbTy2+Mm5HTJvLGYSSeG9gDzNasJPP/yOYKLy+/cLG/ftrqq5fvkFwBJEw==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.2.tgz", + "integrity": "sha512-807gn82hTnjCYGrnF3eNmIw/dk7/GE4B5h69BlyCK9KHASwSloD1Sjcn06zg9fVG4fYH2DrsNBZkpLtb25WtaQ==" }, "vue-scroll": { "version": "2.1.13", diff --git a/package.json b/package.json index 84517da46..60fdb997f 100644 --- a/package.json +++ b/package.json @@ -63,10 +63,9 @@ "vue": "^2.6.14", "vue-autosize": "^1.0.2", "vue-click-outside": "^1.1.0", - "vue-infinite-scroll": "^2.0.2", "vue-material-design-icons": "^4.12.1", "vue-on-click-outside": "^1.0.3", - "vue-router": "^3.5.1", + "vue-router": "^3.5.2", "vue-scroll": "^2.1.13", "vue-shortkey": "^3.1.7", "vue-slide-up-down": "^2.0.1", diff --git a/src/components/MailboxThread.vue b/src/components/MailboxThread.vue index 88efeb2ec..181c96014 100644 --- a/src/components/MailboxThread.vue +++ b/src/components/MailboxThread.vue @@ -69,11 +69,11 @@ import AppContent from '@nextcloud/vue/dist/Components/AppContent' import AppContentList from '@nextcloud/vue/dist/Components/AppContentList' import Popover from '@nextcloud/vue/dist/Components/Popover' -import infiniteScroll from 'vue-infinite-scroll' import isMobile from '@nextcloud/vue/dist/Mixins/isMobile' import SectionTitle from './SectionTitle' import Vue from 'vue' +import infiniteScroll from '../directives/infinite-scroll' import logger from '../logger' import Mailbox from './Mailbox' import NewMessageDetail from './NewMessageDetail' diff --git a/src/directives/infinite-scroll.js b/src/directives/infinite-scroll.js new file mode 100644 index 000000000..b4eb91357 --- /dev/null +++ b/src/directives/infinite-scroll.js @@ -0,0 +1,221 @@ +/* eslint-disable */ + +/** + * Vendored and fixed version of the abandoned https://github.com/ElemeFE/vue-infinite-scroll lib + */ + +const ctx = '@@InfiniteScroll'; + +var throttle = function (fn, delay) { + var now, lastExec, timer, context, args; //eslint-disable-line + + var execute = function () { + fn.apply(context, args); + lastExec = now; + }; + + return function () { + context = this; + args = arguments; + + now = Date.now(); + + if (timer) { + clearTimeout(timer); + timer = null; + } + + if (lastExec) { + var diff = delay - (now - lastExec); + if (diff < 0) { + execute(); + } else { + timer = setTimeout(() => { + execute(); + }, diff); + } + } else { + execute(); + } + }; +}; + +var getScrollTop = function (element) { + if (element === window) { + return Math.max(window.pageYOffset || 0, document.documentElement.scrollTop); + } + + return element.scrollTop; +}; + +var getComputedStyle = document.defaultView.getComputedStyle; + +var getScrollEventTarget = function (element) { + var currentNode = element; + // bugfix, see http://w3help.org/zh-cn/causes/SD9013 and http://stackoverflow.com/questions/17016740/onscroll-function-is-not-working-for-chrome + while (currentNode && currentNode.tagName !== 'HTML' && currentNode.tagName !== 'BODY' && currentNode.nodeType === 1) { + var overflowY = getComputedStyle(currentNode).overflowY; + if (overflowY === 'scroll' || overflowY === 'auto') { + return currentNode; + } + currentNode = currentNode.parentNode; + } + return window; +}; + +var getVisibleHeight = function (element) { + if (element === window) { + return document.documentElement.clientHeight; + } + + return element.clientHeight; +}; + +var getElementTop = function (element) { + if (element === window) { + return getScrollTop(window); + } + return element.getBoundingClientRect().top + getScrollTop(window); +}; + +var isAttached = function (element) { + var currentNode = element.parentNode; + while (currentNode) { + if (currentNode.tagName === 'HTML') { + return true; + } + if (currentNode.nodeType === 11) { + return false; + } + currentNode = currentNode.parentNode; + } + return false; +}; + +var doBind = function () { + if (this.binded) return; // eslint-disable-line + this.binded = true; + + var directive = this; + var element = directive.el; + + var throttleDelayExpr = element.getAttribute('infinite-scroll-throttle-delay'); + var throttleDelay = 200; + if (throttleDelayExpr) { + throttleDelay = Number(directive.vm[throttleDelayExpr] || throttleDelayExpr); + if (isNaN(throttleDelay) || throttleDelay < 0) { + throttleDelay = 200; + } + } + directive.throttleDelay = throttleDelay; + + directive.scrollEventTarget = getScrollEventTarget(element); + directive.scrollListener = throttle(doCheck.bind(directive), directive.throttleDelay); + directive.scrollEventTarget.addEventListener('scroll', directive.scrollListener); + + this.vm.$on('hook:beforeDestroy', function () { + directive.scrollEventTarget.removeEventListener('scroll', directive.scrollListener); + }); + + var disabledExpr = element.getAttribute('infinite-scroll-disabled'); + var disabled = false; + + if (disabledExpr) { + this.vm.$watch(disabledExpr, function(value) { + directive.disabled = value; + if (!value && directive.immediateCheck) { + doCheck.call(directive); + } + }); + disabled = Boolean(directive.vm[disabledExpr]); + } + directive.disabled = disabled; + + var distanceExpr = element.getAttribute('infinite-scroll-distance'); + var distance = 0; + if (distanceExpr) { + distance = Number(directive.vm[distanceExpr] || distanceExpr); + if (isNaN(distance)) { + distance = 0; + } + } + directive.distance = distance; + + var immediateCheckExpr = element.getAttribute('infinite-scroll-immediate-check'); + var immediateCheck = true; + if (immediateCheckExpr) { + immediateCheck = Boolean(directive.vm[immediateCheckExpr]); + } + directive.immediateCheck = immediateCheck; + + if (immediateCheck) { + doCheck.call(directive); + } + + var eventName = element.getAttribute('infinite-scroll-listen-for-event'); + if (eventName) { + directive.vm.$on(eventName, function() { + doCheck.call(directive); + }); + } +}; + +var doCheck = function (force) { + var scrollEventTarget = this.scrollEventTarget; + var element = this.el; + var distance = this.distance; + + if (force !== true && this.disabled) return; //eslint-disable-line + var viewportScrollTop = getScrollTop(scrollEventTarget); + var viewportBottom = viewportScrollTop + getVisibleHeight(scrollEventTarget); + + var shouldTrigger = false; + + if (scrollEventTarget === element) { + shouldTrigger = scrollEventTarget.scrollHeight - viewportBottom <= distance; + } else { + var elementBottom = getElementTop(element) - getElementTop(scrollEventTarget) + element.offsetHeight + viewportScrollTop; + + shouldTrigger = viewportBottom + distance >= elementBottom; + } + + if (shouldTrigger && this.expression) { + this.expression(); + } +}; + +export default { + bind(el, binding, vnode) { + el[ctx] = { + el, + vm: vnode.context, + expression: binding.value + }; + const args = arguments; + console.info('binding', el, binding, vnode) + el[ctx].vm.$nextTick(function () { + if (isAttached(el)) { + doBind.call(el[ctx], args); + } + + el[ctx].bindTryCount = 0; + + var tryBind = function () { + if (el[ctx].bindTryCount > 10) return; //eslint-disable-line + el[ctx].bindTryCount++; + if (isAttached(el)) { + doBind.call(el[ctx], args); + } else { + setTimeout(tryBind, 50); + } + }; + + tryBind(); + }); + }, + + unbind(el) { + if (el && el[ctx] && el[ctx].scrollEventTarget) + el[ctx].scrollEventTarget.removeEventListener('scroll', el[ctx].scrollListener); + } +}; |