this repo has no description

Merge remote-tracking branch 'origin/SvelteStuff' into astra/style

astrra.space 2a355be5 dcca38a9

verified
+25
deno.lock
··· 3 3 "specifiers": { 4 4 "npm:@atcute/bluesky@^2.0.2": "2.0.2_@atcute+client@3.0.1", 5 5 "npm:@atcute/client@^3.0.1": "3.0.1", 6 + "npm:@atcute/identity-resolver@~0.1.2": "0.1.2_@atcute+identity@0.1.3", 6 7 "npm:@sveltejs/vite-plugin-svelte@^5.0.3": "5.0.3_svelte@5.28.1__acorn@8.14.1_vite@6.3.2__picomatch@4.0.2", 7 8 "npm:@tsconfig/svelte@^5.0.4": "5.0.4", 8 9 "npm:svelte-check@^4.1.5": "4.1.6_svelte@5.28.1__acorn@8.14.1_typescript@5.7.3", ··· 26 27 }, 27 28 "@atcute/client@3.0.1": { 28 29 "integrity": "sha512-j51SuQYQj5jeKrx1DCXx+Q3fpVvO0JYGnKnJAdDSlesSLjPXjvnx1abC+hkuro58KRHHJvRA6P1MC0pmJsWfcg==" 30 + }, 31 + "@atcute/identity-resolver@0.1.2_@atcute+identity@0.1.3": { 32 + "integrity": "sha512-fP2VbHD04kVcCdNi/Kszo6jFzqM7Pg3p33oGhfp2zVkwFKaVBlwCaFRWEga/Xvu/IDLwNdASGWnLqoA34SFeSg==", 33 + "dependencies": [ 34 + "@atcute/identity", 35 + "@atcute/util-fetch", 36 + "@badrap/valita" 37 + ] 38 + }, 39 + "@atcute/identity@0.1.3": { 40 + "integrity": "sha512-ndlD8nypHt8G00wixbozKdSNL0O8HTzBjFGEXeAcBUCXSZPBjRWbqtgyJxhgUWnr7swgxgw1mSbZwRB5b7xCiQ==", 41 + "dependencies": [ 42 + "@badrap/valita" 43 + ] 44 + }, 45 + "@atcute/util-fetch@1.0.1": { 46 + "integrity": "sha512-Clc0E/5ufyGBVfYBUwWNlHONlZCoblSr4Ho50l1LhmRPGB1Wu/AQ9Sz+rsBg7fdaW/auve8ulmwhRhnX2cGRow==", 47 + "dependencies": [ 48 + "@badrap/valita" 49 + ] 50 + }, 51 + "@badrap/valita@0.4.4": { 52 + "integrity": "sha512-GEhUCk9c4XbNxi+0YZHZsV4fYNd6HejfWuN4Ti4c02DauX+LyX5WY1Y3WfyZ8Pxxl0zqhs+MLtW98cMh86vv6g==" 29 53 }, 30 54 "@esbuild/aix-ppc64@0.25.2": { 31 55 "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==" ··· 443 467 "dependencies": [ 444 468 "npm:@atcute/bluesky@^2.0.2", 445 469 "npm:@atcute/client@^3.0.1", 470 + "npm:@atcute/identity-resolver@~0.1.2", 446 471 "npm:@sveltejs/vite-plugin-svelte@^5.0.3", 447 472 "npm:@tsconfig/svelte@^5.0.4", 448 473 "npm:svelte-check@^4.1.5",
+2 -1
package.json
··· 11 11 }, 12 12 "dependencies": { 13 13 "@atcute/bluesky": "^2.0.2", 14 - "@atcute/client": "^3.0.1" 14 + "@atcute/client": "^3.0.1", 15 + "@atcute/identity-resolver": "^0.1.2" 15 16 }, 16 17 "devDependencies": { 17 18 "@sveltejs/vite-plugin-svelte": "^5.0.3",
+16 -5
src/lib/PostComponent.svelte
··· 13 13 alt="avatar of {post.displayName}" 14 14 /> 15 15 {/if} 16 - <div id="headerText">{post.displayName} | {post.timenotstamp}</div> 16 + <div id="headerText">{post.displayName} | {post.authorHandle} | {post.timenotstamp}</div> 17 17 </div> 18 18 <div id="postContent"> 19 - {#if post.replyingDid} 20 - <p id="replyingText">replying to: {post.replyingDid}</p> 21 - {/if} 22 - <p id="postText">{post.text}</p> 19 + <p>{post.text}</p> 20 + {#if post.replyingUri} 21 + <a 22 + id="replyingText" 23 + href="https://deer.social/profile/{post.replyingUri.repo}/post/{post 24 + .replyingUri.rkey}">replying to {post.replyingUri.repo}</a 25 + > 26 + {/if} 27 + {#if post.quotingUri} 28 + <a 29 + id="quotingText" 30 + href="https://deer.social/profile/{post.quotingUri.repo}/post/{post 31 + .quotingUri.rkey}">quoting {post.quotingUri.repo}</a 32 + > 33 + {/if} 23 34 {#if post.imagesCid} 24 35 <div id="imagesContainer"> 25 36 {#each post.imagesCid as imageLink}
+66 -10
src/lib/pdsfetch.ts
··· 2 2 import "@atcute/bluesky/lexicons"; 3 3 import type { 4 4 AppBskyActorDefs, 5 + AppBskyActorProfile, 5 6 AppBskyFeedPost, 7 + At, 6 8 ComAtprotoRepoListRecords, 7 9 } from "@atcute/client/lexicons"; 10 + import { 11 + CompositeDidDocumentResolver, 12 + PlcDidDocumentResolver, 13 + WebDidDocumentResolver, 14 + } from "@atcute/identity-resolver"; 8 15 import { Config } from "../../config"; 9 16 // import { ComAtprotoRepoListRecords.Record } from "@atcute/client/lexicons"; 10 17 // import { AppBskyFeedPost } from "@atcute/client/lexicons"; ··· 13 20 interface AccountMetadata { 14 21 did: string; 15 22 displayName: string; 23 + handle: string; 16 24 avatarCid: string | null; 17 25 } 26 + interface atUriObject { 27 + repo: string; 28 + collection: string; 29 + rkey: string; 30 + } 18 31 class Post { 19 32 authorDid: string; 20 33 authorAvatarCid: string | null; 34 + authorHandle: string; 21 35 displayName: string; 22 36 text: string; 23 37 timestamp: number; 24 38 timenotstamp: string; 25 - quotingDid: string | null; 26 - replyingDid: string | null; 39 + quotingUri: atUriObject | null; 40 + replyingUri: atUriObject | null; 27 41 imagesCid: string[] | null; 28 42 videosLinkCid: string | null; 29 43 ··· 33 47 ) { 34 48 this.authorDid = account.did; 35 49 this.authorAvatarCid = account.avatarCid; 50 + this.authorHandle = account.handle; 36 51 this.displayName = account.displayName; 37 52 const post = record.value as AppBskyFeedPost.Record; 38 53 this.timenotstamp = post.createdAt; 39 54 this.text = post.text; 40 55 this.timestamp = Date.parse(post.createdAt); 41 56 if (post.reply) { 42 - this.replyingDid = didFromATuri(post.reply.parent.uri).repo; 57 + this.replyingUri = processAtUri(post.reply.parent.uri); 43 58 } else { 44 - this.replyingDid = null; 59 + this.replyingUri = null; 45 60 } 46 - this.quotingDid = null; 61 + this.quotingUri = null; 47 62 this.imagesCid = null; 48 63 this.videosLinkCid = null; 49 64 switch (post.embed?.$type) { ··· 56 71 this.videosLinkCid = post.embed.video.ref.$link; 57 72 break; 58 73 case "app.bsky.embed.record": 59 - this.quotingDid = didFromATuri(post.embed.record.uri).repo; 74 + this.quotingUri = processAtUri(post.embed.record.uri); 60 75 break; 61 76 case "app.bsky.embed.recordWithMedia": 62 - this.quotingDid = didFromATuri(post.embed.record.record.uri).repo; 77 + this.quotingUri = processAtUri(post.embed.record.record.uri); 63 78 switch (post.embed.media.$type) { 64 79 case "app.bsky.embed.images": 65 80 this.imagesCid = post.embed.media.images.map((imageRecord) => ··· 77 92 } 78 93 } 79 94 80 - const didFromATuri = (aturi: string) => { 95 + const processAtUri = (aturi: string): atUriObject => { 81 96 const parts = aturi.split("/"); 82 97 return { 83 98 repo: parts[2], ··· 108 123 rkey: "self", 109 124 }, 110 125 }); 111 - const value = data.value as AppBskyActorDefs.ProfileView; 126 + const value = data.value as AppBskyActorProfile.Record; 127 + const handle = await blueskyHandleFromDid(did); 112 128 const account: AccountMetadata = { 113 129 did: did, 130 + handle: handle, 114 131 displayName: value.displayName || "", 115 132 avatarCid: null, 116 133 }; ··· 143 160 try { 144 161 const { data } = await rpc.get("com.atproto.repo.listRecords", { 145 162 params: { 146 - repo: did, 163 + repo: did as At.Identifier, 147 164 collection: "app.bsky.feed.post", 148 165 limit: 5, 149 166 }, ··· 163 180 } 164 181 }; 165 182 183 + const identityResolve = async (did: At.Did) => { 184 + const resolver = new CompositeDidDocumentResolver({ 185 + methods: { 186 + plc: new PlcDidDocumentResolver(), 187 + web: new WebDidDocumentResolver(), 188 + }, 189 + }); 190 + 191 + if (did.startsWith("did:plc:") || did.startsWith("did:web:")) { 192 + const doc = await resolver.resolve( 193 + did as `did:plc:${string}` | `did:web:${string}`, 194 + ); 195 + return doc; 196 + } else { 197 + throw new Error(`Unsupported DID type: ${did}`); 198 + } 199 + }; 200 + 201 + const blueskyHandleFromDid = async (did: At.Did) => { 202 + const doc = await identityResolve(did); 203 + if (doc.alsoKnownAs) { 204 + const handleAtUri = doc.alsoKnownAs.find((url) => url.startsWith("at://")); 205 + const handle = handleAtUri?.split("/")[2]; 206 + if (!handle) { 207 + return "Handle not found"; 208 + } else { 209 + return handle; 210 + } 211 + } else { 212 + return "Handle not found"; 213 + } 214 + }; 215 + 166 216 const fetchAllPosts = async () => { 167 217 const users: AccountMetadata[] = await getAllMetadataFromPds(); 168 218 const postRecords = await Promise.all( ··· 186 236 return posts; 187 237 }; 188 238 239 + const testApiCall = async () => { 240 + const { data } = await rpc.get("com.atproto.sync.listRepos", { 241 + params: {}, 242 + }); 243 + console.log(data); 244 + }; 189 245 export { fetchAllPosts, getAllMetadataFromPds, Post }; 190 246 export type { AccountMetadata };