43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import { describeRepo, getServiceInfo, resolveHandle } from '../lib/api.js'
|
|
|
|
export async function renderServices(handle: string): Promise<string> {
|
|
const did = handle.startsWith('did:') ? handle : await resolveHandle(handle)
|
|
const collections = await describeRepo(did)
|
|
|
|
if (collections.length === 0) {
|
|
return ''
|
|
}
|
|
|
|
// Group by service
|
|
const serviceMap = new Map<string, { name: string; favicon: string; collections: string[] }>()
|
|
|
|
for (const col of collections) {
|
|
const info = getServiceInfo(col)
|
|
if (info) {
|
|
const key = info.domain
|
|
if (!serviceMap.has(key)) {
|
|
serviceMap.set(key, { name: info.name, favicon: info.favicon, collections: [] })
|
|
}
|
|
serviceMap.get(key)!.collections.push(col)
|
|
}
|
|
}
|
|
|
|
const items = Array.from(serviceMap.entries()).map(([domain, info]) => {
|
|
const url = `/at/${handle}/${domain}`
|
|
|
|
return `
|
|
<a href="${url}" class="service-item" title="${info.collections.join(', ')}">
|
|
<img src="${info.favicon}" class="service-favicon" alt="" onerror="this.style.display='none'">
|
|
<span class="service-name">${info.name}</span>
|
|
</a>
|
|
`
|
|
}).join('')
|
|
|
|
return `<div class="services">${items}</div>`
|
|
}
|
|
|
|
export async function mountServices(container: HTMLElement, handle: string): Promise<void> {
|
|
const html = await renderServices(handle)
|
|
container.innerHTML = html
|
|
}
|