feat: basic conversations (#15)
This commit is contained in:
parent
4fc6e405e0
commit
1aa81a3a0a
14
components/account/AccountInlineInfo.vue
Normal file
14
components/account/AccountInlineInfo.vue
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Account } from 'masto'
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
account: Account
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a :href="`/@${account.acct}`" flex gap-2 font-bold items-center>
|
||||||
|
<img :src="account.avatar" class="w-5 h-5 rounded">
|
||||||
|
{{ account.displayName }}
|
||||||
|
</a>
|
||||||
|
</template>
|
17
components/conversation/ConversationCard.vue
Normal file
17
components/conversation/ConversationCard.vue
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Conversation } from 'masto'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
conversation: Conversation
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div flex flex-col gap-2>
|
||||||
|
<div flex gap-2>
|
||||||
|
With
|
||||||
|
<AccountInlineInfo v-for="account in conversation.accounts" :key="account.id" :account="account" />
|
||||||
|
</div>
|
||||||
|
<StatusCard v-if="conversation.lastStatus" :status="conversation.lastStatus" :actions="false" />
|
||||||
|
</div>
|
||||||
|
</template>
|
21
components/conversation/ConversationPaginator.client.vue
Normal file
21
components/conversation/ConversationPaginator.client.vue
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Conversation, Paginator } from 'masto'
|
||||||
|
|
||||||
|
const { paginator } = defineProps<{
|
||||||
|
paginator: Paginator<any, Conversation[]>
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<CommonPaginator
|
||||||
|
:paginator="paginator"
|
||||||
|
border="t border"
|
||||||
|
>
|
||||||
|
<template #default="{ item }">
|
||||||
|
<ConversationCard
|
||||||
|
:conversation="item"
|
||||||
|
border="b border" py-1
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</CommonPaginator>
|
||||||
|
</template>
|
|
@ -27,9 +27,9 @@ const isLogin = useLoginState()
|
||||||
<span>Federated</span>
|
<span>Federated</span>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<template v-if="isLogin">
|
<template v-if="isLogin">
|
||||||
<NuxtLink flex gap2 items-center active-class="text-primary">
|
<NuxtLink flex gap2 items-center to="/conversations" active-class="text-primary">
|
||||||
<div i-ri:at-line />
|
<div i-ri:at-line />
|
||||||
<span>Messages</span>
|
<span>Conversations</span>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink flex gap2 items-center to="/favourites" active-class="text-primary">
|
<NuxtLink flex gap2 items-center to="/favourites" active-class="text-primary">
|
||||||
<div i-ri:heart-3-line />
|
<div i-ri:heart-3-line />
|
||||||
|
|
|
@ -24,11 +24,8 @@ const router = useRouter()
|
||||||
|
|
||||||
function go(e: MouseEvent) {
|
function go(e: MouseEvent) {
|
||||||
const path = e.composedPath() as HTMLElement[]
|
const path = e.composedPath() as HTMLElement[]
|
||||||
const hasButton = path.find(el => ['A', 'BUTTON', 'P'].includes(el.tagName.toUpperCase()))
|
const el = path.find(el => ['A', 'BUTTON', 'P'].includes(el.tagName?.toUpperCase()))
|
||||||
if (hasButton)
|
if (!el || el.tagName.toUpperCase() === 'P')
|
||||||
return
|
|
||||||
|
|
||||||
if (path.find(i => i === el.value))
|
|
||||||
router.push(`/@${status.account.acct}/${status.id}`)
|
router.push(`/@${status.account.acct}/${status.id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,10 +67,7 @@ const timeago = useTimeAgo(() => status.createdAt, {
|
||||||
<div v-if="rebloggedBy" pl8>
|
<div v-if="rebloggedBy" pl8>
|
||||||
<div flex gap-1 items-center text-gray:75 text-sm>
|
<div flex gap-1 items-center text-gray:75 text-sm>
|
||||||
<div i-ri:repeat-fill mr-1 />
|
<div i-ri:repeat-fill mr-1 />
|
||||||
<a :href="`/@${rebloggedBy.acct}`" flex gap-2 font-bold items-center>
|
<AccountInlineInfo :account="rebloggedBy" />
|
||||||
<img :src="rebloggedBy.avatar" class="w-5 h-5 rounded">
|
|
||||||
{{ rebloggedBy.displayName }}
|
|
||||||
</a>
|
|
||||||
reblogged
|
reblogged
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,10 +12,11 @@ const { data: context } = await useAsyncData(`${id}-context`, () => masto.status
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<template v-for="comment of context?.ancestors" :key="comment.id">
|
||||||
|
<StatusCard :status="comment" border="t border" pt-4 />
|
||||||
|
</template>
|
||||||
<StatusDetails :status="status" />
|
<StatusDetails :status="status" />
|
||||||
<template v-for="comment of context?.descendants" :key="comment.id">
|
<template v-for="comment of context?.descendants" :key="comment.id">
|
||||||
<StatusCard :status="comment" border="t border" pt-4 />
|
<StatusCard :status="comment" border="t border" pt-4 />
|
||||||
</template>
|
</template>
|
||||||
<pre>{{ status }}</pre>
|
|
||||||
<pre>{{ context }}</pre>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
22
pages/conversations.vue
Normal file
22
pages/conversations.vue
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
middleware: 'auth',
|
||||||
|
})
|
||||||
|
|
||||||
|
const masto = await useMasto()
|
||||||
|
const paginator = masto.conversations.getIterator()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MainContent>
|
||||||
|
<template #title>
|
||||||
|
<div i-ri:at-line h-6 mr-1 /><span>Conversations</span>
|
||||||
|
</template>
|
||||||
|
<template #actions>
|
||||||
|
<div color-gray i-ri:equalizer-fill mr-1 h-6 />
|
||||||
|
</template>
|
||||||
|
<slot>
|
||||||
|
<ConversationPaginator :paginator="paginator" />
|
||||||
|
</slot>
|
||||||
|
</MainContent>
|
||||||
|
</template>
|
Loading…
Reference in a new issue