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>