diff --git a/src/hooks/useCrews.ts b/src/hooks/useCrews.ts index 324fd27..295e478 100644 --- a/src/hooks/useCrews.ts +++ b/src/hooks/useCrews.ts @@ -90,6 +90,14 @@ export function useCrew(identifier: string, pubkey?: string) { queryFn: async () => { const signal = AbortSignal.timeout(10000); + const pickMostRecent = (events: { created_at: number }[]) => + events.length + ? events.reduce((latest, current) => + current.created_at > latest.created_at ? current : latest + ) + : undefined; + + // 1) Precise addressable lookup: kind + d-tag (+ author when known). const filter: { kinds: number[]; '#d': string[]; @@ -102,14 +110,25 @@ export function useCrew(identifier: string, pubkey?: string) { }; if (pubkey) filter.authors = [pubkey]; - const events = await querySkateContent([filter], { signal }); - if (events.length === 0) return null; + let events = await querySkateContent([filter], { signal }); - const mostRecent = events.reduce((latest, current) => - current.created_at > latest.created_at ? current : latest - ); + // 2) Fallback: some relays don't index the `d` tag reliably (or choke on + // combined author + tag filters). If nothing came back and we know the + // author, fetch that author's crews and match the identifier locally. + if (events.length === 0 && pubkey) { + const byAuthor = await querySkateContent( + [{ kinds: [SKATE_CREW_KIND], authors: [pubkey], limit: 200 }], + { signal } + ); + events = byAuthor.filter((e) => + e.tags.some(([name, value]) => name === 'd' && value === identifier) + ); + } - return parseSkateCrew(mostRecent); + const mostRecent = pickMostRecent(events); + if (!mostRecent) return null; + + return parseSkateCrew(mostRecent as typeof events[number]); }, enabled: !!identifier, staleTime: 5 * 60 * 1000,