logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git

with_subscription.js (2665B)


  1. import Vue from 'vue'
  2. import isEmpty from 'lodash/isEmpty'
  3. import { getComponentProps } from '../../services/component_utils/component_utils'
  4. import './with_subscription.scss'
  5. import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
  6. import { library } from '@fortawesome/fontawesome-svg-core'
  7. import {
  8. faCircleNotch
  9. } from '@fortawesome/free-solid-svg-icons'
  10. library.add(
  11. faCircleNotch
  12. )
  13. const withSubscription = ({
  14. fetch, // function to fetch entries and return a promise
  15. select, // function to select data from store
  16. childPropName = 'content', // name of the prop to be passed into the wrapped component
  17. additionalPropNames = [] // additional prop name list of the wrapper component
  18. }) => (WrappedComponent) => {
  19. const originalProps = Object.keys(getComponentProps(WrappedComponent))
  20. const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames)
  21. return Vue.component('withSubscription', {
  22. props: [
  23. ...props,
  24. 'refresh' // boolean saying to force-fetch data whenever created
  25. ],
  26. data () {
  27. return {
  28. loading: false,
  29. error: false
  30. }
  31. },
  32. computed: {
  33. fetchedData () {
  34. return select(this.$props, this.$store)
  35. }
  36. },
  37. created () {
  38. if (this.refresh || isEmpty(this.fetchedData)) {
  39. this.fetchData()
  40. }
  41. },
  42. methods: {
  43. fetchData () {
  44. if (!this.loading) {
  45. this.loading = true
  46. this.error = false
  47. fetch(this.$props, this.$store)
  48. .then(() => {
  49. this.loading = false
  50. })
  51. .catch(() => {
  52. this.error = true
  53. this.loading = false
  54. })
  55. }
  56. }
  57. },
  58. render (h) {
  59. if (!this.error && !this.loading) {
  60. const props = {
  61. props: {
  62. ...this.$props,
  63. [childPropName]: this.fetchedData
  64. },
  65. on: this.$listeners,
  66. scopedSlots: this.$scopedSlots
  67. }
  68. const children = Object.entries(this.$slots).map(([key, value]) => h('template', { slot: key }, value))
  69. return (
  70. <div class="with-subscription">
  71. <WrappedComponent {...props}>
  72. {children}
  73. </WrappedComponent>
  74. </div>
  75. )
  76. } else {
  77. return (
  78. <div class="with-subscription-loading">
  79. {this.error
  80. ? <a onClick={this.fetchData} class="alert error">{this.$t('general.generic_error')}</a>
  81. : <FAIcon spin icon="circle-notch"/>
  82. }
  83. </div>
  84. )
  85. }
  86. }
  87. })
  88. }
  89. export default withSubscription