commit: 76a2e6befb3aea6e890bb3c2e001a4635d05091a
parent 1f5f612163bd1c359212c2e6832806f0dd606977
Author: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Apr 2021 12:50:17 +0300
remove Vue.component from hooks
Diffstat:
4 files changed, 204 insertions(+), 205 deletions(-)
diff --git a/src/hocs/with_load_more/with_load_more.js b/src/hocs/with_load_more/with_load_more.js
@@ -1,111 +0,0 @@
-import isEmpty from 'lodash/isEmpty'
-import { getComponentProps } from '../../services/component_utils/component_utils'
-import './with_load_more.scss'
-
-import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
-import { library } from '@fortawesome/fontawesome-svg-core'
-import {
- faCircleNotch
-} from '@fortawesome/free-solid-svg-icons'
-
-library.add(
- faCircleNotch
-)
-
-const withLoadMore = ({
- fetch, // function to fetch entries and return a promise
- select, // function to select data from store
- destroy, // function called at "destroyed" lifecycle
- 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 = Object.keys(getComponentProps(WrappedComponent))
- const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames)
-
- return {
- props,
- data () {
- return {
- loading: false,
- bottomedOut: false,
- error: false,
- entries: []
- }
- },
- created () {
- window.addEventListener('scroll', this.scrollLoad)
- if (this.entries.length === 0) {
- this.fetchEntries()
- }
- },
- destroyed () {
- window.removeEventListener('scroll', this.scrollLoad)
- destroy && destroy(this.$props, this.$store)
- },
- methods: {
- // Entries is not a computed because computed can't track the dynamic
- // selector for changes and won't trigger after fetch.
- updateEntries () {
- this.entries = select(this.$props, this.$store) || []
- },
- fetchEntries () {
- if (!this.loading) {
- this.loading = true
- this.error = false
- fetch(this.$props, this.$store)
- .then((newEntries) => {
- this.loading = false
- this.bottomedOut = isEmpty(newEntries)
- })
- .catch(() => {
- this.loading = false
- this.error = true
- })
- .finally(() => {
- this.updateEntries()
- })
- }
- },
- 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()
- }
- }
- },
- render (h) {
- const props = {
- props: {
- ...this.$props,
- [childPropName]: this.entries
- },
- on: this.$listeners,
- scopedSlots: this.$scopedSlots
- }
- const children = Object.entries(this.$slots).map(([key, value]) => h('template', { slot: key }, value))
- return (
- <div class="with-load-more">
- <WrappedComponent {...props}>
- {children}
- </WrappedComponent>
- <div class="with-load-more-footer">
- {this.error &&
- <button onClick={this.fetchEntries} class="button-unstyled -link -fullwidth alert error">
- {this.$t('general.generic_error')}
- </button>
- }
- {!this.error && this.loading && <FAIcon spin icon="circle-notch"/>}
- {!this.error && !this.loading && !this.bottomedOut && <a onClick={this.fetchEntries}>{this.$t('general.more')}</a>}
- </div>
- </div>
- )
- }
- }
-}
-
-export default withLoadMore
diff --git a/src/hocs/with_load_more/with_load_more.jsx b/src/hocs/with_load_more/with_load_more.jsx
@@ -0,0 +1,111 @@
+import isEmpty from 'lodash/isEmpty'
+import { getComponentProps } from '../../services/component_utils/component_utils'
+import './with_load_more.scss'
+
+import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
+import { library } from '@fortawesome/fontawesome-svg-core'
+import {
+ faCircleNotch
+} from '@fortawesome/free-solid-svg-icons'
+
+library.add(
+ faCircleNotch
+)
+
+const withLoadMore = ({
+ fetch, // function to fetch entries and return a promise
+ select, // function to select data from store
+ destroy, // function called at "destroyed" lifecycle
+ 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 = Object.keys(getComponentProps(WrappedComponent))
+ const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames)
+
+ return {
+ props,
+ data () {
+ return {
+ loading: false,
+ bottomedOut: false,
+ error: false,
+ entries: []
+ }
+ },
+ created () {
+ window.addEventListener('scroll', this.scrollLoad)
+ if (this.entries.length === 0) {
+ this.fetchEntries()
+ }
+ },
+ unmounted () {
+ window.removeEventListener('scroll', this.scrollLoad)
+ destroy && destroy(this.$props, this.$store)
+ },
+ methods: {
+ // Entries is not a computed because computed can't track the dynamic
+ // selector for changes and won't trigger after fetch.
+ updateEntries () {
+ this.entries = select(this.$props, this.$store) || []
+ },
+ fetchEntries () {
+ if (!this.loading) {
+ this.loading = true
+ this.error = false
+ fetch(this.$props, this.$store)
+ .then((newEntries) => {
+ this.loading = false
+ this.bottomedOut = isEmpty(newEntries)
+ })
+ .catch(() => {
+ this.loading = false
+ this.error = true
+ })
+ .finally(() => {
+ this.updateEntries()
+ })
+ }
+ },
+ 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()
+ }
+ }
+ },
+ render (h) {
+ const props = {
+ props: {
+ ...this.$props,
+ [childPropName]: this.entries
+ },
+ on: this.$listeners,
+ scopedSlots: this.$scopedSlots
+ }
+ const children = Object.entries(this.$slots).map(([key, value]) => h('template', { slot: key }, value))
+ return (
+ <div class="with-load-more">
+ <WrappedComponent {...props}>
+ {children}
+ </WrappedComponent>
+ <div class="with-load-more-footer">
+ {this.error &&
+ <button onClick={this.fetchEntries} class="button-unstyled -link -fullwidth alert error">
+ {this.$t('general.generic_error')}
+ </button>
+ }
+ {!this.error && this.loading && <FAIcon spin icon="circle-notch"/>}
+ {!this.error && !this.loading && !this.bottomedOut && <a onClick={this.fetchEntries}>{this.$t('general.more')}</a>}
+ </div>
+ </div>
+ )
+ }
+ }
+}
+
+export default withLoadMore
diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.js
@@ -1,94 +0,0 @@
-import Vue from 'vue'
-import isEmpty from 'lodash/isEmpty'
-import { getComponentProps } from '../../services/component_utils/component_utils'
-import './with_subscription.scss'
-
-import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
-import { library } from '@fortawesome/fontawesome-svg-core'
-import {
- faCircleNotch
-} from '@fortawesome/free-solid-svg-icons'
-
-library.add(
- faCircleNotch
-)
-
-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
- additionalPropNames = [] // additional prop name list of the wrapper component
-}) => (WrappedComponent) => {
- const originalProps = Object.keys(getComponentProps(WrappedComponent))
- const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames)
-
- return Vue.component('withSubscription', {
- props: [
- ...props,
- 'refresh' // boolean saying to force-fetch data whenever created
- ],
- data () {
- return {
- loading: false,
- error: false
- }
- },
- computed: {
- fetchedData () {
- return select(this.$props, this.$store)
- }
- },
- created () {
- if (this.refresh || 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
- })
- }
- }
- },
- render (h) {
- if (!this.error && !this.loading) {
- const props = {
- props: {
- ...this.$props,
- [childPropName]: this.fetchedData
- },
- on: this.$listeners,
- scopedSlots: this.$scopedSlots
- }
- const children = Object.entries(this.$slots).map(([key, value]) => h('template', { slot: key }, value))
- return (
- <div class="with-subscription">
- <WrappedComponent {...props}>
- {children}
- </WrappedComponent>
- </div>
- )
- } else {
- return (
- <div class="with-subscription-loading">
- {this.error
- ? <a onClick={this.fetchData} class="alert error">{this.$t('general.generic_error')}</a>
- : <FAIcon spin icon="circle-notch"/>
- }
- </div>
- )
- }
- }
- })
-}
-
-export default withSubscription
diff --git a/src/hocs/with_subscription/with_subscription.jsx b/src/hocs/with_subscription/with_subscription.jsx
@@ -0,0 +1,93 @@
+import isEmpty from 'lodash/isEmpty'
+import { getComponentProps } from '../../services/component_utils/component_utils'
+import './with_subscription.scss'
+
+import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
+import { library } from '@fortawesome/fontawesome-svg-core'
+import {
+ faCircleNotch
+} from '@fortawesome/free-solid-svg-icons'
+
+library.add(
+ faCircleNotch
+)
+
+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
+ additionalPropNames = [] // additional prop name list of the wrapper component
+}) => (WrappedComponent) => {
+ const originalProps = Object.keys(getComponentProps(WrappedComponent))
+ const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames)
+
+ return {
+ props: [
+ ...props,
+ 'refresh' // boolean saying to force-fetch data whenever created
+ ],
+ data () {
+ return {
+ loading: false,
+ error: false
+ }
+ },
+ computed: {
+ fetchedData () {
+ return select(this.$props, this.$store)
+ }
+ },
+ created () {
+ if (this.refresh || 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
+ })
+ }
+ }
+ },
+ render (h) {
+ if (!this.error && !this.loading) {
+ const props = {
+ props: {
+ ...this.$props,
+ [childPropName]: this.fetchedData
+ },
+ on: this.$listeners,
+ scopedSlots: this.$scopedSlots
+ }
+ const children = Object.entries(this.$slots).map(([key, value]) => h('template', { slot: key }, value))
+ return (
+ <div class="with-subscription">
+ <WrappedComponent {...props}>
+ {children}
+ </WrappedComponent>
+ </div>
+ )
+ } else {
+ return (
+ <div class="with-subscription-loading">
+ {this.error
+ ? <a onClick={this.fetchData} class="alert error">{this.$t('general.generic_error')}</a>
+ : <FAIcon spin icon="circle-notch"/>
+ }
+ </div>
+ )
+ }
+ }
+ }
+}
+
+export default withSubscription