feat: retrieve images

This commit is contained in:
Julien Calixte
2026-02-14 00:17:16 +01:00
parent 7ab4d64dea
commit 33eeb9ae02
2 changed files with 36 additions and 10 deletions

View File

@@ -1,27 +1,33 @@
const correspondanceCache = new Map<string, string>()
type Author = { alias: string; endpoint: string }
export const getUniqueAka = async (did: string) => {
const correspondanceCache = new Map<string, Author>()
export const getUniqueAka = async (did: string): Promise<Author> => {
console.log(correspondanceCache)
if (correspondanceCache.has(did)) {
return correspondanceCache.get(did) as string
return correspondanceCache.get(did) as Author
}
const response = await fetch(`https://plc.directory/${did}`)
const {
alsoKnownAs: [aka],
service: [{ serviceEndpoint }],
} = await response.json()
const alias = aka.replace("at://", "")
const author = { alias, endpoint: serviceEndpoint }
correspondanceCache.set(did, alias)
correspondanceCache.set(did, author)
console.log(correspondanceCache)
return alias
return author
}
export const getAka = async (dids: Set<string>) => {
const correspondance = await Promise.all(
[...dids].map(async (did) => {
if (correspondanceCache.has(did)) {
return [did, correspondanceCache.get(did)!] as [string, string]
return [did, correspondanceCache.get(did)?.alias] as [string, string]
}
const response = await fetch(`https://plc.directory/${did}`)

View File

@@ -42,7 +42,7 @@ const did = computed(() => props.did)
const rkey = computed(() => props.rkey)
const { scrollToFocusedNote } = useRouteQueryStackedNotes()
const alias = computedAsync(async () => getUniqueAka(did.value))
const author = computedAsync(async () => getUniqueAka(did.value))
const url = computedAsync(async () =>
getUrl({ did: did.value, rkey: rkey.value }),
)
@@ -50,11 +50,27 @@ const rawContent = computedAsync(async () =>
url.value ? ((await fetch(url.value).then()).json() as Promise<Root>) : null,
)
const { toHTML } = markdownBuilder()
const withATProtoImages = (markdown: string) => {
if (!author.value) {
return markdown
}
const endpoint = author.value.endpoint
const imageLinkPattern = /!\[([^\]]*)\]\((bafkrei[a-z0-9]+)\)/g
return markdown.replace(imageLinkPattern, (_, altText, cid) => {
const imageUrl = new URL("/xrpc/com.atproto.sync.getBlob", endpoint)
imageUrl.searchParams.set("did", did.value)
imageUrl.searchParams.set("cid", cid)
return `![${altText}](${imageUrl.toString()})`
})
}
const title = computed(() => rawContent.value?.value.title)
const content = computed(() =>
rawContent.value?.value.content
? toHTML(rawContent.value?.value.content)
? toHTML(withATProtoImages(rawContent.value?.value.content))
: "",
)
</script>
@@ -66,11 +82,11 @@ const content = computed(() =>
<a
class="title-stacked-note-link"
@click.prevent="scrollToFocusedNote()"
v-if="alias && title"
v-if="author && title"
>{{ title }}</a
>
</div>
<span class="badge badge-accent">{{ alias }}</span>
<span class="badge badge-accent" v-if="author">{{ author.alias }}</span>
<article v-html="content"></article>
</div>
</div>
@@ -81,6 +97,10 @@ const content = computed(() =>
display: flex;
flex: 1;
.badge {
margin-bottom: 1rem;
}
.article {
position: sticky;
left: 0;