kodadot/nft-gallery

View on GitHub
components/profile/follow/Tab.vue

Summary

Maintainability
Test Coverage
<template>
  <div
    v-if="isLoading"
    class="flex flex-col gap-5"
  >
    <UserRowSkeleton
      v-for="(_, index) in loadingSkeletonItems"
      :key="index"
    />
  </div>
  <div
    v-else-if="totalCount > 0"
    ref="el"
    class="flex flex-col gap-5 max-h-[400px] overflow-y-auto"
  >
    <UserRow
      v-for="user in vList"
      :key="user.address"
      :user="user"
    />
  </div>
  <div
    v-else
    class="text-center text-k-grey"
  >
    <span>Not Following Anyone Yet</span>
  </div>
</template>

<script setup lang="ts">
import { useInfiniteScroll } from '@vueuse/core'
import type { Tab } from '../types'
import UserRow from '@/components/profile/follow/UserRow.vue'
import UserRowSkeleton from '@/components/profile/follow/UserRowSkeleton.vue'

import type { Follower } from '@/services/profile'
import { fetchFollowersOf, fetchFollowing } from '@/services/profile'

const route = useRoute()

const props = defineProps<{
  totalCount: number
  type: Tab
}>()

const vList = ref<Follower[]>([])
const offset = computed(() => vList.value.length)
const limit = 10
const el = ref<HTMLElement | null>(null)
const loadingSkeletonItems = computed(() => Math.min(4, props.totalCount))
const isLoading = ref(false)

const fetchNextPage = async () => {
  if (offset.value >= props.totalCount) {
    return
  }

  if (offset.value === 0) {
    isLoading.value = true
  }
  if (props.type === 'following') {
    const { following } = await fetchFollowing(route.params.id as string, {
      limit,
      offset: offset.value,
    })
    vList.value.push(...following)
  }
  else {
    const { followers } = await fetchFollowersOf(route.params.id as string, {
      limit,
      offset: offset.value,
    })
    vList.value.push(...followers)
  }

  isLoading.value = false
}

onMounted(() => {
  if (props.totalCount > 0) {
    fetchNextPage()
  }
})

useInfiniteScroll(el, fetchNextPage, { distance: limit })
</script>