personal site
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: embeddable bluesky post

serenity 0091092e cc406a6b

+78
+78
src/components/Bsky/Post.astro
··· 1 + --- 2 + import TablerBrandBluesky from "../Icons/TablerBrandBluesky.astro"; 3 + 4 + interface Props { 5 + pdsUrl: string; 6 + repoDid: string; 7 + rkey: string; 8 + } 9 + 10 + const { pdsUrl, repoDid, rkey } = Astro.props; 11 + const postRes = await fetch( 12 + `${pdsUrl}/xrpc/com.atproto.repo.getRecord?repo=${repoDid}&collection=app.bsky.feed.post&rkey=${rkey}` 13 + ); 14 + const profileRes = await fetch( 15 + `${pdsUrl}/xrpc/com.atproto.repo.getRecord?repo=${repoDid}&collection=app.bsky.actor.profile&rkey=self` 16 + ); 17 + const miniDocRes = await fetch( 18 + `https://slingshot.microcosm.blue/xrpc/blue.microcosm.identity.resolveMiniDoc?identifier=${repoDid}` 19 + ); 20 + 21 + const postData = (await postRes.json()) as { 22 + uri: string; 23 + cid: string; 24 + value: { text: string }; 25 + }; 26 + 27 + const profileData = (await profileRes.json()) as { 28 + uri: string; 29 + cid: string; 30 + value: { 31 + avatar: { ref: { $link: string }; mimeType: string }; 32 + banner: { ref: { $link: string }; mimeType: string }; 33 + displayName: string; 34 + }; 35 + }; 36 + 37 + const miniDocData = (await miniDocRes.json()) as { 38 + did: string; 39 + handle: string; 40 + }; 41 + 42 + const avatarBlobSrc = `${pdsUrl}/xrpc/com.atproto.sync.getBlob?did=${repoDid}&cid=${profileData.value.avatar.ref.$link}`; 43 + const bannerBlobSrc = `${pdsUrl}/xrpc/com.atproto.sync.getBlob?did=${repoDid}&cid=${profileData.value.banner.ref.$link}`; 44 + 45 + const { value } = postData; 46 + const { text: postText } = value; 47 + --- 48 + 49 + <div 50 + class="to-glw-base flex flex-col gap-1 rounded-lg bg-linear-to-b bg-cover p-4 font-sans" 51 + style={`background-image: linear-gradient(#282001C0, #060400FF), url(${bannerBlobSrc})`} 52 + > 53 + <div class="flex justify-between items-center mb-4"> 54 + <a 55 + class="flex items-center gap-2" 56 + href={`https://catsky.social/profile/${miniDocData.handle}`} 57 + style="text-decoration: none;" 58 + > 59 + <img 60 + src={avatarBlobSrc} 61 + height="48" 62 + width="48" 63 + class="mt-0 mb-0 rounded-full" 64 + style="border-radius: calc(infinity * 1px);" 65 + /> 66 + <div class="flex flex-col"> 67 + <span class="text-glw-text text-lg font-semibold no-underline"> 68 + {profileData.value.displayName}</span 69 + > 70 + <span class="text-glw-text font-mono text-sm no-underline"> 71 + @{miniDocData.handle} 72 + </span> 73 + </div> 74 + </a> 75 + <TablerBrandBluesky class="text-3xl text-glw-blue"/> 76 + </div> 77 + <span class="text-glw-text mt-0 mb-0 whitespace-pre-wrap">{postText}</span> 78 + </div>