From 3a689ef8eead0503b90d3c9dec3b15fa0ace8eb6 Mon Sep 17 00:00:00 2001 From: taehoon Date: Mon, 25 Feb 2019 02:10:59 -0500 Subject: Allow HOCs to accept additional props --- src/hocs/with_load_more/with_load_more.js | 5 +++-- src/hocs/with_subscription/with_subscription.js | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/hocs') diff --git a/src/hocs/with_load_more/with_load_more.js b/src/hocs/with_load_more/with_load_more.js index e862a39b..a521014c 100644 --- a/src/hocs/with_load_more/with_load_more.js +++ b/src/hocs/with_load_more/with_load_more.js @@ -6,10 +6,11 @@ import './with_load_more.scss' const withLoadMore = ({ fetch, // function to fetch entries and return a promise select, // function to select data from store - childPropName = 'entries' // name of the prop to be passed into the wrapped component + childPropName = 'entries', // name of the prop to be passed into the wrapped component + additionalPropNames = [] // additional prop name list of the wrapper component }) => (WrappedComponent) => { const originalProps = WrappedComponent.props || [] - const props = filter(originalProps, v => v !== 'entries') + const props = filter(originalProps, v => v !== childPropName).concat(additionalPropNames) return Vue.component('withLoadMore', { render (createElement) { diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.js index 1ac67cba..b6bc8358 100644 --- a/src/hocs/with_subscription/with_subscription.js +++ b/src/hocs/with_subscription/with_subscription.js @@ -1,16 +1,16 @@ import Vue from 'vue' -import reject from 'lodash/reject' +import filter from 'lodash/filter' import isEmpty from 'lodash/isEmpty' -import omit from 'lodash/omit' import './with_subscription.scss' const withSubscription = ({ fetch, // function to fetch entries and return a promise select, // function to select data from store - childPropName = 'content' // name of the prop to be passed into the wrapped component + childPropName = 'content', // name of the prop to be passed into the wrapped component + additionalPropNames = [] // additional prop name list of the wrapper component }) => (WrappedComponent) => { const originalProps = WrappedComponent.props || [] - const props = reject(originalProps, v => v === 'content') + const props = filter(originalProps, v => v !== childPropName).concat(additionalPropNames) return Vue.component('withSubscription', { props: [ @@ -21,7 +21,7 @@ const withSubscription = ({ if (!this.error && !this.loading) { const props = { props: { - ...omit(this.$props, 'refresh'), + ...this.$props, [childPropName]: this.fetchedData }, on: this.$listeners, -- cgit v1.2.3-70-g09d2 From cb383df517dc5cd5b4d90136b533977a33611b71 Mon Sep 17 00:00:00 2001 From: taehoon Date: Mon, 25 Feb 2019 04:18:41 -0500 Subject: Fix bug to get wrapped component prop name list --- src/hocs/with_load_more/with_load_more.js | 3 ++- src/hocs/with_subscription/with_subscription.js | 3 ++- src/services/component_utils/component_utils.js | 10 ++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 src/services/component_utils/component_utils.js (limited to 'src/hocs') diff --git a/src/hocs/with_load_more/with_load_more.js b/src/hocs/with_load_more/with_load_more.js index a521014c..7d53e7ac 100644 --- a/src/hocs/with_load_more/with_load_more.js +++ b/src/hocs/with_load_more/with_load_more.js @@ -1,6 +1,7 @@ import Vue from 'vue' import filter from 'lodash/filter' import isEmpty from 'lodash/isEmpty' +import { getComponentProps } from '../../services/component_utils/component_utils' import './with_load_more.scss' const withLoadMore = ({ @@ -9,7 +10,7 @@ const withLoadMore = ({ childPropName = 'entries', // name of the prop to be passed into the wrapped component additionalPropNames = [] // additional prop name list of the wrapper component }) => (WrappedComponent) => { - const originalProps = WrappedComponent.props || [] + const originalProps = Object.keys(getComponentProps(WrappedComponent)) const props = filter(originalProps, v => v !== childPropName).concat(additionalPropNames) return Vue.component('withLoadMore', { diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.js index b6bc8358..4d3ae811 100644 --- a/src/hocs/with_subscription/with_subscription.js +++ b/src/hocs/with_subscription/with_subscription.js @@ -1,6 +1,7 @@ import Vue from 'vue' import filter from 'lodash/filter' import isEmpty from 'lodash/isEmpty' +import { getComponentProps } from '../../services/component_utils/component_utils' import './with_subscription.scss' const withSubscription = ({ @@ -9,7 +10,7 @@ const withSubscription = ({ childPropName = 'content', // name of the prop to be passed into the wrapped component additionalPropNames = [] // additional prop name list of the wrapper component }) => (WrappedComponent) => { - const originalProps = WrappedComponent.props || [] + const originalProps = Object.keys(getComponentProps(WrappedComponent)) const props = filter(originalProps, v => v !== childPropName).concat(additionalPropNames) return Vue.component('withSubscription', { diff --git a/src/services/component_utils/component_utils.js b/src/services/component_utils/component_utils.js new file mode 100644 index 00000000..77ea14a1 --- /dev/null +++ b/src/services/component_utils/component_utils.js @@ -0,0 +1,10 @@ +import isFunction from 'lodash/isFunction' + +const getComponentOptions = (Component) => (isFunction(Component)) ? Component.options : Component + +const getComponentProps = (Component) => getComponentOptions(Component).props + +export { + getComponentOptions, + getComponentProps +} -- cgit v1.2.3-70-g09d2 From 080786c9458ba8b9db1ea63732824a3e297e10dc Mon Sep 17 00:00:00 2001 From: taehoon Date: Mon, 25 Feb 2019 04:51:23 -0500 Subject: Rewrite FollowList using hocs --- src/components/follow_list/follow_list.js | 68 ---------------------------- src/components/follow_list/follow_list.vue | 33 -------------- src/components/user_profile/user_profile.js | 29 +++++++++++- src/components/user_profile/user_profile.vue | 10 +--- src/hocs/with_load_more/with_load_more.js | 2 + src/modules/users.js | 19 ++++++-- 6 files changed, 45 insertions(+), 116 deletions(-) delete mode 100644 src/components/follow_list/follow_list.js delete mode 100644 src/components/follow_list/follow_list.vue (limited to 'src/hocs') diff --git a/src/components/follow_list/follow_list.js b/src/components/follow_list/follow_list.js deleted file mode 100644 index 9777c87e..00000000 --- a/src/components/follow_list/follow_list.js +++ /dev/null @@ -1,68 +0,0 @@ -import UserCard from '../user_card/user_card.vue' - -const FollowList = { - data () { - return { - loading: false, - bottomedOut: false, - error: false - } - }, - props: ['userId', 'showFollowers'], - created () { - window.addEventListener('scroll', this.scrollLoad) - if (this.entries.length === 0) { - this.fetchEntries() - } - }, - destroyed () { - window.removeEventListener('scroll', this.scrollLoad) - this.$store.dispatch('clearFriendsAndFollowers', this.userId) - }, - computed: { - user () { - return this.$store.getters.userById(this.userId) - }, - entries () { - return this.showFollowers ? this.user.followers : this.user.friends - }, - showFollowsYou () { - return !this.showFollowers || (this.showFollowers && this.userId !== this.$store.state.users.currentUser.id) - } - }, - methods: { - fetchEntries () { - if (!this.loading) { - const command = this.showFollowers ? 'addFollowers' : 'addFriends' - this.loading = true - this.$store.dispatch(command, this.userId).then(entries => { - this.error = false - this.loading = false - this.bottomedOut = entries.length === 0 - }).catch(() => { - this.error = true - this.loading = false - }) - } - }, - scrollLoad (e) { - const bodyBRect = document.body.getBoundingClientRect() - const height = Math.max(bodyBRect.height, -(bodyBRect.y)) - if (this.loading === false && - this.bottomedOut === false && - this.$el.offsetHeight > 0 && - (window.innerHeight + window.pageYOffset) >= (height - 750) - ) { - this.fetchEntries() - } - } - }, - watch: { - 'user': 'fetchEntries' - }, - components: { - UserCard - } -} - -export default FollowList diff --git a/src/components/follow_list/follow_list.vue b/src/components/follow_list/follow_list.vue deleted file mode 100644 index 27102edf..00000000 --- a/src/components/follow_list/follow_list.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - - - diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js index ebf6c61a..9f9d43e4 100644 --- a/src/components/user_profile/user_profile.js +++ b/src/components/user_profile/user_profile.js @@ -1,8 +1,32 @@ +import { compose } from 'vue-compose' import get from 'lodash/get' import UserCardContent from '../user_card_content/user_card_content.vue' import UserCard from '../user_card/user_card.vue' import Timeline from '../timeline/timeline.vue' -import FollowList from '../follow_list/follow_list.vue' +import withLoadMore from '../../hocs/with_load_more/with_load_more' +import withList from '../../hocs/with_list/with_list' + +const FollowerList = compose( + withLoadMore({ + fetch: (props, $store) => $store.dispatch('addFollowers', props.userId), + select: (props, $store) => get($store.getters.userById(props.userId), 'followers', []), + destory: (props, $store) => $store.dispatch('clearFollowers', props.userId), + childPropName: 'entries', + additionalPropNames: ['userId'] + }), + withList({ getEntryProps: user => ({ user }) }) +)(UserCard) + +const FriendList = compose( + withLoadMore({ + fetch: (props, $store) => $store.dispatch('addFriends', props.userId), + select: (props, $store) => get($store.getters.userById(props.userId), 'friends', []), + destory: (props, $store) => $store.dispatch('clearFriends', props.userId), + childPropName: 'entries', + additionalPropNames: ['userId'] + }), + withList({ getEntryProps: user => ({ user }) }) +)(UserCard) const UserProfile = { data () { @@ -123,7 +147,8 @@ const UserProfile = { UserCardContent, UserCard, Timeline, - FollowList + FollowerList, + FriendList } } diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue index ba1a7760..a3d2825f 100644 --- a/src/components/user_profile/user_profile.vue +++ b/src/components/user_profile/user_profile.vue @@ -18,16 +18,10 @@ :user-id="fetchBy" />
- -
- -
+
- -
- -
+
(WrappedComponent) => { @@ -58,6 +59,7 @@ const withLoadMore = ({ }, destroyed () { window.removeEventListener('scroll', this.scrollLoad) + destroy && destroy(this.$props, this.$store) }, methods: { fetchEntries () { diff --git a/src/modules/users.js b/src/modules/users.js index b2821a92..093af497 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -72,14 +72,20 @@ export const mutations = { }, // Because frontend doesn't have a reason to keep these stuff in memory // outside of viewing someones user profile. - clearFriendsAndFollowers (state, userKey) { - const user = state.usersObject[userKey] + clearFriends (state, userId) { + const user = state.usersObject[userId] if (!user) { return } user.friends = [] - user.followers = [] user.friendsPage = 0 + }, + clearFollowers (state, userId) { + const user = state.usersObject[userId] + if (!user) { + return + } + user.followers = [] user.followersPage = 0 }, addNewUsers (state, users) { @@ -197,8 +203,11 @@ const users = { return followers }) }, - clearFriendsAndFollowers ({ commit }, userKey) { - commit('clearFriendsAndFollowers', userKey) + clearFriends ({ commit }, userId) { + commit('clearFriends', userId) + }, + clearFollowers ({ commit }, userId) { + commit('clearFollowers', userId) }, registerPushNotifications (store) { const token = store.state.currentUser.credentials -- cgit v1.2.3-70-g09d2 From 651c97153ba90daaacc5facc56e20aec5cdb112e Mon Sep 17 00:00:00 2001 From: taehoon Date: Tue, 26 Feb 2019 15:26:59 -0500 Subject: Use native filter function --- src/hocs/with_load_more/with_load_more.js | 3 +-- src/hocs/with_subscription/with_subscription.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/hocs') diff --git a/src/hocs/with_load_more/with_load_more.js b/src/hocs/with_load_more/with_load_more.js index b8246ec9..74979b87 100644 --- a/src/hocs/with_load_more/with_load_more.js +++ b/src/hocs/with_load_more/with_load_more.js @@ -1,5 +1,4 @@ import Vue from 'vue' -import filter from 'lodash/filter' import isEmpty from 'lodash/isEmpty' import { getComponentProps } from '../../services/component_utils/component_utils' import './with_load_more.scss' @@ -12,7 +11,7 @@ const withLoadMore = ({ additionalPropNames = [] // additional prop name list of the wrapper component }) => (WrappedComponent) => { const originalProps = Object.keys(getComponentProps(WrappedComponent)) - const props = filter(originalProps, v => v !== childPropName).concat(additionalPropNames) + const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames) return Vue.component('withLoadMore', { render (createElement) { diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.js index 4d3ae811..679409cf 100644 --- a/src/hocs/with_subscription/with_subscription.js +++ b/src/hocs/with_subscription/with_subscription.js @@ -1,5 +1,4 @@ import Vue from 'vue' -import filter from 'lodash/filter' import isEmpty from 'lodash/isEmpty' import { getComponentProps } from '../../services/component_utils/component_utils' import './with_subscription.scss' @@ -11,7 +10,7 @@ const withSubscription = ({ additionalPropNames = [] // additional prop name list of the wrapper component }) => (WrappedComponent) => { const originalProps = Object.keys(getComponentProps(WrappedComponent)) - const props = filter(originalProps, v => v !== childPropName).concat(additionalPropNames) + const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames) return Vue.component('withSubscription', { props: [ -- cgit v1.2.3-70-g09d2