Browse Source

fixed reactive card display

master
silberengel 7 months ago
parent
commit
e76ed044f8
  1. 9
      src/app.css
  2. 3
      src/lib/components/EventDetails.svelte
  3. 8
      src/lib/components/cards/ProfileHeader.svelte
  4. 224
      src/routes/events/+page.svelte

9
src/app.css

@ -98,6 +98,15 @@
@apply text-gray-900 dark:text-gray-100; @apply text-gray-900 dark:text-gray-100;
} }
/* Responsive card styles */
.responsive-card {
@apply w-full min-w-0 overflow-hidden;
}
.responsive-card-content {
@apply break-words overflow-hidden;
}
h1.h-leather { h1.h-leather {
@apply text-4xl font-bold; @apply text-4xl font-bold;
} }

3
src/lib/components/EventDetails.svelte

@ -26,9 +26,11 @@
const { const {
event, event,
profile = null, profile = null,
communityStatusMap = {},
} = $props<{ } = $props<{
event: NDKEvent; event: NDKEvent;
profile?: UserProfile | null; profile?: UserProfile | null;
communityStatusMap?: Record<string, boolean>;
}>(); }>();
const ndk = getNdkContext(); const ndk = getNdkContext();
@ -378,6 +380,7 @@
<ProfileHeader <ProfileHeader
{event} {event}
{profile} {profile}
{communityStatusMap}
/> />
{/if} {/if}

8
src/lib/components/cards/ProfileHeader.svelte

