|
|
|
|
@ -5,7 +5,7 @@
@@ -5,7 +5,7 @@
|
|
|
|
|
import FeedPost from '../feed/FeedPost.svelte'; |
|
|
|
|
import CommentComponent from '../comments/Comment.svelte'; |
|
|
|
|
import ProfileMenu from '../../components/profile/ProfileMenu.svelte'; |
|
|
|
|
import { fetchProfile, fetchUserStatus, fetchUserStatusEvent, type ProfileData } from '../../services/user-data.js'; |
|
|
|
|
import { fetchProfile, fetchUserStatus, fetchUserStatusEvent, fetchRelayLists, type ProfileData } from '../../services/user-data.js'; |
|
|
|
|
import { nostrClient } from '../../services/nostr/nostr-client.js'; |
|
|
|
|
import { relayManager } from '../../services/nostr/relay-manager.js'; |
|
|
|
|
import { config } from '../../services/nostr/config.js'; |
|
|
|
|
@ -132,6 +132,34 @@
@@ -132,6 +132,34 @@
|
|
|
|
|
return unsubscribe; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Get relays for loading a profile, including the profile owner's relay lists |
|
|
|
|
*/ |
|
|
|
|
async function getProfileRelaysForPubkey(pubkey: string): Promise<string[]> { |
|
|
|
|
// Start with base profile relays |
|
|
|
|
const baseRelays = relayManager.getProfileReadRelays(); |
|
|
|
|
|
|
|
|
|
// Try to fetch relay lists from the profile owner (non-blocking) |
|
|
|
|
try { |
|
|
|
|
const { inbox } = await Promise.race([ |
|
|
|
|
fetchRelayLists(pubkey, baseRelays), |
|
|
|
|
new Promise<{ inbox: string[]; outbox: string[] }>((resolve) => |
|
|
|
|
setTimeout(() => resolve({ inbox: [], outbox: [] }), 2000) |
|
|
|
|
) |
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
// Combine base relays with profile owner's inbox relays |
|
|
|
|
const allRelays = [...baseRelays, ...inbox]; |
|
|
|
|
|
|
|
|
|
// Normalize and deduplicate |
|
|
|
|
const normalized = allRelays.map(r => r.toLowerCase().trim()).filter(r => r.length > 0); |
|
|
|
|
return Array.from(new Set(normalized)); |
|
|
|
|
} catch (error) { |
|
|
|
|
// If fetching relay lists fails, just use base relays |
|
|
|
|
return baseRelays; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function loadProfileEvent(pubkey: string) { |
|
|
|
|
if (!isMounted) return; |
|
|
|
|
try { |
|
|
|
|
@ -144,7 +172,8 @@
@@ -144,7 +172,8 @@
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Fetch from relays if not in cache - shorter timeout |
|
|
|
|
const relays = relayManager.getProfileReadRelays(); |
|
|
|
|
// Include profile owner's relay lists |
|
|
|
|
const relays = await getProfileRelaysForPubkey(pubkey); |
|
|
|
|
const events = await nostrClient.fetchEvents( |
|
|
|
|
[{ kinds: [KIND.METADATA], authors: [pubkey], limit: 1 }], |
|
|
|
|
relays, |
|
|
|
|
@ -632,11 +661,18 @@
@@ -632,11 +661,18 @@
|
|
|
|
|
|
|
|
|
|
loading = true; |
|
|
|
|
try { |
|
|
|
|
// Step 0: Get relays including profile owner's relay lists (non-blocking, with timeout) |
|
|
|
|
const profileRelaysPromise = getProfileRelaysForPubkey(pubkey); |
|
|
|
|
|
|
|
|
|
// Step 1: Load profile and status first (fast from cache) - display immediately |
|
|
|
|
// fetchProfile uses parseProfile which prioritizes tags over JSON content |
|
|
|
|
const profilePromise = fetchProfile(pubkey); |
|
|
|
|
const statusPromise = fetchUserStatus(pubkey); |
|
|
|
|
const statusEventPromise = fetchUserStatusEvent(pubkey); |
|
|
|
|
// Use profile owner's relays if available, otherwise fall back to default |
|
|
|
|
const relaysPromise = profileRelaysPromise.catch(() => relayManager.getProfileReadRelays()); |
|
|
|
|
const relays = await relaysPromise; |
|
|
|
|
|
|
|
|
|
const profilePromise = fetchProfile(pubkey, relays); |
|
|
|
|
const statusPromise = fetchUserStatus(pubkey, relays); |
|
|
|
|
const statusEventPromise = fetchUserStatusEvent(pubkey, relays); |
|
|
|
|
activeFetchPromises.add(profilePromise); |
|
|
|
|
activeFetchPromises.add(statusPromise); |
|
|
|
|
activeFetchPromises.add(statusEventPromise); |
|
|
|
|
|