|
|
|
|
@ -20,6 +20,7 @@
@@ -20,6 +20,7 @@
|
|
|
|
|
import { KIND } from '../types/kind-lookup.js'; |
|
|
|
|
import { goto } from '$app/navigation'; |
|
|
|
|
import Icon from './ui/Icon.svelte'; |
|
|
|
|
import { getEventLink } from '../services/event-links.js'; |
|
|
|
|
|
|
|
|
|
interface Props { |
|
|
|
|
event: NostrEvent; |
|
|
|
|
@ -243,16 +244,47 @@
@@ -243,16 +244,47 @@
|
|
|
|
|
closeMenu(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function viewEvent() { |
|
|
|
|
closeMenu(); |
|
|
|
|
goto(getEventLink(event)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function cloneEvent() { |
|
|
|
|
// Store event data in sessionStorage for the write page to pick up |
|
|
|
|
const cloneData = { |
|
|
|
|
kind: event.kind, |
|
|
|
|
content: event.content, |
|
|
|
|
tags: event.tags, |
|
|
|
|
isClone: true |
|
|
|
|
}; |
|
|
|
|
sessionStorage.setItem('aitherboard_cloneEvent', JSON.stringify(cloneData)); |
|
|
|
|
closeMenu(); |
|
|
|
|
goto('/write'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function broadcastEvent() { |
|
|
|
|
broadcasting = true; |
|
|
|
|
closeMenu(); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
// Get all available relays for broadcasting |
|
|
|
|
const relays = relayManager.getPublishRelays( |
|
|
|
|
[...relayManager.getThreadReadRelays(), ...relayManager.getFeedReadRelays()], |
|
|
|
|
true |
|
|
|
|
); |
|
|
|
|
// Get ALL available relays for maximum broadcasting |
|
|
|
|
// Start with all available relays (includes default, profile, and user inbox relays) |
|
|
|
|
let allRelays = relayManager.getAllAvailableRelays(); |
|
|
|
|
|
|
|
|
|
// Add thread publish relays (includes thread-specific relays) |
|
|
|
|
allRelays = [...allRelays, ...relayManager.getThreadPublishRelays()]; |
|
|
|
|
|
|
|
|
|
// Add file metadata publish relays (includes GIF relays) |
|
|
|
|
allRelays = [...allRelays, ...relayManager.getFileMetadataPublishRelays()]; |
|
|
|
|
|
|
|
|
|
// Add feed response relays |
|
|
|
|
allRelays = [...allRelays, ...relayManager.getFeedResponseReadRelays()]; |
|
|
|
|
|
|
|
|
|
// Use getPublishRelays to ensure user outbox and local write relays are included |
|
|
|
|
// This will also normalize, deduplicate, filter read-only relays, and filter blocked relays |
|
|
|
|
const relays = relayManager.getPublishRelays(allRelays, true); |
|
|
|
|
|
|
|
|
|
console.log(`[Broadcast] Broadcasting to ${relays.length} relays:`, relays); |
|
|
|
|
|
|
|
|
|
const results = await nostrClient.publish(event, { relays }); |
|
|
|
|
publicationResults = results; |
|
|
|
|
@ -284,14 +316,18 @@
@@ -284,14 +316,18 @@
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function pinNote() { |
|
|
|
|
await togglePin(event.id); |
|
|
|
|
const results = await togglePin(event.id); |
|
|
|
|
publicationResults = results; |
|
|
|
|
publicationModalOpen = true; |
|
|
|
|
// Force state update |
|
|
|
|
stateUpdateTrigger++; |
|
|
|
|
closeMenu(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function bookmarkNote() { |
|
|
|
|
await toggleBookmark(event.id); |
|
|
|
|
const results = await toggleBookmark(event.id); |
|
|
|
|
publicationResults = results; |
|
|
|
|
publicationModalOpen = true; |
|
|
|
|
// Force state update by re-checking bookmark status |
|
|
|
|
const newBookmarked = await isBookmarked(event.id); |
|
|
|
|
bookmarkedState = newBookmarked; |
|
|
|
|
@ -390,6 +426,19 @@
@@ -390,6 +426,19 @@
|
|
|
|
|
class="menu-dropdown" |
|
|
|
|
style="top: {menuPosition.top}px; right: {menuPosition.right}px;" |
|
|
|
|
> |
|
|
|
|
<!-- View actions --> |
|
|
|
|
<button class="menu-item" onclick={viewEvent}> |
|
|
|
|
<Icon name="eye" size={16} /> |
|
|
|
|
<span>View this note</span> |
|
|
|
|
</button> |
|
|
|
|
<button class="menu-item" onclick={viewJson}> |
|
|
|
|
<Icon name="code" size={16} /> |
|
|
|
|
<span>View JSON</span> |
|
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
<div class="menu-divider"></div> |
|
|
|
|
|
|
|
|
|
<!-- Copy actions --> |
|
|
|
|
<button class="menu-item" onclick={copyUserId}> |
|
|
|
|
<Icon name="copy" size={16} /> |
|
|
|
|
<span>Copy user ID</span> |
|
|
|
|
@ -404,20 +453,10 @@
@@ -404,20 +453,10 @@
|
|
|
|
|
<span class="copied-indicator">✓</span> |
|
|
|
|
{/if} |
|
|
|
|
</button> |
|
|
|
|
<button class="menu-item" onclick={viewJson}> |
|
|
|
|
<Icon name="code" size={16} /> |
|
|
|
|
<span>View JSON</span> |
|
|
|
|
</button> |
|
|
|
|
{#if isLoggedIn} |
|
|
|
|
<button class="menu-item" onclick={viewRelatedEvents}> |
|
|
|
|
<Icon name="search" size={16} /> |
|
|
|
|
<span>View your related events</span> |
|
|
|
|
</button> |
|
|
|
|
{/if} |
|
|
|
|
<button class="menu-item" onclick={broadcastEvent} disabled={broadcasting}> |
|
|
|
|
<Icon name="radio" size={16} /> |
|
|
|
|
<span>{broadcasting ? 'Broadcasting...' : 'Broadcast event'}</span> |
|
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
<div class="menu-divider"></div> |
|
|
|
|
|
|
|
|
|
<!-- Share actions --> |
|
|
|
|
<button class="menu-item" onclick={shareWithaitherboard}> |
|
|
|
|
<Icon name="share" size={16} /> |
|
|
|
|
<span>Share with aitherboard</span> |
|
|
|
|
@ -426,6 +465,24 @@
@@ -426,6 +465,24 @@
|
|
|
|
|
{/if} |
|
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
<!-- User-specific actions (logged in only) --> |
|
|
|
|
{#if isLoggedIn} |
|
|
|
|
<div class="menu-divider"></div> |
|
|
|
|
<button class="menu-item" onclick={viewRelatedEvents}> |
|
|
|
|
<Icon name="search" size={16} /> |
|
|
|
|
<span>View your related events</span> |
|
|
|
|
</button> |
|
|
|
|
<button class="menu-item" onclick={cloneEvent}> |
|
|
|
|
<Icon name="edit" size={16} /> |
|
|
|
|
<span>Edit/Clone this event</span> |
|
|
|
|
</button> |
|
|
|
|
<button class="menu-item" onclick={broadcastEvent} disabled={broadcasting}> |
|
|
|
|
<Icon name="radio" size={16} /> |
|
|
|
|
<span>{broadcasting ? 'Broadcasting...' : 'Broadcast event'}</span> |
|
|
|
|
</button> |
|
|
|
|
{/if} |
|
|
|
|
|
|
|
|
|
<!-- Interaction actions (logged in only) --> |
|
|
|
|
{#if isLoggedIn && onReply} |
|
|
|
|
<div class="menu-divider"></div> |
|
|
|
|
<button class="menu-item menu-item-reply" onclick={() => { onReply(); closeMenu(); }}> |
|
|
|
|
@ -434,7 +491,9 @@
@@ -434,7 +491,9 @@
|
|
|
|
|
</button> |
|
|
|
|
{/if} |
|
|
|
|
{#if isLoggedIn && showContentActions} |
|
|
|
|
<div class="menu-divider"></div> |
|
|
|
|
{#if !onReply} |
|
|
|
|
<div class="menu-divider"></div> |
|
|
|
|
{/if} |
|
|
|
|
<button class="menu-item" onclick={pinNote} class:active={pinnedState}> |
|
|
|
|
<Icon name="plus" size={16} /> |
|
|
|
|
<span>Pin note</span> |
|
|
|
|
@ -458,6 +517,7 @@
@@ -458,6 +517,7 @@
|
|
|
|
|
</button> |
|
|
|
|
{/if} |
|
|
|
|
|
|
|
|
|
<!-- Delete action (logged in and own event only) --> |
|
|
|
|
{#if isLoggedIn && isOwnEvent} |
|
|
|
|
<div class="menu-divider"></div> |
|
|
|
|
<button class="menu-item menu-item-danger" onclick={confirmDelete} disabled={deleting}> |
|
|
|
|
|