From 159e84532ebdae038e1263efe8832015597a5e20 Mon Sep 17 00:00:00 2001 From: taehoon Date: Wed, 13 Feb 2019 21:07:28 -0500 Subject: Add withSubscription hoc --- src/hocs/with_subscription/with_subscription.js | 65 +++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/hocs/with_subscription/with_subscription.js (limited to 'src/hocs/with_subscription/with_subscription.js') diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.js new file mode 100644 index 00000000..31fc106f --- /dev/null +++ b/src/hocs/with_subscription/with_subscription.js @@ -0,0 +1,65 @@ +import Vue from 'vue' +import filter from 'lodash/filter' +import isEmpty from 'lodash/isEmpty' +import './with_subscription.scss' + +const withSubscription = (Component, fetch, select, contentPropName = 'content') => { + const originalProps = Component.props || [] + const props = filter(originalProps, v => v !== 'content') + + return Vue.component('withSubscription', { + render (createElement) { + const props = { + props: { + ...this.$props, + [contentPropName]: this.fetchedData + }, + on: this.$listeners + } + return ( +
+ + +
+ ) + }, + props, + data () { + return { + loading: false, + error: false + } + }, + computed: { + fetchedData () { + return select(this.$props, this.$store) + } + }, + created () { + if (isEmpty(this.fetchedData)) { + this.fetchData() + } + }, + methods: { + fetchData () { + if (!this.loading) { + this.loading = true + this.error = false + fetch(this.$props, this.$store) + .then(() => { + this.loading = false + }) + .catch(() => { + this.error = true + this.loading = false + }) + } + } + } + }) +} + +export default withSubscription -- cgit v1.2.3-70-g09d2 From 09315b27804beadb7590f8e908ae9d0eb1d6a992 Mon Sep 17 00:00:00 2001 From: taehoon Date: Wed, 13 Feb 2019 21:21:56 -0500 Subject: Add a prop to force-refresh data to withSubscription hoc --- src/components/user_settings/user_settings.vue | 2 +- src/hocs/with_subscription/with_subscription.js | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/hocs/with_subscription/with_subscription.js') diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index 5cf21815..5bae583c 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -164,7 +164,7 @@
- +
diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.js index 31fc106f..633517e3 100644 --- a/src/hocs/with_subscription/with_subscription.js +++ b/src/hocs/with_subscription/with_subscription.js @@ -1,24 +1,25 @@ import Vue from 'vue' -import filter from 'lodash/filter' +import reject from 'lodash/reject' import isEmpty from 'lodash/isEmpty' +import omit from 'lodash/omit' import './with_subscription.scss' const withSubscription = (Component, fetch, select, contentPropName = 'content') => { const originalProps = Component.props || [] - const props = filter(originalProps, v => v !== 'content') + const props = reject(originalProps, v => v === 'content') return Vue.component('withSubscription', { render (createElement) { const props = { props: { - ...this.$props, + ...omit(this.$props, 'refresh'), [contentPropName]: this.fetchedData }, on: this.$listeners } return (
- + {!this.error && !this.loading && } ) }, - props, + props: [...props, 'refresh'], data () { return { loading: false, @@ -39,7 +40,7 @@ const withSubscription = (Component, fetch, select, contentPropName = 'content') } }, created () { - if (isEmpty(this.fetchedData)) { + if (this.refresh || isEmpty(this.fetchedData)) { this.fetchData() } }, -- cgit v1.2.3-70-g09d2 From f81b82b4714643ba396b69ca54b97259a36a6b9f Mon Sep 17 00:00:00 2001 From: taehoon Date: Wed, 13 Feb 2019 22:52:57 -0500 Subject: Use hoc definitions to be factor of factory --- src/components/user_settings/user_settings.js | 26 ++++++++++++------------- src/hocs/with_list/with_list.js | 8 ++++---- src/hocs/with_load_more/with_load_more.js | 6 +++--- src/hocs/with_subscription/with_subscription.js | 6 +++--- 4 files changed, 22 insertions(+), 24 deletions(-) (limited to 'src/hocs/with_subscription/with_subscription.js') diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 8114d5e2..21023841 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -10,21 +10,19 @@ import MuteCard from '../mute_card/mute_card.vue' import withSubscription from '../../hocs/with_subscription/with_subscription' import withList from '../../hocs/with_list/with_list' -const BlockList = withList(BlockCard, userId => ({ userId })) -const BlockListWithSubscription = withSubscription( - BlockList, - (props, $store) => $store.dispatch('fetchBlocks'), - (props, $store) => get($store.state.users.currentUser, 'blockIds', []), - 'entries' -) +const BlockList = withList({ getEntryProps: userId => ({ userId }) })(BlockCard) +const BlockListWithSubscription = withSubscription({ + fetch: (props, $store) => $store.dispatch('fetchBlocks'), + select: (props, $store) => get($store.state.users.currentUser, 'blockIds', []), + contentPropName: 'entries' +})(BlockList) -const MuteList = withList(MuteCard, userId => ({ userId })) -const MuteListWithSubscription = withSubscription( - MuteList, - (props, $store) => $store.dispatch('fetchMutes'), - (props, $store) => get($store.state.users.currentUser, 'muteIds', []), - 'entries' -) +const MuteList = withList({ getEntryProps: userId => ({ userId }) })(MuteCard) +const MuteListWithSubscription = withSubscription({ + fetch: (props, $store) => $store.dispatch('fetchMutes'), + select: (props, $store) => get($store.state.users.currentUser, 'muteIds', []), + contentPropName: 'entries' +})(MuteList) const UserSettings = { data () { diff --git a/src/hocs/with_list/with_list.js b/src/hocs/with_list/with_list.js index 5ec37a2b..c31cdcb1 100644 --- a/src/hocs/with_list/with_list.js +++ b/src/hocs/with_list/with_list.js @@ -4,8 +4,8 @@ import map from 'lodash/map' const defaultEntryPropsGetter = entry => ({ entry }) const defaultKeyGetter = entry => entry.id -const withList = (Component, getEntryProps = defaultEntryPropsGetter, getKey = defaultKeyGetter) => { - return Vue.component('withList', { +const withList = ({ getEntryProps = defaultEntryPropsGetter, getKey = defaultKeyGetter }) => (ItemComponent) => ( + Vue.component('withList', { render (createElement) { return (
@@ -18,13 +18,13 @@ const withList = (Component, getEntryProps = defaultEntryPropsGetter, getKey = d }, on: this.$props.entryListeners } - return + return })}
) }, props: ['entries', 'entryProps', 'entryListeners'] }) -} +) export default withList diff --git a/src/hocs/with_load_more/with_load_more.js b/src/hocs/with_load_more/with_load_more.js index 8877f8d3..28c741e3 100644 --- a/src/hocs/with_load_more/with_load_more.js +++ b/src/hocs/with_load_more/with_load_more.js @@ -3,8 +3,8 @@ import filter from 'lodash/filter' import isEmpty from 'lodash/isEmpty' import './with_load_more.scss' -const withLoadMore = (Component, fetch, select, entriesPropName = 'entries') => { - const originalProps = Component.props || [] +const withLoadMore = ({ fetch, select, entriesPropName = 'entries' }) => (WrappedComponent) => { + const originalProps = WrappedComponent.props || [] const props = filter(originalProps, v => v !== 'entries') return Vue.component('withLoadMore', { @@ -18,7 +18,7 @@ const withLoadMore = (Component, fetch, select, entriesPropName = 'entries') => } return (
- +