feat: following and followers routes (#4)

zio/stable
patak 2022-11-15 16:56:11 +01:00 committed by GitHub
parent 39249e378f
commit a6a189ba59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 127 additions and 39 deletions

View File

@ -0,0 +1,18 @@
<script setup lang="ts">
import type { Account } from 'masto'
defineProps<{
account: Account
}>()
</script>
<template>
<div flex justify-between>
<AccountInfo :account="account" p3 />
<div h-full p5>
<!-- TODO is following logic and actions -->
<div v-if="false" color-purple hover:color-gray hover:cursor-pointer i-ri:user-unfollow-fill />
<div v-else color-gray hover:color-purple hover:cursor-pointer i-ri:user-follow-fill />
</div>
</div>
</template>

View File

@ -71,9 +71,15 @@ const createdAt = $computed(() => {
</div> </div>
</div> </div>
<div flex gap-5> <div flex gap-5>
<div><span font-bold>{{ account.statusesCount }}</span> Posts</div> <NuxtLink :to="`/@${account.acct}/`">
<div><span font-bold>{{ account.followingCount }}</span> Following</div> <span font-bold>{{ account.statusesCount }}</span> Posts
<div><span font-bold>{{ account.followersCount }}</span> Followers</div> </NuxtLink>
<NuxtLink :to="`/@${account.acct}/following`">
<span font-bold>{{ account.followingCount }}</span> Following
</NuxtLink>
<NuxtLink :to="`/@${account.acct}/followers`">
<span font-bold>{{ account.followersCount }}</span> Followers
</NuxtLink>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,22 @@
<script setup lang="ts">
import type { Account, Paginator } from 'masto'
const { paginator } = defineProps<{
paginator: Paginator<any, Account[]>
}>()
const { items: accounts, isLoading, isDone, endAnchor } = usePaginator(paginator)
</script>
<template>
<template v-for="account of accounts" :key="account.id">
<AccountCard :account="account" border="t border" pt-4 />
</template>
<div ref="endAnchor" />
<div v-if="isLoading">
Loading...
</div>
<div v-if="isDone">
End of list
</div>
</template>

View File

@ -5,42 +5,7 @@ const { paginator } = defineProps<{
paginator: Paginator<any, Status[]> paginator: Paginator<any, Status[]>
}>() }>()
let isLoading = $ref(false) const { items: statuses, isLoading, isDone, endAnchor } = usePaginator(paginator)
let isDone = $ref(false)
const statuses = $ref<Status[]>([])
const endAnchor = ref<HTMLDivElement>()
const bound = reactive(useElementBounding(endAnchor))
const isInScreen = $computed(() => bound.top < window.innerHeight * 2)
async function loadNext() {
if (isLoading || isDone)
return
// console.log('REQUEST')
isLoading = true
const result = await paginator.next()
if (result.done)
isDone = true
if (result.value?.length)
statuses.push(...result.value)
isLoading = false
await nextTick()
bound.update()
}
useIntervalFn(() => {
bound.update()
}, 1000)
watch(
() => isInScreen,
() => {
if (isInScreen && !isLoading)
loadNext()
},
{ immediate: true },
)
</script> </script>
<template> <template>

View File

@ -0,0 +1,41 @@
import type { Paginator } from 'masto'
export function usePaginator<T>(paginator: Paginator<any, T[]>) {
let isLoading = $ref(false)
let isDone = $ref(false)
const items = $ref<T[]>([])
const endAnchor = ref<HTMLDivElement>()
const bound = reactive(useElementBounding(endAnchor))
const isInScreen = $computed(() => bound.top < window.innerHeight * 2)
async function loadNext() {
if (isLoading || isDone)
return
isLoading = true
const result = await paginator.next()
if (result.done)
isDone = true
if (result.value?.length)
items.push(...result.value)
isLoading = false
await nextTick()
bound.update()
}
useIntervalFn(() => {
bound.update()
}, 1000)
watch(
() => isInScreen,
() => {
if (isInScreen && !isLoading)
loadNext()
},
{ immediate: true },
)
return { items, isLoading, isDone, endAnchor }
}

View File

@ -0,0 +1,18 @@
<script setup lang="ts">
const props = defineProps<{
modelValue?: boolean
}>()
const params = useRoute().params
const user = $computed(() => params.user as string)
const masto = await useMasto()
const { data: account } = await useAsyncData(`${user}:info`, () => masto.accounts.lookup({ acct: user }))
const paginator = masto.accounts.getFollowersIterable(account.value!.id!, {})
</script>
<template>
<div>
<AccountHeader :account="account" />
</div>
<AccountPaginator :paginator="paginator" />
</template>

View File

@ -0,0 +1,18 @@
<script setup lang="ts">
const props = defineProps<{
modelValue?: boolean
}>()
const params = useRoute().params
const user = $computed(() => params.user as string)
const masto = await useMasto()
const { data: account } = await useAsyncData(`${user}:info`, () => masto.accounts.lookup({ acct: user }))
const paginator = masto.accounts.getFollowingIterable(account.value!.id!, {})
</script>
<template>
<div>
<AccountHeader :account="account" />
</div>
<AccountPaginator :paginator="paginator" />
</template>