1<script setup lang="ts">
2import type { AppBskyFeedDefs } from "@atcute/bluesky";
3import { extractPostId } from "~/util/atproto";
4
5const props = defineProps<{
6 post: AppBskyFeedDefs.ThreadViewPost;
7 depth: number;
8}>();
9const { post, depth } = toRefs(props);
10
11const MAX_DEPTH = 3; // Max number of replies to a reply
12
13console.log(post);
14</script>
15
16<template>
17<div v-if="post && depth < MAX_DEPTH" class="mt-6 bsky-post">
18 <a :href="`https://bsky.app/profile/${post.post.author.handle}`">
19 <img :src="post.post.author.avatar" :alt="post.post.author.displayName" class="size-8 rounded-full" />
20 </a>
21 <div class="flex flex-col gap-1">
22 <a :href="`https://bsky.app/profile/${post.post.author.handle}`" class="text-md font-bold w-fit">
23 {{ post.post.author.displayName }}
24 </a>
25 <div>
26 {{ post.post.record.text }}
27 </div>
28 <div class="flex items-baseline gap-4 mt-2">
29 <p class="text-gray-500 text-sm" title="Replies">
30 <Icon name="ri:reply-line" class="-mb-[2px] mr-1" />
31 {{post.post.replyCount}}
32 </p>
33 <p class="text-gray-500 text-sm" title="Likes">
34 <Icon name="ri:heart-3-line" class="-mb-[2px] mr-1" />
35 <span>
36 {{post.post.likeCount}}
37 </span>
38 </p>
39 <p class="text-gray-500 text-sm" title="Bookmarks">
40 <Icon name="ri:bookmark-line" class="-mb-[2px] mr-1" />
41 {{post.post.bookmarkCount}}
42 </p>
43 </div>
44
45 <div v-if="post.replies && post.replies.length > 0">
46 <div v-if="depth+1 === MAX_DEPTH">
47 <a :href="`https://bsky.app/profile/${post.post.author.handle}/post/${extractPostId(post.post.uri)}`" class="text-gray-500 text-sm flex items-center gap-2 mt-4">
48 View more replies on Bluesky
49 <Icon name='ri:arrow-drop-right-line' />
50 </a>
51 </div>
52 <div v-else v-for="reply in post.replies">
53 <BskyPost v-if="reply.$type === 'app.bsky.feed.defs#threadViewPost'" :post="reply" :depth="depth + 1" />
54 </div>
55 </div>
56 </div>
57</div>
58</template>
59
60<style scoped>
61.bsky-post {
62 @apply gap-2 md:gap-4;
63
64 display: grid;
65 grid-template-columns: auto 1fr;
66 grid-template-areas:
67 "avatar content";
68 align-items: start;
69
70 & > a:has(> img) {
71 grid-area: avatar;
72 }
73
74 & > div {
75 grid-area: content;
76 }
77
78}
79</style>