Browse Source

render embedded reposts

master
silberengel 7 months ago
parent
commit
f2e3cc08b2
  1. 33
      src/lib/components/Notifications.svelte
  2. 42
      src/lib/utils/notification_utils.ts

33
src/lib/components/Notifications.svelte

@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
truncateContent,
truncateRenderedContent,
parseContent,
parseRepostContent,
renderQuotedContent,
getNotificationType,
fetchAuthorProfiles
@ -692,7 +693,7 @@ @@ -692,7 +693,7 @@
</script>
{#if isOwnProfile && $userStore.signedIn}
<div class="mb-6">
<div class="mb-6 w-full overflow-x-hidden">
<div class="flex items-center justify-between mb-4">
<Heading tag="h3" class="h-leather">Notifications</Heading>
@ -740,7 +741,7 @@ @@ -740,7 +741,7 @@
<P>No public messages found.</P>
</div>
{:else}
<div class="max-h-[72rem] overflow-y-auto">
<div class="max-h-[72rem] overflow-y-auto overflow-x-hidden">
{#if filteredByUser}
<div class="filter-indicator mb-4 p-3 rounded-lg">
<div class="flex items-center justify-between">
@ -818,7 +819,7 @@ @@ -818,7 +819,7 @@
</div>
<!-- Message Content -->
<div class="message-content flex-1 {isFromUser ? 'text-right' : ''}">
<div class="message-content flex-1 min-w-0 {isFromUser ? 'text-right' : ''}">
<div class="flex items-center gap-2 mb-2 {isFromUser ? 'justify-end' : ''}">
<span class="text-xs font-medium text-primary-600 dark:text-primary-400 bg-primary-100 dark:bg-primary-900 px-2 py-1 rounded">
{isFromUser ? 'Your Message' : 'Public Message'}
@ -848,11 +849,13 @@ @@ -848,11 +849,13 @@
{/if}
{#if message.content}
<div class="text-sm text-gray-800 dark:text-gray-200 mb-2 leading-relaxed">
{#await parseContent(message.content) then parsedContent}
{@html parsedContent}
{:catch}
{@html message.content}
{/await}
<div class="px-2">
{#await ((message.kind === 6 || message.kind === 16) ? parseRepostContent(message.content) : parseContent(message.content)) then parsedContent}
{@html parsedContent}
{:catch}
{@html message.content}
{/await}
</div>
</div>
{/if}
@ -877,7 +880,7 @@ @@ -877,7 +880,7 @@
<P>No notifications {notificationMode === "to-me" ? "received" : "sent"} found.</P>
</div>
{:else}
<div class="max-h-[72rem] overflow-y-auto space-y-4">
<div class="max-h-[72rem] overflow-y-auto overflow-x-hidden space-y-4">
{#each notifications.slice(0, 100) as notification}
{@const authorProfile = authorProfiles.get(notification.pubkey)}
<div class="message-container p-4 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm">
@ -929,11 +932,13 @@ @@ -929,11 +932,13 @@
{#if notification.content}
<div class="text-sm text-gray-800 dark:text-gray-200 mb-2 leading-relaxed">
{#await parseContent(notification.content) then parsedContent}
{@html parsedContent}
{:catch}
{@html truncateContent(notification.content)}
{/await}
<div class="px-2">
{#await ((notification.kind === 6 || notification.kind === 16) ? parseRepostContent(notification.content) : parseContent(notification.content)) then parsedContent}
{@html parsedContent}
{:catch}
{@html truncateContent(notification.content)}
{/await}
</div>
</div>
{/if}

42
src/lib/utils/notification_utils.ts

@ -73,6 +73,48 @@ export async function parseContent(content: string): Promise<string> { @@ -73,6 +73,48 @@ export async function parseContent(content: string): Promise<string> {
return await parseBasicmarkup(content);
}
/**
* Parses repost content and renders it as an embedded event
*/
export async function parseRepostContent(content: string): Promise<string> {
if (!content) return "";
try {
// Try to parse the content as JSON (repost events contain the original event as JSON)
const originalEvent = JSON.parse(content);
// Extract the original event's content
const originalContent = originalEvent.content || "";
const originalAuthor = originalEvent.pubkey || "";
const originalCreatedAt = originalEvent.created_at || 0;
// Parse the original content with basic markup
const parsedOriginalContent = await parseBasicmarkup(originalContent);
// Create an embedded event display
const formattedDate = originalCreatedAt ? new Date(originalCreatedAt * 1000).toLocaleDateString() : "Unknown date";
const shortAuthor = originalAuthor ? `${originalAuthor.slice(0, 8)}...${originalAuthor.slice(-4)}` : "Unknown";
return `
<div class="embedded-repost bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-3 my-2">
<div class="flex items-center gap-2 mb-2 text-xs text-gray-600 dark:text-gray-400">
<span class="font-medium">Reposted by:</span>
<span class="font-mono">${shortAuthor}</span>
<span></span>
<span>${formattedDate}</span>
</div>
<div class="text-sm text-gray-800 dark:text-gray-200 leading-relaxed">
${parsedOriginalContent}
</div>
</div>
`;
} catch (error) {
// If JSON parsing fails, fall back to basic markup
console.warn("Failed to parse repost content as JSON, falling back to basic markup:", error);
return await parseBasicmarkup(content);
}
}
/**
* Renders quoted content for a message
*/

Loading…
Cancel
Save