Personal blog finxol.io
blog

fix: max depth truncate + post elements alignment

finxol.io 1bccc71c 376a6d04

verified
+66 -85
+7 -53
app/components/BskyComments.vue
··· 62 62 <div>No replies yet!</div> 63 63 </div> 64 64 65 - <div v-else v-for="reply in post.replies" class="mt-6"> 66 - <BskyPost :post="reply" :depth="0" /> 67 - 68 - <!-- <a :href="`https://bsky.app/profile/${reply.post.author.handle}`" class="flex items-center gap-2 text-blue-500 hover:underline w-fit"> 69 - <img :src="reply.post.author.avatar" :alt="reply.post.author.displayName" class="size-8 rounded-full" /> 70 - <span> 71 - {{ reply.post.author.displayName }} 72 - </span> 73 - </a> 74 - <div class="ml-10">{{ reply.post.record.text }}</div> 75 - <div class="flex items-baseline gap-4 ml-10 mt-2"> 76 - <p class="text-gray-500 text-sm" title="Replies"> 77 - <Icon name="ri:reply-line" class="-mb-[2px] mr-1" /> 78 - {{reply.post.replyCount}} 79 - </p> 80 - <p class="text-gray-500 text-sm" title="Likes"> 81 - <Icon name="ri:heart-3-line" class="-mb-[2px] mr-1" /> 82 - <span> 83 - {{reply.post.likeCount}} 84 - </span> 85 - </p> 86 - <p class="text-gray-500 text-sm" title="Bookmarks"> 87 - <Icon name="ri:bookmark-line" class="-mb-[2px] mr-1" /> 88 - {{reply.post.bookmarkCount}} 89 - </p> 90 - </div> 91 - 92 - <div v-for="rep in reply.replies" class="mt-6 ml-10"> 93 - <a :href="`https://bsky.app/profile/${rep.post.author.handle}`" class="flex items-center gap-2 text-blue-500 hover:underline w-fit"> 94 - <img :src="rep.post.author.avatar" :alt="rep.post.author.displayName" class="size-8 rounded-full" /> 95 - <span> 96 - {{ rep.post.author.displayName }} 97 - </span> 98 - </a> 99 - <div class="ml-10">{{ rep.post.record.text }}</div> 100 - <div class="flex items-baseline gap-4 ml-10 mt-2"> 101 - <p class="text-gray-500 text-sm" title="Replies"> 102 - <Icon name="ri:reply-line" class="-mb-[2px] mr-1" /> 103 - {{rep.post.replyCount}} 104 - </p> 105 - <p class="text-gray-500 text-sm" title="Likes"> 106 - <Icon name="ri:heart-3-line" class="-mb-[2px] mr-1" /> 107 - <span> 108 - {{rep.post.likeCount}} 109 - </span> 110 - </p> 111 - <p class="text-gray-500 text-sm" title="Bookmarks"> 112 - <Icon name="ri:bookmark-line" class="-mb-[2px] mr-1" /> 113 - {{rep.post.bookmarkCount}} 114 - </p> 115 - </div> 116 - </div> --> 117 - </div> 65 + <BskyPost 66 + v-else 67 + v-for="reply in post.replies" 68 + :key="reply.post.cid" 69 + :post="reply" 70 + :depth="0" 71 + /> 118 72 </div> 119 73 </div> 120 74 </template>
+59 -32
app/components/BskyPost.vue
··· 8 8 }>(); 9 9 const { post, depth } = toRefs(props); 10 10 11 - const MAX_DEPTH = 2; // Max number of replies to a reply 11 + const MAX_DEPTH = 3; // Max number of replies to a reply 12 + 13 + console.log(post); 12 14 </script> 13 15 14 16 <template> 15 - <div v-if="post && depth <= MAX_DEPTH" :class="['mt-6', depth > 0 ? 'ml-10' : '']"> 16 - <a :href="`https://bsky.app/profile/${post.post.author.handle}`" class="flex items-center gap-2 text-blue-500 hover:underline w-fit"> 17 + <div v-if="post && depth < MAX_DEPTH" class="mt-6 bsky-post"> 18 + <a :href="`https://bsky.app/profile/${post.post.author.handle}`"> 17 19 <img :src="post.post.author.avatar" :alt="post.post.author.displayName" class="size-8 rounded-full" /> 18 - <span> 19 - {{ post.post.author.displayName }} 20 - </span> 21 20 </a> 22 - <div class="ml-10">{{ post.post.record.text }}</div> 23 - <div class="flex items-baseline gap-4 ml-10 mt-2"> 24 - <p class="text-gray-500 text-sm" title="Replies"> 25 - <Icon name="ri:reply-line" class="-mb-[2px] mr-1" /> 26 - {{post.post.replyCount}} 27 - </p> 28 - <p class="text-gray-500 text-sm" title="Likes"> 29 - <Icon name="ri:heart-3-line" class="-mb-[2px] mr-1" /> 30 - <span> 31 - {{post.post.likeCount}} 32 - </span> 33 - </p> 34 - <p class="text-gray-500 text-sm" title="Bookmarks"> 35 - <Icon name="ri:bookmark-line" class="-mb-[2px] mr-1" /> 36 - {{post.post.bookmarkCount}} 37 - </p> 38 - </div> 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> 39 44 40 - <div v-if="post.replies"> 41 - <div v-if="depth === MAX_DEPTH"> 42 - <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 ml-10"> 43 - View more replies on Bluesky 44 - <Icon name='ri:arrow-drop-right-line' /> 45 - </a> 46 - </div> 47 - <div v-for="reply in post.replies"> 48 - <BskyPost v-if="reply.$type === 'app.bsky.feed.defs#threadViewPost'" :post="reply" :depth="depth + 1" /> 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> 49 55 </div> 50 56 </div> 51 57 </div> 52 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>