From a6c169c2e0af63321004b0dd8df223031c2db942 Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Fri, 15 Nov 2019 14:20:09 +0100 Subject: [PATCH 1/5] Fix infinite scrolling out of control --- webapp/layouts/default.vue | 7 +---- webapp/nuxt.config.js | 2 +- webapp/package.json | 1 + webapp/pages/index.vue | 37 +++++++++++--------------- webapp/pages/profile/_id/_slug.vue | 18 ++++++------- webapp/plugins/vue-infinite-loading.js | 4 +++ webapp/plugins/vue-infinite-scroll.js | 4 --- webapp/store/posts.js | 28 ------------------- webapp/yarn.lock | 5 ++++ 9 files changed, 36 insertions(+), 70 deletions(-) create mode 100644 webapp/plugins/vue-infinite-loading.js delete mode 100644 webapp/plugins/vue-infinite-scroll.js diff --git a/webapp/layouts/default.vue b/webapp/layouts/default.vue index a39e0a148..94a9c0912 100644 --- a/webapp/layouts/default.vue +++ b/webapp/layouts/default.vue @@ -6,11 +6,7 @@ - + @@ -143,7 +139,6 @@ export default { ...mapActions({ quickSearchClear: 'search/quickClear', quickSearch: 'search/quickSearch', - refreshPosts: 'posts/refreshPosts', }), goToPost(item) { this.$nextTick(() => { diff --git a/webapp/nuxt.config.js b/webapp/nuxt.config.js index 17bb5290c..eb628c7d6 100644 --- a/webapp/nuxt.config.js +++ b/webapp/nuxt.config.js @@ -118,7 +118,7 @@ export default { { src: '~/plugins/v-tooltip.js', ssr: false }, { src: '~/plugins/izi-toast.js', ssr: false }, { src: '~/plugins/vue-filters.js' }, - { src: '~/plugins/vue-infinite-scroll.js', ssr: false }, + { src: '~/plugins/vue-infinite-loading.js', ssr: false }, ], router: { diff --git a/webapp/package.json b/webapp/package.json index 322e88817..74e4451fc 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -83,6 +83,7 @@ "v-tooltip": "~2.0.2", "validator": "^12.0.0", "vue-count-to": "~1.0.13", + "vue-infinite-loading": "^2.4.4", "vue-infinite-scroll": "^2.0.2", "vue-izitoast": "^1.2.1", "vue-scrollto": "^2.17.1", diff --git a/webapp/pages/index.vue b/webapp/pages/index.vue index caf5d54f6..da4c2bdcd 100644 --- a/webapp/pages/index.vue +++ b/webapp/pages/index.vue @@ -16,7 +16,7 @@ @@ -97,7 +92,6 @@ export default { orderBy: 'posts/orderBy', selectedOrder: 'posts/selectedOrder', sortingIcon: 'posts/orderIcon', - currentPosts: 'posts/currentPosts', }), selected: { get() { @@ -105,7 +99,7 @@ export default { }, set({ value }) { this.offset = 0 - this.setCurrentPosts([]) + this.posts = [] this.selectOrder(value) }, }, @@ -123,13 +117,12 @@ export default { return filter }, hasResults() { - return this.$apollo.loading || (this.currentPosts && this.currentPosts.length > 0) + return this.$apollo.loading || (this.posts && this.posts.length > 0) }, }, methods: { ...mapMutations({ selectOrder: 'posts/SELECT_ORDER', - setCurrentPosts: 'posts/SET_CURRENT_POSTS', }), clearSearch() { this.$router.push({ path: '/' }) @@ -141,7 +134,7 @@ export default { params: { id: post.id, slug: post.slug }, }).href }, - showMoreContributions() { + showMoreContributions($state) { const { Post: PostQuery } = this.$apollo.queries if (!PostQuery) return // seems this can be undefined on subpages @@ -156,7 +149,9 @@ export default { updateQuery: (previousResult, { fetchMoreResult }) => { if (!fetchMoreResult || fetchMoreResult.Post.length < this.pageSize) { this.hasMore = false + $state.complete() } + const result = { ...previousResult, Post: [ @@ -168,19 +163,19 @@ export default { ...fetchMoreResult.Post, ], } - this.setCurrentPosts(result.Post) + $state.loaded() + return result }, }) }, deletePost(deletedPost) { - const posts = this.currentPosts.filter(post => { + this.posts = this.posts.filter(post => { return post.id !== deletedPost.id }) - this.setCurrentPosts(posts) }, resetPostList() { this.offset = 0 - this.setCurrentPosts([]) + this.posts = [] this.hasMore = true }, pinPost(post) { @@ -224,7 +219,7 @@ export default { } }, update({ Post }) { - this.setCurrentPosts(Post) + this.posts = Post }, fetchPolicy: 'cache-and-network', }, diff --git a/webapp/pages/profile/_id/_slug.vue b/webapp/pages/profile/_id/_slug.vue index b0d6a8d11..4400fd3c7 100644 --- a/webapp/pages/profile/_id/_slug.vue +++ b/webapp/pages/profile/_id/_slug.vue @@ -255,16 +255,14 @@ -
- -
+ + + + +
diff --git a/webapp/plugins/vue-infinite-loading.js b/webapp/plugins/vue-infinite-loading.js new file mode 100644 index 000000000..e3e447a21 --- /dev/null +++ b/webapp/plugins/vue-infinite-loading.js @@ -0,0 +1,4 @@ +import Vue from 'vue' +import InfiniteLoading from 'vue-infinite-loading' + +Vue.use(InfiniteLoading, { props: { distance: 10 }, system: { throttleLimit: 800 } }) diff --git a/webapp/plugins/vue-infinite-scroll.js b/webapp/plugins/vue-infinite-scroll.js deleted file mode 100644 index 776db193b..000000000 --- a/webapp/plugins/vue-infinite-scroll.js +++ /dev/null @@ -1,4 +0,0 @@ -import Vue from 'vue' -import infiniteScroll from 'vue-infinite-scroll' - -Vue.use(infiniteScroll) diff --git a/webapp/store/posts.js b/webapp/store/posts.js index 4342c5e9e..25a48f0d5 100644 --- a/webapp/store/posts.js +++ b/webapp/store/posts.js @@ -4,8 +4,6 @@ import xor from 'lodash/xor' import isEmpty from 'lodash/isEmpty' import isEqual from 'lodash/isEqual' import clone from 'lodash/clone' -import { filterPosts } from '~/graphql/PostQuery' -import { first, offset } from '~/constants/posts' const defaultFilter = {} @@ -28,7 +26,6 @@ export const state = () => { ...defaultFilter, }, order: orderOptions['createdAt_desc'], - currentPosts: [], } } @@ -77,9 +74,6 @@ export const mutations = { SELECT_ORDER(state, value) { state.order = orderOptions[value] }, - SET_CURRENT_POSTS(state, posts) { - state.currentPosts = posts - }, } export const getters = { @@ -120,26 +114,4 @@ export const getters = { orderIcon(state) { return state.order.icon }, - currentPosts(state) { - return state.currentPosts || [] - }, -} - -export const actions = { - async refreshPosts({ commit, getters }, { i18n }) { - const client = this.app.apolloProvider.defaultClient - const { - data: { Post }, - } = await client.query({ - query: filterPosts(i18n), - variables: { - filter: getters.filter, - first, - orderBy: ['pinned_asc', getters.orderBy], - offset, - }, - }) - commit('SET_CURRENT_POSTS', Post) - return Post - }, } diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 31a6085fe..521c622ad 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -16331,6 +16331,11 @@ vue-hot-reload-api@^2.3.0: resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz#2756f46cb3258054c5f4723de8ae7e87302a1ccf" integrity sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g== +vue-infinite-loading@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vue-infinite-loading/-/vue-infinite-loading-2.4.4.tgz#8a9defb9ceeea797c057cb36bdf558a4b2ce409f" + integrity sha512-eIFBcyKqkivtsDDq7Ee5ybDJVGLxIzU1NcBJCHG7Zx9Ic66QEGzSPs2OPJlGUdtu0/RS7KpUER35ZP/a7FdSOg== + vue-infinite-scroll@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/vue-infinite-scroll/-/vue-infinite-scroll-2.0.2.tgz#ca37a91fe92ee0ad3b74acf8682c00917144b711" From a10a735e35acae2f4b009d2e3b8e13878cc971ed Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Fri, 15 Nov 2019 14:56:44 +0100 Subject: [PATCH 2/5] Tell vue-infinite-loader when complete or loaded --- webapp/pages/profile/_id/_slug.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webapp/pages/profile/_id/_slug.vue b/webapp/pages/profile/_id/_slug.vue index 4400fd3c7..d61ea40df 100644 --- a/webapp/pages/profile/_id/_slug.vue +++ b/webapp/pages/profile/_id/_slug.vue @@ -376,7 +376,7 @@ export default { uniq(items, field = 'id') { return uniqBy(items, field) }, - showMoreContributions() { + showMoreContributions($state) { const { profilePagePosts: PostQuery } = this.$apollo.queries if (!PostQuery) return // seems this can be undefined on subpages this.offset += this.pageSize @@ -391,6 +391,7 @@ export default { updateQuery: (previousResult, { fetchMoreResult }) => { if (!fetchMoreResult || fetchMoreResult.profilePagePosts.length < this.pageSize) { this.hasMore = false + $state.complete() } const result = { ...previousResult, @@ -404,6 +405,7 @@ export default { ...fetchMoreResult.profilePagePosts, ], } + $state.loaded() return result }, }) From f8c5290be01658a97fa21d81c535f8f0f29feb0e Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Fri, 15 Nov 2019 15:23:16 +0100 Subject: [PATCH 3/5] Clean up following @roschaefer PR review suggestions --- webapp/package.json | 1 - webapp/pages/index.spec.js | 4 ++-- webapp/pages/profile/_id/_slug.spec.js | 4 ++-- webapp/yarn.lock | 5 ----- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 74e4451fc..e47fbef00 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -84,7 +84,6 @@ "validator": "^12.0.0", "vue-count-to": "~1.0.13", "vue-infinite-loading": "^2.4.4", - "vue-infinite-scroll": "^2.0.2", "vue-izitoast": "^1.2.1", "vue-scrollto": "^2.17.1", "vue-sweetalert-icons": "~4.2.0", diff --git a/webapp/pages/index.spec.js b/webapp/pages/index.spec.js index 0cee06b38..68c4e3314 100644 --- a/webapp/pages/index.spec.js +++ b/webapp/pages/index.spec.js @@ -5,7 +5,7 @@ import Styleguide from '@human-connection/styleguide' import Filters from '~/plugins/vue-filters' import VTooltip from 'v-tooltip' import FilterMenu from '~/components/FilterMenu/FilterMenu' -import InfiniteScroll from '~/plugins/vue-infinite-scroll' +import InfiniteLoading from '~/plugins/vue-infinite-loading' const localVue = createLocalVue() @@ -13,7 +13,7 @@ localVue.use(Vuex) localVue.use(Styleguide) localVue.use(Filters) localVue.use(VTooltip) -localVue.use(InfiniteScroll) +localVue.use(InfiniteLoading) config.stubs['client-only'] = '' config.stubs['router-link'] = '' diff --git a/webapp/pages/profile/_id/_slug.spec.js b/webapp/pages/profile/_id/_slug.spec.js index f7eba10cc..fbf94d300 100644 --- a/webapp/pages/profile/_id/_slug.spec.js +++ b/webapp/pages/profile/_id/_slug.spec.js @@ -3,14 +3,14 @@ import ProfileSlug from './_slug.vue' import Vuex from 'vuex' import Styleguide from '@human-connection/styleguide' import Filters from '~/plugins/vue-filters' -import InfiniteScroll from '~/plugins/vue-infinite-scroll' +import InfiniteLoading from '~/plugins/vue-infinite-loading' const localVue = createLocalVue() localVue.use(Vuex) localVue.use(Styleguide) localVue.use(Filters) -localVue.use(InfiniteScroll) +localVue.use(InfiniteLoading) localVue.filter('date', d => d) config.stubs['client-only'] = '' diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 521c622ad..cce1568db 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -16336,11 +16336,6 @@ vue-infinite-loading@^2.4.4: resolved "https://registry.yarnpkg.com/vue-infinite-loading/-/vue-infinite-loading-2.4.4.tgz#8a9defb9ceeea797c057cb36bdf558a4b2ce409f" integrity sha512-eIFBcyKqkivtsDDq7Ee5ybDJVGLxIzU1NcBJCHG7Zx9Ic66QEGzSPs2OPJlGUdtu0/RS7KpUER35ZP/a7FdSOg== -vue-infinite-scroll@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/vue-infinite-scroll/-/vue-infinite-scroll-2.0.2.tgz#ca37a91fe92ee0ad3b74acf8682c00917144b711" - integrity sha512-n+YghR059YmciANGJh9SsNWRi1YZEBVlODtmnb/12zI+4R72QZSWd+EuZ5mW6auEo/yaJXgxzwsuhvALVnm73A== - vue-izitoast@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/vue-izitoast/-/vue-izitoast-1.2.1.tgz#cd2cbfbd96ea438dede8fb00f2c328364cb7141d" From 3fa7eeb038c1eb7acddb5a475f2cd883676e562e Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 15 Nov 2019 15:36:37 +0100 Subject: [PATCH 4/5] @mattwr18 looks like you forgot $state --- webapp/pages/profile/_id/_slug.vue | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/webapp/pages/profile/_id/_slug.vue b/webapp/pages/profile/_id/_slug.vue index d61ea40df..e0436753d 100644 --- a/webapp/pages/profile/_id/_slug.vue +++ b/webapp/pages/profile/_id/_slug.vue @@ -256,10 +256,7 @@ - + From 950df1cd0723b7faaaab5c4ec6141731034ffb43 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Fri, 15 Nov 2019 15:45:05 +0100 Subject: [PATCH 5/5] Fix frontend tests I also removed one frontend test. The test case was checking an edge case. We use `hasMore` as the single source of truth so I think it's safe to remove this test case. --- webapp/pages/index.spec.js | 3 +-- webapp/pages/profile/_id/_slug.spec.js | 18 +----------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/webapp/pages/index.spec.js b/webapp/pages/index.spec.js index 68c4e3314..73e88d972 100644 --- a/webapp/pages/index.spec.js +++ b/webapp/pages/index.spec.js @@ -18,6 +18,7 @@ localVue.use(InfiniteLoading) config.stubs['client-only'] = '' config.stubs['router-link'] = '' config.stubs['nuxt-link'] = '' +config.stubs['infinite-loading'] = '' describe('PostIndex', () => { let wrapper @@ -29,7 +30,6 @@ describe('PostIndex', () => { beforeEach(() => { mutations = { 'posts/SELECT_ORDER': jest.fn(), - 'posts/SET_CURRENT_POSTS': jest.fn(), } store = new Vuex.Store({ getters: { @@ -54,7 +54,6 @@ describe('PostIndex', () => { 'auth/user': () => { return { id: 'u23' } }, - 'posts/currentPosts': () => [], }, mutations, }) diff --git a/webapp/pages/profile/_id/_slug.spec.js b/webapp/pages/profile/_id/_slug.spec.js index fbf94d300..4dfbbd3e0 100644 --- a/webapp/pages/profile/_id/_slug.spec.js +++ b/webapp/pages/profile/_id/_slug.spec.js @@ -16,6 +16,7 @@ localVue.filter('date', d => d) config.stubs['client-only'] = '' config.stubs['v-popover'] = '' config.stubs['nuxt-link'] = '' +config.stubs['infinite-loading'] = '' describe('ProfileSlug', () => { let wrapper @@ -127,23 +128,6 @@ describe('ProfileSlug', () => { }) }) - describe('pagination returned less posts than available', () => { - beforeEach(() => { - const posts = [1, 2, 3, 4, 5].map(id => { - return { - ...aPost, - id, - } - }) - - wrapper.setData({ posts, hasMore: true }) - }) - - it('does not display a "load more" button', () => { - expect(wrapper.find('.load-more').exists()).toBe(false) - }) - }) - describe('pagination returned at least as many posts as pageSize', () => { beforeEach(() => { const posts = [1, 2, 3, 4, 5, 6].map(id => {