Browse Source

fixed quote

master
silberengel 7 months ago
parent
commit
958b16ba23
  1. 47
      src/lib/components/EventDetails.svelte
  2. 60
      src/lib/components/Notifications.svelte
  3. 25
      src/lib/components/embedded_events/EmbeddedEvent.svelte
  4. 12
      src/lib/utils/mime.ts
  5. 2
      src/lib/utils/nostrUtils.ts
  6. 89
      src/routes/events/+page.svelte

47
src/lib/components/EventDetails.svelte

@ -15,6 +15,10 @@ @@ -15,6 +15,10 @@
import ContainingIndexes from "$lib/components/util/ContainingIndexes.svelte";
import Notifications from "$lib/components/Notifications.svelte";
import { parseBasicmarkup } from "$lib/utils/markup/basicMarkupParser";
import { repostContent, quotedContent } from "$lib/components/embedded_events/EmbeddedSnippets.svelte";
import { repostKinds } from "$lib/consts";
import { getNdkContext } from "$lib/ndk";
import { processNostrIdentifiers } from "$lib/utils/nostrUtils";
import type { UserProfile } from "$lib/models/user_profile";
@ -30,6 +34,7 @@ import type { UserProfile } from "$lib/models/user_profile"; @@ -30,6 +34,7 @@ import type { UserProfile } from "$lib/models/user_profile";
let showFullContent = $state(false);
let shouldTruncate = $derived(event.content.length > 250 && !showFullContent);
let parsedContent = $state<string>("");
let isRepost = $derived(repostKinds.includes(event.kind) || (event.kind === 1 && event.getMatchingTags("q").length > 0));
function getEventTitle(event: NDKEvent): string {
// First try to get title from title tag
@ -246,12 +251,20 @@ import type { UserProfile } from "$lib/models/user_profile"; @@ -246,12 +251,20 @@ import type { UserProfile } from "$lib/models/user_profile";
$effect(() => {
if (event.content) {
parseBasicmarkup(event.content).then((parsed) => {
parsedContent = parsed;
// For kind 6 and 16 reposts, we don't need to parse the content as basic markup since it's JSON
// For quote reposts (kind 1 with q tags), we still need to parse the content for nostr identifiers
if (repostKinds.includes(event.kind)) {
parsedContent = event.content;
} else {
// For all other events (including quote reposts), parse the content for nostr identifiers
// Use the proper processNostrIdentifiers function to get display names
processNostrIdentifiers(event.content, getNdkContext()).then((processed) => {
parsedContent = processed;
}).catch((error) => {
console.error("Error parsing content:", error);
parsedContent = event.content;
});
}
} else {
parsedContent = "";
}
@ -324,6 +337,35 @@ import type { UserProfile } from "$lib/models/user_profile"; @@ -324,6 +337,35 @@ import type { UserProfile } from "$lib/models/user_profile";
<div class="flex flex-col space-y-1 min-w-0">
<span class="text-gray-700 dark:text-gray-300 font-semibold">Content:</span>
<div class="prose dark:prose-invert max-w-none text-gray-900 dark:text-gray-100 break-words overflow-wrap-anywhere min-w-0">
{#if isRepost}
<!-- Repost content handling -->
{#if repostKinds.includes(event.kind)}
<!-- Kind 6 and 16 reposts - stringified JSON content -->
<div class="border-l-4 border-primary-300 dark:border-primary-600 pl-3 mb-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
{event.kind === 6 ? 'Reposted content:' : 'Generic reposted content:'}
</div>
{@render repostContent(event.content)}
</div>
{:else if event.kind === 1 && event.getMatchingTags("q").length > 0}
<!-- Quote repost - kind 1 with q tag -->
<div class="border-l-4 border-primary-300 dark:border-primary-600 pl-3 mb-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Quote repost:
</div>
{@render quotedContent(event, [], getNdkContext())}
{#if event.content && event.content.trim()}
<div class="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Added comment:
</div>
{@html parsedContent}
</div>
{/if}
</div>
{/if}
{:else}
<!-- Regular content -->
<div class={shouldTruncate ? 'max-h-32 overflow-hidden' : ''}>
{@html parsedContent}
</div>
@ -333,6 +375,7 @@ import type { UserProfile } from "$lib/models/user_profile"; @@ -333,6 +375,7 @@ import type { UserProfile } from "$lib/models/user_profile";
onclick={() => (showFullContent = true)}>Show more</button
>
{/if}
{/if}
</div>
</div>
</div>

60
src/lib/components/Notifications.svelte

@ -22,6 +22,8 @@ @@ -22,6 +22,8 @@
import { formatDate, neventEncode } from "$lib/utils";
import { NDKRelaySetFromNDK } from "$lib/utils/nostrUtils";
import { parseBasicmarkup } from "$lib/utils/markup/basicMarkupParser";
import { repostContent } from "$lib/components/embedded_events/EmbeddedSnippets.svelte";
import { repostKinds } from "$lib/consts";
import { getNdkContext } from "$lib/ndk";
@ -819,9 +821,38 @@ @@ -819,9 +821,38 @@
<div class="text-sm text-gray-800 dark:text-gray-200 mb-2 leading-relaxed">
<div class="px-2">
<div class="text-sm text-gray-700 dark:text-gray-300">
{#if repostKinds.includes(message.kind)}
<!-- Repost content - parse stringified JSON -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
{message.kind === 6 ? 'Repost:' : 'Generic repost:'}
</div>
{@render repostContent(message.content)}
</div>
{:else if message.kind === 1 && message.getMatchingTags("q").length > 0}
<!-- Quote repost content -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Quote repost:
</div>
{@render quotedContent(message, publicMessages, ndk)}
{#if message.content && message.content.trim()}
<div class="mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Comment:
</div>
{#await parseBasicmarkup(message.content.slice(0, 100) + (message.content.length > 100 ? "..." : "")) then parsed}
{@html parsed}
{/await}
</div>
{/if}
</div>
{:else}
<!-- Regular content -->
{#await parseBasicmarkup(message.content || "No content") then parsed}
{@html parsed}
{/await}
{/if}
</div>
</div>
</div>
@ -900,9 +931,38 @@ @@ -900,9 +931,38 @@
<div class="text-sm text-gray-800 dark:text-gray-200 mb-2 leading-relaxed">
<div class="px-2">
<div class="text-sm text-gray-700 dark:text-gray-300">
{#if repostKinds.includes(notification.kind)}
<!-- Repost content - parse stringified JSON -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
{notification.kind === 6 ? 'Repost:' : 'Generic repost:'}
</div>
{@render repostContent(notification.content)}
</div>
{:else if notification.kind === 1 && notification.getMatchingTags("q").length > 0}
<!-- Quote repost content -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Quote repost:
</div>
{@render quotedContent(notification, notifications, ndk)}
{#if notification.content && notification.content.trim()}
<div class="mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Comment:
</div>
{#await parseBasicmarkup(notification.content.slice(0, 100) + (notification.content.length > 100 ? "..." : "")) then parsed}
{@html parsed}
{/await}
</div>
{/if}
</div>
{:else}
<!-- Regular content -->
{#await parseBasicmarkup(notification.content || "No content") then parsed}
{@html parsed}
{/await}
{/if}
</div>
</div>
</div>

25
src/lib/components/embedded_events/EmbeddedEvent.svelte

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { fetchEventWithFallback, getUserMetadata, toNpub } from "$lib/utils/nostrUtils";
import { userBadge } from "$lib/snippets/UserSnippets.svelte";
import { parsedContent } from "$lib/components/embedded_events/EmbeddedSnippets.svelte";
import { parsedContent, repostContent, quotedContent } from "$lib/components/embedded_events/EmbeddedSnippets.svelte";
import { naddrEncode } from "$lib/utils";
import { activeInboxRelays, getNdkContext } from "$lib/ndk";
import { goto } from "$app/navigation";
@ -292,14 +292,27 @@ @@ -292,14 +292,27 @@
{#if event.kind === 1 || repostKinds.includes(event.kind)}
<div class="prose prose-sm dark:prose-invert max-w-none text-gray-900 dark:text-gray-100 min-w-0 overflow-hidden">
{#if repostKinds.includes(event.kind)}
<!-- Repost content -->
<!-- Repost content - parse stringified JSON according to NIP-18 -->
<div class="border-l-4 border-primary-300 dark:border-primary-600 pl-3 mb-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Reposted content:
{event.kind === 6 ? 'Reposted content:' : 'Generic reposted content:'}
</div>
{@render repostContent(event.content)}
</div>
{:else if event.kind === 1 && event.getMatchingTags("q").length > 0}
<!-- Quote repost content - kind 1 with q tag according to NIP-18 -->
<div class="border-l-4 border-primary-300 dark:border-primary-600 pl-3 mb-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Quote repost:
</div>
{@render quotedContent(event, [], ndk)}
{#if event.content && event.content.trim()}
<div class="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Added comment:
</div>
{@render parsedContent(event.content)}
</div>
{@render parsedContent(event.content.slice(0, 300))}
{#if event.content.length > 300}
<span class="text-gray-500 dark:text-gray-400">...</span>
{/if}
</div>
{:else}

12
src/lib/utils/mime.ts

@ -62,6 +62,18 @@ export function getMimeTags(kind: number): [string, string][] { @@ -62,6 +62,18 @@ export function getMimeTags(kind: number): [string, string][] {
MTag = ["M", `note/microblog/${replaceability}`];
break;
// Repost (NIP-18)
case 6:
mTag = ["m", "application/json"];
MTag = ["M", `note/repost/${replaceability}`];
break;
// Generic repost (NIP-18)
case 16:
mTag = ["m", "application/json"];
MTag = ["M", `note/generic-repost/${replaceability}`];
break;
// Generic reply
case 1111:
mTag = ["m", "text/plain"];

2
src/lib/utils/nostrUtils.ts

@ -179,7 +179,7 @@ export async function createProfileLinkWithVerification( @@ -179,7 +179,7 @@ export async function createProfileLinkWithVerification(
/**
* Create a note link element
*/
function createNoteLink(identifier: string): string {
export function createNoteLink(identifier: string): string {
const cleanId = identifier.replace(/^nostr:/, "");
const shortId = `${cleanId.slice(0, 12)}...${cleanId.slice(-8)}`;
const escapedId = escapeHtml(cleanId);

89
src/routes/events/+page.svelte

@ -22,6 +22,8 @@ @@ -22,6 +22,8 @@
import ViewPublicationLink from "$lib/components/util/ViewPublicationLink.svelte";
import { checkCommunity } from "$lib/utils/search_utility";
import { parseBasicmarkup } from "$lib/utils/markup/basicMarkupParser";
import { repostContent, quotedContent } from "$lib/components/embedded_events/EmbeddedSnippets.svelte";
import { repostKinds } from "$lib/consts";
import { userStore } from "$lib/stores/userStore";
import {
@ -752,9 +754,38 @@ @@ -752,9 +754,38 @@
<div
class="text-sm text-gray-800 dark:text-gray-200 mt-1 line-clamp-2 break-words"
>
{#if repostKinds.includes(result.kind)}
<!-- Repost content - parse stringified JSON -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
{result.kind === 6 ? 'Repost:' : 'Generic repost:'}
</div>
{@render repostContent(result.content)}
</div>
{:else if result.kind === 1 && result.getMatchingTags("q").length > 0}
<!-- Quote repost content -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Quote repost:
</div>
{@render quotedContent(result, [], ndk)}
{#if result.content && result.content.trim()}
<div class="mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Comment:
</div>
{#await parseBasicmarkup(result.content.slice(0, 100) + (result.content.length > 100 ? "..." : "")) then parsed}
{@html parsed}
{/await}
</div>
{/if}
</div>
{:else}
<!-- Regular content -->
{#await parseBasicmarkup(result.content.slice(0, 200) + (result.content.length > 200 ? "..." : "")) then parsed}
{@html parsed}
{/await}
{/if}
</div>
{/if}
{/if}
@ -938,9 +969,38 @@ @@ -938,9 +969,38 @@
<div
class="text-sm text-gray-800 dark:text-gray-200 mt-1 line-clamp-2 break-words"
>
{#if repostKinds.includes(result.kind)}
<!-- Repost content - parse stringified JSON -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
{result.kind === 6 ? 'Repost:' : 'Generic repost:'}
</div>
{@render repostContent(result.content)}
</div>
{:else if result.kind === 1 && result.getMatchingTags("q").length > 0}
<!-- Quote repost content -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Quote repost:
</div>
{@render quotedContent(result, [], ndk)}
{#if result.content && result.content.trim()}
<div class="mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Comment:
</div>
{#await parseBasicmarkup(result.content.slice(0, 100) + (result.content.length > 100 ? "..." : "")) then parsed}
{@html parsed}
{/await}
</div>
{/if}
</div>
{:else}
<!-- Regular content -->
{#await parseBasicmarkup(result.content.slice(0, 200) + (result.content.length > 200 ? "..." : "")) then parsed}
{@html parsed}
{/await}
{/if}
</div>
{/if}
{/if}
@ -1110,9 +1170,38 @@ @@ -1110,9 +1170,38 @@
<div
class="text-sm text-gray-800 dark:text-gray-200 mt-1 line-clamp-2 break-words"
>
{#if repostKinds.includes(result.kind)}
<!-- Repost content - parse stringified JSON -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
{result.kind === 6 ? 'Repost:' : 'Generic repost:'}
</div>
{@render repostContent(result.content)}
</div>
{:else if result.kind === 1 && result.getMatchingTags("q").length > 0}
<!-- Quote repost content -->
<div class="border-l-2 border-primary-300 dark:border-primary-600 pl-2">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Quote repost:
</div>
{@render quotedContent(result, [], ndk)}
{#if result.content && result.content.trim()}
<div class="mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">
Comment:
</div>
{#await parseBasicmarkup(result.content.slice(0, 100) + (result.content.length > 100 ? "..." : "")) then parsed}
{@html parsed}
{/await}
</div>
{/if}
</div>
{:else}
<!-- Regular content -->
{#await parseBasicmarkup(result.content.slice(0, 200) + (result.content.length > 200 ? "..." : "")) then parsed}
{@html parsed}
{/await}
{/if}
</div>
{/if}
{/if}

Loading…
Cancel
Save