SkateSpots/src/hooks/useAuthor.ts
shakespeare.diy a6c220c911 Increase useAuthor timeout and retries for Capacitor WebView
WebSocket connections take longer to establish on first load in
Capacitor. Increase timeout from 8s to 15s and retries from 3 to 5.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 13:34:18 +07:00

66 lines
2.1 KiB
TypeScript

import { type NostrEvent, type NostrMetadata, NSchema as n } from '@nostrify/nostrify';
import { useNostr } from '@nostrify/react';
import { useQuery } from '@tanstack/react-query';
// Fallback relays for profile aggregation — global indexers
const FALLBACK_RELAYS = [
'wss://purplepag.es',
'wss://relay.nostr.band',
'wss://nos.lol',
'wss://relay.damus.io',
];
export function useAuthor(pubkey: string | undefined) {
const { nostr } = useNostr();
return useQuery<{ event?: NostrEvent; metadata?: NostrMetadata }>({
queryKey: ['author', pubkey ?? ''],
queryFn: async ({ signal }) => {
if (!pubkey) {
return {};
}
const querySignal = AbortSignal.any([signal, AbortSignal.timeout(15000)]);
try {
// Try main relays first
let [event] = await nostr.query(
[{ kinds: [0], authors: [pubkey], limit: 1 }],
{ signal: querySignal },
);
// If not found, try fallback profile aggregator relays
if (!event) {
try {
const fallbackGroup = nostr.group(FALLBACK_RELAYS);
[event] = await fallbackGroup.query(
[{ kinds: [0], authors: [pubkey], limit: 1 }],
{ signal: AbortSignal.timeout(5000) },
);
} catch {
// Fallback failed, continue with no event
}
}
if (!event) {
// No profile found - this is okay, user may not have published one yet
return {};
}
try {
const metadata = n.json().pipe(n.metadata()).parse(event.content);
return { metadata, event };
} catch {
return { event };
}
} catch (error) {
// Network error or timeout - return empty to avoid breaking the UI
console.warn('[useAuthor] Failed to fetch profile for', pubkey?.slice(0, 8), error);
return {};
}
},
staleTime: 60 * 1000, // 1 minute — allows NostrSync to invalidate and refetch quickly
retry: 5,
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 10000),
});
}