test card

This commit is contained in:
2026-01-21 00:48:00 +09:00
parent b2f36073ec
commit 968ea019a6
8 changed files with 696 additions and 18 deletions

View File

@@ -1,5 +1,5 @@
import { xrpcUrl, comAtprotoIdentity, comAtprotoRepo } from '../lexicons'
import type { AppConfig, Networks, Profile, Post, ListRecordsResponse, ChatMessage } from '../types'
import type { AppConfig, Networks, Profile, Post, ListRecordsResponse, ChatMessage, CardCollection } from '../types'
// Cache
let configCache: AppConfig | null = null
@@ -428,3 +428,37 @@ export async function getChatMessages(
new Date(a.value.createdAt).getTime() - new Date(b.value.createdAt).getTime()
)
}
// Get user's card collection (ai.syui.card.user)
export async function getCards(
did: string,
collection: string = 'ai.syui.card.user'
): Promise<CardCollection | null> {
// Try local first
try {
const res = await fetch(`/content/${did}/${collection}/self.json`)
if (res.ok && isJsonResponse(res)) {
const record = await res.json()
return record.value as CardCollection
}
} catch {
// Try remote
}
// Remote fallback
const pds = await getPds(did)
if (!pds) return null
try {
const host = pds.replace('https://', '')
const url = `${xrpcUrl(host, comAtprotoRepo.getRecord)}?repo=${did}&collection=${collection}&rkey=self`
const res = await fetch(url)
if (res.ok) {
const record = await res.json()
return record.value as CardCollection
}
} catch {
// Failed
}
return null
}

View File

@@ -1,5 +1,5 @@
export interface Route {
type: 'home' | 'user' | 'post' | 'postpage' | 'atbrowser' | 'service' | 'collection' | 'record' | 'chat' | 'chat-thread'
type: 'home' | 'user' | 'post' | 'postpage' | 'atbrowser' | 'service' | 'collection' | 'record' | 'chat' | 'chat-thread' | 'card'
handle?: string
rkey?: string
service?: string
@@ -51,6 +51,12 @@ export function parseRoute(): Route {
return { type: 'postpage', handle: postPageMatch[1] }
}
// Card page: /@handle/at/card
const cardMatch = path.match(/^\/@([^/]+)\/at\/card\/?$/)
if (cardMatch) {
return { type: 'card', handle: cardMatch[1] }
}
// Chat thread: /@handle/at/chat/{rkey}
const chatThreadMatch = path.match(/^\/@([^/]+)\/at\/chat\/([^/]+)$/)
if (chatThreadMatch) {
@@ -91,6 +97,8 @@ export function navigate(route: Route): void {
path = `/@${route.handle}/at/collection/${route.collection}`
} else if (route.type === 'record' && route.handle && route.collection && route.rkey) {
path = `/@${route.handle}/at/collection/${route.collection}/${route.rkey}`
} else if (route.type === 'card' && route.handle) {
path = `/@${route.handle}/at/card`
} else if (route.type === 'chat' && route.handle) {
path = `/@${route.handle}/at/chat`
} else if (route.type === 'chat-thread' && route.handle && route.rkey) {