zaphyra's git: domsonic

subsonic web-client

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 import { useTemplateRef, watch, onMounted, onBeforeUnmount } from 'vue'
import { isElementInViewport } from '../utils'

export const InfiniteLoader = ({ isLoading, hasMore }: { isLoading: boolean, hasMore: boolean }) => {
  const emit = vineEmits(['load-more'])
  const
    loaderElement = useTemplateRef('loader'),
    loaderObserver = new IntersectionObserver(([ entry ]) => {
      (
        entry?.isIntersecting &&
        !isLoading && hasMore
      ) && emit('load-more')
    })

  onBeforeUnmount(() => loaderObserver.unobserve(loaderElement.value as HTMLElement))
  onMounted(() => {
    loaderObserver.observe(loaderElement.value as HTMLElement)
    emit('load-more')
  })
  watch(
    () => [ isLoading, hasMore ],
    () => {
      (
        isElementInViewport(loaderElement.value as HTMLElement) &&
        !isLoading && hasMore
      ) && emit('load-more')
    },
    { immediate: true }
  )

  return vine`
    <div ref="loader" class="row justify-content-center">
      <span :aria-busy="isLoading" />
    </div>
  `
}