clone of repo on github
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

95 lines
3.1 KiB

<script lang="ts">
import { AAlert, AProfilePreview } from "$lib/a";
import CommentBox from "$lib/components/CommentBox.svelte";
import CommentViewer from "$lib/components/CommentViewer.svelte";
import { userStore } from "$lib/stores/userStore";
import { getUserMetadata } from "$lib/utils/nostrUtils";
import type { NDKEvent } from "$lib/utils/nostrUtils";
import { getNdkContext } from "$lib/ndk.ts";
// State
let user = $state($userStore);
let loading = $state(false);
let error = $state<string | null>(null);
let profileEvent = $state<NDKEvent | null>(null);
let profile = $state<{
name?: string;
display_name?: string;
about?: string;
picture?: string;
banner?: string;
website?: string;
lud16?: string;
nip05?: string;
} | null>(null);
let lastFetchedPubkey: string | null = null;
let userRelayPreference = $state(false); // required by CommentBox
userStore.subscribe(v => user = v);
async function fetchProfileEvent(pubkey: string) {
if (!pubkey || pubkey === lastFetchedPubkey) return;
loading = true;
error = null;
try {
const ndk = getNdkContext();
if (!ndk) {
throw new Error('NDK not initialized');
}
// Fetch kind 0 event for this author
const evt = await ndk.fetchEvent({ kinds: [0], authors: [pubkey] });
profileEvent = evt || null;
if (evt?.content) {
try { profile = JSON.parse(evt.content); } catch { profile = null; }
} else {
profile = null;
}
// Fallback: ensure we have metadata via helper (will cache)
if (!profile && user.npub) {
const meta = await getUserMetadata(user.npub, ndk, true);
profile = {
name: meta.name,
display_name: meta.displayName,
about: meta.about,
picture: meta.picture,
banner: meta.banner,
website: meta.website,
lud16: meta.lud16,
nip05: meta.nip05,
};
}
lastFetchedPubkey = pubkey;
} catch (e: any) {
console.error('[profile/+page] Failed to fetch profile event', e);
error = e?.message || 'Failed to load profile';
} finally {
loading = false;
}
}
// Reactive: when user login changes fetch profile event
$effect(() => {
if (user?.pubkey) fetchProfileEvent(user.pubkey);
});
</script>
{#if !user || !user.signedIn}
<div class="w-full max-w-3xl mx-auto mt-10 px-4">
<AAlert color="blue">Please log in to view your profile.</AAlert>
</div>
{:else}
<div class="w-full flex justify-center">
<div class="flex flex-col w-full max-w-5xl my-6 px-4 mx-auto gap-6">
<AProfilePreview user={user} profile={profile} loading={loading} error={error} isOwn={!!user?.signedIn && (!profileEvent?.pubkey || profileEvent.pubkey === user.pubkey)} />
{#if profileEvent}
<div class="main-leather flex flex-col space-y-6">
<CommentViewer event={profileEvent} />
<CommentBox event={profileEvent} {userRelayPreference} />
</div>
{:else if !loading}
<AAlert color="gray">No profile event (kind 0) found for this user.</AAlert>
{/if}
</div>
</div>
{/if}