feat: use nested routes for profile

This commit is contained in:
Anthony Fu 2022-11-24 14:18:05 +08:00
parent e81273e944
commit 1ee945447d
12 changed files with 56 additions and 36 deletions

View file

@ -25,7 +25,7 @@ const createdAt = $computed(() => {
</NuxtLink> </NuxtLink>
</div> </div>
<div flex flex-col> <div flex flex-col>
<CommonRichContent font-bold text-2xl :content="getDisplayName(account)" :emojis="account.emojis" /> <ContentRich font-bold text-2xl :content="getDisplayName(account)" :emojis="account.emojis" />
<p op50> <p op50>
{{ getAccountHandle(account) }} {{ getAccountHandle(account) }}
</p> </p>
@ -66,13 +66,13 @@ const createdAt = $computed(() => {
</div> </div>
<div flex gap-5> <div flex gap-5>
<NuxtLink :to="`/${getAccountHandle(account)}/`" active-class="text-primary"> <NuxtLink :to="`/${getAccountHandle(account)}/`" active-class="text-primary">
<span font-bold>{{ account.statusesCount }}</span> Posts <span font-bold>{{ account.statusesCount }}</span> <span op50>Posts</span>
</NuxtLink> </NuxtLink>
<NuxtLink :to="`/${getAccountHandle(account)}/following`" active-class="text-primary"> <NuxtLink :to="`/${getAccountHandle(account)}/following`" active-class="text-primary">
<span font-bold>{{ account.followingCount }}</span> Following <span font-bold>{{ account.followingCount }}</span> <span op50>Following</span>
</NuxtLink> </NuxtLink>
<NuxtLink :to="`/${getAccountHandle(account)}/followers`" active-class="text-primary"> <NuxtLink :to="`/${getAccountHandle(account)}/followers`" active-class="text-primary">
<span font-bold>{{ account.followersCount }}</span> Followers <span font-bold>{{ account.followersCount }}</span> <span op50>Followers</span>
</NuxtLink> </NuxtLink>
</div> </div>
</div> </div>

View file

@ -18,7 +18,7 @@ const id = computed(() => fullServer && !account.acct.includes('@') ? `@${accoun
</NuxtLink> </NuxtLink>
</div> </div>
<NuxtLink flex flex-col :to="link ? getAccountPath(account) : null"> <NuxtLink flex flex-col :to="link ? getAccountPath(account) : null">
<CommonRichContent font-bold :content="getDisplayName(account)" :emojis="account.emojis" /> <ContentRich font-bold :content="getDisplayName(account)" :emojis="account.emojis" />
<p op35 text-sm> <p op35 text-sm>
{{ id }} {{ id }}
</p> </p>

View file

@ -9,6 +9,6 @@ defineProps<{
<template> <template>
<NuxtLink :href="getAccountPath(account)" flex gap-1 items-center> <NuxtLink :href="getAccountPath(account)" flex gap-1 items-center>
<AccountAvatar :account="account" w-5 h-5 /> <AccountAvatar :account="account" w-5 h-5 />
<CommonRichContent :content="getDisplayName(account)" :emojis="account.emojis" /> <ContentRich :content="getDisplayName(account)" :emojis="account.emojis" />
</NuxtLink> </NuxtLink>
</template> </template>

View file

@ -11,7 +11,7 @@ const { paginator } = defineProps<{
<template #default="{ item }"> <template #default="{ item }">
<AccountCard <AccountCard
:account="item" :account="item"
border="b base" p1 border="b base" py2 px4
/> />
</template> </template>
</CommonPaginator> </CommonPaginator>

View file

@ -7,7 +7,12 @@
> >
<div flex justify-between px5 py4> <div flex justify-between px5 py4>
<div flex gap-1> <div flex gap-1>
<slot name="title" /> <slot name="title">
<NuxtLink flex="~ gap1" items-center btn-text p-0 @click="$router.go(-1)">
<div i-ri-arrow-left-line />
Back
</NuxtLink>
</slot>
</div> </div>
<div flex> <div flex>
<slot name="actions" /> <slot name="actions" />

View file

@ -8,6 +8,6 @@ const { status } = defineProps<{
<template> <template>
<div class="status-body"> <div class="status-body">
<CommonRichContent :content="status.content" :emojis="status.emojis" /> <ContentRich :content="status.content" :emojis="status.emojis" />
</div> </div>
</template> </template>

31
pages/@[account].vue Normal file
View file

@ -0,0 +1,31 @@
<script setup lang="ts">
const props = defineProps<{
modelValue?: boolean
}>()
const params = useRoute().params
const accountName = $computed(() => params.account as string)
const account = await fetchAccountByName(accountName)
const tabNames = ['Posts', 'Posts and replies'] as const
// Don't use local storage because it is better to default to Posts every time you visit a user's profile.
const tab = $ref('Posts')
const paginator = $computed(() => {
return masto.accounts.getStatusesIterable(account.id, { excludeReplies: tab === 'Posts' } as any)
})
</script>
<template>
<MainContent>
<template v-if="account">
<AccountHeader :account="account" border="b base" />
<NuxtPage />
</template>
<CommonNotFound v-else>
Account @{{ params.user }} not found
</CommonNotFound>
</MainContent>
</template>

View file

@ -8,13 +8,6 @@ const paginator = account ? masto.accounts.getFollowersIterable(account!.id!, {}
<template> <template>
<template v-if="account"> <template v-if="account">
<div>
<AccountHeader :account="account" />
</div>
<AccountPaginator :paginator="paginator" /> <AccountPaginator :paginator="paginator" />
</template> </template>
<CommonNotFound v-else>
Account @{{ params.user }} not found
</CommonNotFound>
</template> </template>

View file

@ -3,18 +3,11 @@ const params = useRoute().params
const accountName = $computed(() => params.account as string) const accountName = $computed(() => params.account as string)
const account = await fetchAccountByName(accountName) const account = await fetchAccountByName(accountName)
const paginator = account ? masto.accounts.getFollowingIterable(account!.id!, {}) : null const paginator = account ? masto.accounts.getFollowingIterable(account.id, {}) : null
</script> </script>
<template> <template>
<template v-if="account"> <template v-if="account">
<div>
<AccountHeader :account="account" />
</div>
<AccountPaginator :paginator="paginator" /> <AccountPaginator :paginator="paginator" />
</template> </template>
<CommonNotFound v-else>
Account @{{ params.user }} not found
</CommonNotFound>
</template> </template>

View file

@ -12,21 +12,19 @@ const tabNames = ['Posts', 'Posts and replies'] as const
// Don't use local storage because it is better to default to Posts every time you visit a user's profile. // Don't use local storage because it is better to default to Posts every time you visit a user's profile.
const tab = $ref('Posts') const tab = $ref('Posts')
const paginator1 = masto.accounts.getStatusesIterable(account.id, { excludeReplies: true })
const paginator2 = masto.accounts.getStatusesIterable(account.id, { excludeReplies: false })
const paginator = $computed(() => { const paginator = $computed(() => {
return masto.accounts.getStatusesIterable(account.id, { excludeReplies: tab === 'Posts' } as any) return tab === 'Posts' ? paginator1 : paginator2
}) })
</script> </script>
<template> <template>
<template v-if="account">
<div> <div>
<AccountHeader :account="account" />
</div>
<CommonTabs v-model="tab" :options="tabNames" /> <CommonTabs v-model="tab" :options="tabNames" />
<KeepAlive>
<TimelinePaginator :key="tab" :paginator="paginator" /> <TimelinePaginator :key="tab" :paginator="paginator" />
</template> </KeepAlive>
</div>
<CommonNotFound v-else>
Account @{{ params.user }} not found
</CommonNotFound>
</template> </template>

View file

@ -21,7 +21,7 @@ export default defineConfig({
'interact-disabled': 'disabled:opacity-50 disabled:pointer-events-none disabled:saturate-0', 'interact-disabled': 'disabled:opacity-50 disabled:pointer-events-none disabled:saturate-0',
'btn-solid': 'px-4 py-2 rounded text-white bg-$c-primary hover:bg-$c-primary-active interact-disabled', 'btn-solid': 'px-4 py-2 rounded text-white bg-$c-primary hover:bg-$c-primary-active interact-disabled',
'btn-outline': 'px-4 py-2 rounded text-$c-primary border border-$c-primary hover:bg-$c-primary hover:text-white interact-disabled', 'btn-outline': 'px-4 py-2 rounded text-$c-primary border border-$c-primary hover:bg-$c-primary hover:text-white interact-disabled',
'btn-text': 'px-4 py-2 text-$c-primary hover:text-$c-primary-active interact-disabled', 'btn-text': 'px-4 py-2 text-$c-primary hover:text-$c-primary-active interact-disabled cursor-pointer',
}, },
], ],
presets: [ presets: [