@ -55,7 +55,12 @@
$effect(() => { $effect(() => {
if (event?.pubkey) { if (event?.pubkey) {
// First check if we have cached profileData with user list information // First check if we have user list information in the profile prop
if (profile && typeof profile.isInUserLists === 'boolean') {
isInUserLists = profile.isInUserLists;
console.log(`[ProfileHeader] Using profile prop user list status for ${event.pubkey}: ${isInUserLists}`);
} else {
// Then check if we have cached profileData with user list information
const cachedProfileData = (event as any).profileData; const cachedProfileData = (event as any).profileData;
console.log(`[ProfileHeader] Checking user list status for ${event.pubkey}, cached profileData:`, cachedProfileData); console.log(`[ProfileHeader] Checking user list status for ${event.pubkey}, cached profileData:`, cachedProfileData);
@ -76,6 +81,7 @@
isInUserLists = false; isInUserLists = false;
}); });
} }
}
// Check community status - use cached data if available // Check community status - use cached data if available
if (communityStatusMap[event.pubkey] !== undefined) { if (communityStatusMap[event.pubkey] !== undefined) {

224
src/routes/events/+page.svelte

@ -91,10 +91,17 @@
try { try {
const parsedProfile = parseProfileContent(newEvent); const parsedProfile = parseProfileContent(newEvent);
if (parsedProfile) { if (parsedProfile) {
// Check if we already have user list information from the search results
const existingProfileData = (newEvent as any).profileData;
if (existingProfileData && typeof existingProfileData.isInUserLists === "boolean") {
// Use the existing user list status from search results
profile = { ...parsedProfile, isInUserLists: existingProfileData.isInUserLists } as any;
console.log(`[Events Page] Using existing user list status for ${newEvent.pubkey}: ${existingProfileData.isInUserLists}`);
} else {
// Set initial profile and fetch user list information
profile = parsedProfile; profile = parsedProfile;
// If the event doesn't have user list information, fetch it // Fetch user list information
if (typeof parsedProfile.isInUserLists !== "boolean") {
fetchCurrentUserLists(undefined, ndk) fetchCurrentUserLists(undefined, ndk)
.then((userLists) => { .then((userLists) => {
const isInLists = isPubkeyInUserLists( const isInLists = isPubkeyInUserLists(
@ -103,11 +110,12 @@
); );
// Update the profile with user list information // Update the profile with user list information
profile = { ...parsedProfile, isInUserLists: isInLists } as any; profile = { ...parsedProfile, isInUserLists: isInLists } as any;
// Also update the event's profileData // Also update the event's profileData for consistency
(newEvent as any).profileData = { (newEvent as any).profileData = {
...parsedProfile, ...parsedProfile,
isInUserLists: isInLists, isInUserLists: isInLists,
}; };
console.log(`[Events Page] Updated user list status for ${newEvent.pubkey}: ${isInLists}`);
}) })
.catch(() => { .catch(() => {
profile = { ...parsedProfile, isInUserLists: false } as any; profile = { ...parsedProfile, isInUserLists: false } as any;
@ -115,6 +123,7 @@
...parsedProfile, ...parsedProfile,
isInUserLists: false, isInUserLists: false,
}; };
console.log(`[Events Page] Set default user list status for ${newEvent.pubkey}: false`);
}); });
} }
} else { } else {
@ -136,17 +145,16 @@
if (newEvent.pubkey) { if (newEvent.pubkey) {
cacheProfileForPubkey(newEvent.pubkey); cacheProfileForPubkey(newEvent.pubkey);
// Update profile data with user list information // Also check community status for the individual event if not already cached
updateProfileDataWithUserLists([newEvent]);
// Also check community status for the individual event
if (!communityStatus[newEvent.pubkey]) { if (!communityStatus[newEvent.pubkey]) {
checkCommunity(newEvent.pubkey) checkCommunity(newEvent.pubkey)
.then((status) => { .then((status) => {
communityStatus = { ...communityStatus, [newEvent.pubkey]: status }; communityStatus = { ...communityStatus, [newEvent.pubkey]: status };
console.log(`[Events Page] Updated community status for ${newEvent.pubkey}: ${status}`);
}) })
.catch(() => { .catch(() => {
communityStatus = { ...communityStatus, [newEvent.pubkey]: false }; communityStatus = { ...communityStatus, [newEvent.pubkey]: false };
console.log(`[Events Page] Set default community status for ${newEvent.pubkey}: false`);
}); });
} }
} }
@ -501,15 +509,16 @@
<div class="w-full flex justify-center"> <div class="w-full flex justify-center">
<div <div
class="flex flex-col lg:flex-row w-full max-w-7xl my-6 px-4 mx-auto gap-6" class="flex flex-col lg:flex-row w-full max-w-7xl my-6 px-4 mx-auto gap-6 overflow-hidden"
> >
<!-- Left Panel: Search and Results --> <!-- Left Panel: Search and Results -->
<div <div
class={showSidePanel class={showSidePanel
? "w-full lg:w-80 lg:min-w-80" ? "w-full lg:w-80 lg:min-w-80"
: "flex-1 max-w-4xl mx-auto"} : "w-full max-w-4xl mx-auto lg:max-w-4xl"}
class:min-w-0={true}
> >
<div class="main-leather flex flex-col space-y-6"> <div class="main-leather flex flex-col space-y-6 w-full">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<Heading tag="h1" class="h-leather mb-2">Events</Heading> <Heading tag="h1" class="h-leather mb-2">Events</Heading>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
@ -588,7 +597,7 @@
? "lg:block hidden" ? "lg:block hidden"
: "block"} : "block"}
> >
<Heading tag="h2" class="h-leather mb-4 break-words"> <Heading tag="h2" class="h-leather mb-4 break-words overflow-hidden">
{#if searchType === "n"} {#if searchType === "n"}
Search Results for name: "{searchTerm && Search Results for name: "{searchTerm &&
searchTerm.length > 50 searchTerm.length > 50
@ -610,24 +619,26 @@
})()}" ({searchResults.length} events) })()}" ({searchResults.length} events)
{/if} {/if}
</Heading> </Heading>
<div class="space-y-4"> <div class="space-y-4 w-full max-w-full">
{#each searchResults as result, index} {#each searchResults as result, index}
{@const profileData = {@const profileData =
(result as any).profileData || parseProfileContent(result)} (result as any).profileData || parseProfileContent(result)}
<button <button
class="w-full text-left border border-gray-300 dark:border-gray-600 rounded-lg p-4 bg-white dark:bg-primary-900/70 hover:bg-gray-100 dark:hover:bg-primary-800 focus:bg-gray-100 dark:focus:bg-primary-800 focus:outline-none focus:ring-2 focus:ring-primary-500 transition-colors overflow-hidden" class="responsive-card text-left border border-gray-300 dark:border-gray-600 rounded-lg p-4 bg-white dark:bg-primary-900/70 hover:bg-gray-100 dark:hover:bg-primary-800 focus:bg-gray-100 dark:focus:bg-primary-800 focus:outline-none focus:ring-2 focus:ring-primary-500 transition-colors"
onclick={() => handleEventFound(result)} onclick={() => handleEventFound(result)}
> >
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1 responsive-card-content">
<div class="flex items-center gap-2 mb-1"> <div class="flex items-center gap-2 mb-1 min-w-0">
<span <span
class="font-medium text-gray-800 dark:text-gray-100" class="font-medium text-gray-800 dark:text-gray-100 flex-shrink-0"
>{searchType === "n" ? "Profile" : "Event"} >{searchType === "n" ? "Profile" : "Event"}
{index + 1}</span {index + 1}</span
> >
<span class="text-xs text-gray-600 dark:text-gray-400" <span class="text-xs text-gray-600 dark:text-gray-400 flex-shrink-0"
>Kind: {result.kind}</span >Kind: {result.kind}</span
> >
<div class="flex items-center gap-2 ml-auto flex-shrink-0">
<!-- Indicators -->
{#if profileData?.isInUserLists} {#if profileData?.isInUserLists}
<div <div
class="flex-shrink-0 w-4 h-4 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center" class="flex-shrink-0 w-4 h-4 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center"
@ -643,7 +654,8 @@
/> />
</svg> </svg>
</div> </div>
{:else if result.pubkey && communityStatus[result.pubkey]} {/if}
{#if result.pubkey && communityStatus[result.pubkey]}
<div <div
class="flex-shrink-0 w-4 h-4 bg-yellow-100 dark:bg-yellow-900 rounded-full flex items-center justify-center" class="flex-shrink-0 w-4 h-4 bg-yellow-100 dark:bg-yellow-900 rounded-full flex items-center justify-center"
title="Has posted to the community" title="Has posted to the community"
@ -658,9 +670,36 @@
/> />
</svg> </svg>
</div> </div>
{:else} {/if}
{#if !profileData?.isInUserLists && !(result.pubkey && communityStatus[result.pubkey])}
<div class="flex-shrink-0 w-4 h-4"></div> <div class="flex-shrink-0 w-4 h-4"></div>
{/if} {/if}
<!-- Profile picture -->
{#if profileData?.picture}
<img
src={profileData.picture}
alt="Profile"
class="w-6 h-6 rounded-full object-cover border border-gray-200 dark:border-gray-600 flex-shrink-0"
onerror={(e) => {
(e.target as HTMLImageElement).style.display = "none";
(e.target as HTMLImageElement).nextElementSibling?.classList.remove("hidden");
}}
/>
<div
class="w-6 h-6 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 flex-shrink-0 hidden"
>
<UserOutline class="w-3 h-3 text-gray-600 dark:text-gray-300" />
</div>
{:else}
<div
class="w-6 h-6 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 flex-shrink-0"
>
<UserOutline class="w-3 h-3 text-gray-600 dark:text-gray-300" />
</div>
{/if}
<!-- User badge -->
<span class="text-xs text-gray-600 dark:text-gray-400"> <span class="text-xs text-gray-600 dark:text-gray-400">
{@render userBadge( {@render userBadge(
toNpub(result.pubkey) as string, toNpub(result.pubkey) as string,
@ -668,6 +707,7 @@
ndk, ndk,
)} )}
</span> </span>
</div>
<span <span
class="text-xs text-gray-500 dark:text-gray-400 ml-auto" class="text-xs text-gray-500 dark:text-gray-400 ml-auto"
> >
@ -684,7 +724,7 @@
<img <img
src={profileData.picture} src={profileData.picture}
alt="Profile" alt="Profile"
class="w-12 h-12 rounded-full object-cover border border-gray-200 dark:border-gray-600" class="w-12 h-12 rounded-full object-cover border border-gray-200 dark:border-gray-600 flex-shrink-0"
onerror={(e) => { onerror={(e) => {
(e.target as HTMLImageElement).style.display = (e.target as HTMLImageElement).style.display =
"none"; "none";
@ -696,7 +736,7 @@
}} }}
/> />
<div <div
class="w-12 h-12 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 hidden" class="w-12 h-12 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 hidden flex-shrink-0"
> >
<UserOutline <UserOutline
class="w-6 h-6 text-gray-600 dark:text-gray-300" class="w-6 h-6 text-gray-600 dark:text-gray-300"
@ -704,14 +744,14 @@
</div> </div>
{:else} {:else}
<div <div
class="w-12 h-12 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600" class="w-12 h-12 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 flex-shrink-0"
> >
<UserOutline <UserOutline
class="w-6 h-6 text-gray-600 dark:text-gray-300" class="w-6 h-6 text-gray-600 dark:text-gray-300"
/> />
</div> </div>
{/if} {/if}
<div class="flex flex-col min-w-0 flex-1"> <div class="flex flex-col min-w-0 flex-1 overflow-hidden">
{#if profileData.display_name || profileData.name} {#if profileData.display_name || profileData.name}
<span <span
class="font-medium text-gray-900 dark:text-gray-100 truncate" class="font-medium text-gray-900 dark:text-gray-100 truncate"
@ -721,7 +761,7 @@
{/if} {/if}
{#if profileData.about} {#if profileData.about}
<span <span
class="text-sm text-gray-600 dark:text-gray-400 line-clamp-2" class="text-sm text-gray-600 dark:text-gray-400 line-clamp-2 break-words"
> >
{profileData.about} {profileData.about}
</span> </span>
@ -822,7 +862,7 @@
? "lg:block hidden" ? "lg:block hidden"
: "block"} : "block"}
> >
<Heading tag="h2" class="h-leather mb-4"> <Heading tag="h2" class="h-leather mb-4 break-words overflow-hidden">
Second-Order Events (References, Replies, Quotes) ({secondOrderResults.length} Second-Order Events (References, Replies, Quotes) ({secondOrderResults.length}
events) events)
</Heading> </Heading>
@ -835,23 +875,41 @@
Events that reference, reply to, highlight, or quote the Events that reference, reply to, highlight, or quote the
original events. original events.
</P> </P>
<div class="space-y-4"> <div class="space-y-4 w-full max-w-full">
{#each secondOrderResults as result, index} {#each secondOrderResults as result, index}
{@const profileData = {@const profileData =
(result as any).profileData || parseProfileContent(result)} (result as any).profileData || parseProfileContent(result)}
<button <button
class="w-full text-left border border-gray-300 dark:border-gray-600 rounded-lg p-4 bg-gray-50 dark:bg-primary-800/50 hover:bg-gray-100 dark:hover:bg-primary-700 focus:bg-gray-100 dark:focus:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 transition-colors overflow-hidden" class="responsive-card text-left border border-gray-300 dark:border-gray-600 rounded-lg p-4 bg-gray-50 dark:bg-primary-800/50 hover:bg-gray-100 dark:hover:bg-primary-700 focus:bg-gray-100 dark:focus:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 transition-colors"
onclick={() => handleEventFound(result)} onclick={() => handleEventFound(result)}
> >
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1 responsive-card-content">
<div class="flex items-center gap-2 mb-1"> <div class="flex items-center gap-2 mb-1 min-w-0">
<span <span
class="font-medium text-gray-800 dark:text-gray-100" class="font-medium text-gray-800 dark:text-gray-100 flex-shrink-0"
>Reference {index + 1}</span >Reference {index + 1}</span
> >
<span class="text-xs text-gray-600 dark:text-gray-400" <span class="text-xs text-gray-600 dark:text-gray-400 flex-shrink-0"
>Kind: {result.kind}</span >Kind: {result.kind}</span
> >
<div class="flex items-center gap-2 ml-auto flex-shrink-0">
<!-- Indicators -->
{#if profileData?.isInUserLists}
<div
class="flex-shrink-0 w-4 h-4 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center"
title="In your lists (follows, etc.)"
>
<svg
class="w-3 h-3 text-red-600 dark:text-red-400"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
/>
</svg>
</div>
{/if}
{#if result.pubkey && communityStatus[result.pubkey]} {#if result.pubkey && communityStatus[result.pubkey]}
<div <div
class="flex-shrink-0 w-4 h-4 bg-yellow-100 dark:bg-yellow-900 rounded-full flex items-center justify-center" class="flex-shrink-0 w-4 h-4 bg-yellow-100 dark:bg-yellow-900 rounded-full flex items-center justify-center"
@ -867,9 +925,36 @@
/> />
</svg> </svg>
</div> </div>
{:else} {/if}
{#if !profileData?.isInUserLists && !(result.pubkey && communityStatus[result.pubkey])}
<div class="flex-shrink-0 w-4 h-4"></div> <div class="flex-shrink-0 w-4 h-4"></div>
{/if} {/if}
<!-- Profile picture -->
{#if profileData?.picture}
<img
src={profileData.picture}
alt="Profile"
class="w-6 h-6 rounded-full object-cover border border-gray-200 dark:border-gray-600 flex-shrink-0"
onerror={(e) => {
(e.target as HTMLImageElement).style.display = "none";
(e.target as HTMLImageElement).nextElementSibling?.classList.remove("hidden");
}}
/>
<div
class="w-6 h-6 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 flex-shrink-0 hidden"
>
<UserOutline class="w-3 h-3 text-gray-600 dark:text-gray-300" />
</div>
{:else}
<div
class="w-6 h-6 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 flex-shrink-0"
>
<UserOutline class="w-3 h-3 text-gray-600 dark:text-gray-300" />
</div>
{/if}
<!-- User badge -->
<span class="text-xs text-gray-600 dark:text-gray-400"> <span class="text-xs text-gray-600 dark:text-gray-400">
{@render userBadge( {@render userBadge(
toNpub(result.pubkey) as string, toNpub(result.pubkey) as string,
@ -877,8 +962,9 @@
ndk, ndk,
)} )}
</span> </span>
</div>
<span <span
class="text-xs text-gray-500 dark:text-gray-400 ml-auto" class="text-xs text-gray-500 dark:text-gray-400 ml-auto flex-shrink-0"
> >
{result.created_at {result.created_at
? new Date( ? new Date(
@ -902,7 +988,7 @@
<img <img
src={profileData.picture} src={profileData.picture}
alt="Profile" alt="Profile"
class="w-12 h-12 rounded-full object-cover border border-gray-200 dark:border-gray-600" class="w-12 h-12 rounded-full object-cover border border-gray-200 dark:border-gray-600 flex-shrink-0"
onerror={(e) => { onerror={(e) => {
(e.target as HTMLImageElement).style.display = (e.target as HTMLImageElement).style.display =
"none"; "none";
@ -910,7 +996,7 @@
/> />
{:else} {:else}
<div <div
class="w-12 h-12 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600" class="w-12 h-12 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 flex-shrink-0"
> >
<span <span
class="text-lg font-medium text-gray-600 dark:text-gray-300" class="text-lg font-medium text-gray-600 dark:text-gray-300"
@ -923,7 +1009,7 @@
</span> </span>
</div> </div>
{/if} {/if}
<div class="flex flex-col min-w-0 flex-1"> <div class="flex flex-col min-w-0 flex-1 overflow-hidden">
{#if profileData.display_name || profileData.name} {#if profileData.display_name || profileData.name}
<span <span
class="font-medium text-gray-900 dark:text-gray-100 truncate" class="font-medium text-gray-900 dark:text-gray-100 truncate"
@ -933,7 +1019,7 @@
{/if} {/if}
{#if profileData.about} {#if profileData.about}
<span <span
class="text-sm text-gray-600 dark:text-gray-400 line-clamp-2" class="text-sm text-gray-600 dark:text-gray-400 line-clamp-2 break-words"
> >
{profileData.about} {profileData.about}
</span> </span>
@ -1034,7 +1120,7 @@
? "lg:block hidden" ? "lg:block hidden"
: "block"} : "block"}
> >
<Heading tag="h2" class="h-leather mb-4"> <Heading tag="h2" class="h-leather mb-4 break-words overflow-hidden">
Search Results for t-tag: "{searchTerm || Search Results for t-tag: "{searchTerm ||
(searchType === "t" ? searchValue : "")}" ({tTagResults.length} (searchType === "t" ? searchValue : "")}" ({tTagResults.length}
events) events)
@ -1042,23 +1128,41 @@
<P class="mb-4 text-sm text-gray-600 dark:text-gray-400"> <P class="mb-4 text-sm text-gray-600 dark:text-gray-400">
Events that are tagged with the t-tag. Events that are tagged with the t-tag.
</P> </P>
<div class="space-y-4"> <div class="space-y-4 w-full max-w-full">
{#each tTagResults as result, index} {#each tTagResults as result, index}
{@const profileData = {@const profileData =
(result as any).profileData || parseProfileContent(result)} (result as any).profileData || parseProfileContent(result)}
<button <button
class="w-full text-left border border-gray-300 dark:border-gray-600 rounded-lg p-4 bg-gray-50 dark:bg-primary-800/50 hover:bg-gray-100 dark:hover:bg-primary-700 focus:bg-gray-100 dark:focus:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 transition-colors overflow-hidden" class="responsive-card text-left border border-gray-300 dark:border-gray-600 rounded-lg p-4 bg-gray-50 dark:bg-primary-800/50 hover:bg-gray-100 dark:hover:bg-primary-700 focus:bg-gray-100 dark:focus:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 transition-colors"
onclick={() => handleEventFound(result)} onclick={() => handleEventFound(result)}
> >
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1 responsive-card-content">
<div class="flex items-center gap-2 mb-1"> <div class="flex items-center gap-2 mb-1 min-w-0">
<span <span
class="font-medium text-gray-800 dark:text-gray-100" class="font-medium text-gray-800 dark:text-gray-100 flex-shrink-0"
>Tagged Event {index + 1}</span >Tagged Event {index + 1}</span
> >
<span class="text-xs text-gray-600 dark:text-gray-400" <span class="text-xs text-gray-600 dark:text-gray-400 flex-shrink-0"
>Kind: {result.kind}</span >Kind: {result.kind}</span
> >
<div class="flex items-center gap-2 ml-auto flex-shrink-0">
<!-- Indicators -->
{#if profileData?.isInUserLists}
<div
class="flex-shrink-0 w-4 h-4 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center"
title="In your lists (follows, etc.)"
>
<svg
class="w-3 h-3 text-red-600 dark:text-red-400"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
/>
</svg>
</div>
{/if}
{#if result.pubkey && communityStatus[result.pubkey]} {#if result.pubkey && communityStatus[result.pubkey]}
<div <div
class="flex-shrink-0 w-4 h-4 bg-yellow-100 dark:bg-yellow-900 rounded-full flex items-center justify-center" class="flex-shrink-0 w-4 h-4 bg-yellow-100 dark:bg-yellow-900 rounded-full flex items-center justify-center"
@ -1074,9 +1178,36 @@
/> />
</svg> </svg>
</div> </div>
{:else} {/if}
{#if !profileData?.isInUserLists && !(result.pubkey && communityStatus[result.pubkey])}
<div class="flex-shrink-0 w-4 h-4"></div> <div class="flex-shrink-0 w-4 h-4"></div>
{/if} {/if}
<!-- Profile picture -->
{#if profileData?.picture}
<img
src={profileData.picture}
alt="Profile"
class="w-6 h-6 rounded-full object-cover border border-gray-200 dark:border-gray-600 flex-shrink-0"
onerror={(e) => {
(e.target as HTMLImageElement).style.display = "none";
(e.target as HTMLImageElement).nextElementSibling?.classList.remove("hidden");
}}
/>
<div
class="w-6 h-6 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 flex-shrink-0 hidden"
>
<UserOutline class="w-3 h-3 text-gray-600 dark:text-gray-300" />
</div>
{:else}
<div
class="w-6 h-6 rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center border border-gray-200 dark:border-gray-600 flex-shrink-0"
>
<UserOutline class="w-3 h-3 text-gray-600 dark:text-gray-300" />
</div>
{/if}
<!-- User badge -->
<span class="text-xs text-gray-600 dark:text-gray-400"> <span class="text-xs text-gray-600 dark:text-gray-400">
{@render userBadge( {@render userBadge(
toNpub(result.pubkey) as string, toNpub(result.pubkey) as string,
@ -1084,6 +1215,7 @@
ndk, ndk,
)} )}
</span> </span>
</div>
<span <span
class="text-xs text-gray-500 dark:text-gray-400 ml-auto" class="text-xs text-gray-500 dark:text-gray-400 ml-auto"
> >
@ -1296,7 +1428,7 @@
{/if} {/if}
<div class="min-w-0 overflow-hidden"> <div class="min-w-0 overflow-hidden">
<EventDetails {event} {profile} /> <EventDetails {event} {profile} communityStatusMap={communityStatus} />
</div> </div>
<div class="min-w-0 overflow-hidden"> <div class="min-w-0 overflow-hidden">
<RelayActions {event} /> <RelayActions {event} />

Loading…
Cancel
Save