|
|
|
@ -159,8 +159,9 @@ export function isHighlighted(eventId: string): boolean { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Toggle pin status of an event |
|
|
|
* Toggle pin status of an event |
|
|
|
* Publishes kind 10001 list event (pins are stored in cache and on relays only) |
|
|
|
* Publishes kind 10001 list event (pins are stored in cache and on relays only) |
|
|
|
|
|
|
|
* Returns publication results |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
export async function togglePin(eventId: string): Promise<boolean> { |
|
|
|
export async function togglePin(eventId: string): Promise<{ success: string[]; failed: Array<{ relay: string; error: string }> }> { |
|
|
|
try { |
|
|
|
try { |
|
|
|
const session = sessionManager.getSession(); |
|
|
|
const session = sessionManager.getSession(); |
|
|
|
if (!session) { |
|
|
|
if (!session) { |
|
|
|
@ -179,27 +180,26 @@ export async function togglePin(eventId: string): Promise<boolean> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Publish updated pin list event
|
|
|
|
// Publish updated pin list event
|
|
|
|
await publishPinList(Array.from(currentPins)); |
|
|
|
const result = await publishPinList(Array.from(currentPins)); |
|
|
|
|
|
|
|
|
|
|
|
// Invalidate cache so next read gets fresh data
|
|
|
|
// Invalidate cache so next read gets fresh data
|
|
|
|
invalidatePinCache(); |
|
|
|
invalidatePinCache(); |
|
|
|
|
|
|
|
|
|
|
|
return !isCurrentlyPinned; |
|
|
|
return result; |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
console.error('Failed to toggle pin:', error); |
|
|
|
console.error('Failed to toggle pin:', error); |
|
|
|
// Return current state on error
|
|
|
|
return { success: [], failed: [{ relay: 'unknown', error: error instanceof Error ? error.message : String(error) }] }; |
|
|
|
const currentPins = await getPinnedEvents(); |
|
|
|
|
|
|
|
return currentPins.has(eventId); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Publish pin list event (kind 10001) |
|
|
|
* Publish pin list event (kind 10001) |
|
|
|
|
|
|
|
* Returns publication results |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
async function publishPinList(eventIds: string[]): Promise<void> { |
|
|
|
async function publishPinList(eventIds: string[]): Promise<{ success: string[]; failed: Array<{ relay: string; error: string }> }> { |
|
|
|
try { |
|
|
|
try { |
|
|
|
const session = sessionManager.getSession(); |
|
|
|
const session = sessionManager.getSession(); |
|
|
|
if (!session) return; |
|
|
|
if (!session) return { success: [], failed: [] }; |
|
|
|
|
|
|
|
|
|
|
|
// Deduplicate input eventIds first
|
|
|
|
// Deduplicate input eventIds first
|
|
|
|
const deduplicatedEventIds = Array.from(new Set(eventIds)); |
|
|
|
const deduplicatedEventIds = Array.from(new Set(eventIds)); |
|
|
|
@ -236,7 +236,7 @@ async function publishPinList(eventIds: string[]): Promise<void> { |
|
|
|
const removedEventIds = [...existingEventIds].filter(id => !deduplicatedEventIds.includes(id)); |
|
|
|
const removedEventIds = [...existingEventIds].filter(id => !deduplicatedEventIds.includes(id)); |
|
|
|
|
|
|
|
|
|
|
|
if (newEventIds.length === 0 && removedEventIds.length === 0 && existingLists.length > 0) { |
|
|
|
if (newEventIds.length === 0 && removedEventIds.length === 0 && existingLists.length > 0) { |
|
|
|
return; // No changes, cancel operation
|
|
|
|
return { success: [], failed: [] }; // No changes, cancel operation
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Build final tags: preserve all a-tags, add/update e-tags
|
|
|
|
// Build final tags: preserve all a-tags, add/update e-tags
|
|
|
|
@ -293,17 +293,19 @@ async function publishPinList(eventIds: string[]): Promise<void> { |
|
|
|
|
|
|
|
|
|
|
|
// Publish to write relays
|
|
|
|
// Publish to write relays
|
|
|
|
const writeRelays = relayManager.getPublishRelays(relays, true); |
|
|
|
const writeRelays = relayManager.getPublishRelays(relays, true); |
|
|
|
await signAndPublish(listEvent, writeRelays); |
|
|
|
return await signAndPublish(listEvent, writeRelays); |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
console.error('Failed to publish pin list:', error); |
|
|
|
console.error('Failed to publish pin list:', error); |
|
|
|
|
|
|
|
return { success: [], failed: [{ relay: 'unknown', error: error instanceof Error ? error.message : String(error) }] }; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Toggle bookmark status of an event |
|
|
|
* Toggle bookmark status of an event |
|
|
|
* Publishes kind 10003 list event (bookmarks are stored in cache and on relays only) |
|
|
|
* Publishes kind 10003 list event (bookmarks are stored in cache and on relays only) |
|
|
|
|
|
|
|
* Returns publication results |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
export async function toggleBookmark(eventId: string): Promise<boolean> { |
|
|
|
export async function toggleBookmark(eventId: string): Promise<{ success: string[]; failed: Array<{ relay: string; error: string }> }> { |
|
|
|
try { |
|
|
|
try { |
|
|
|
const session = sessionManager.getSession(); |
|
|
|
const session = sessionManager.getSession(); |
|
|
|
if (!session) { |
|
|
|
if (!session) { |
|
|
|
@ -322,27 +324,26 @@ export async function toggleBookmark(eventId: string): Promise<boolean> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Publish updated bookmark list event
|
|
|
|
// Publish updated bookmark list event
|
|
|
|
await publishBookmarkList(Array.from(currentBookmarks)); |
|
|
|
const result = await publishBookmarkList(Array.from(currentBookmarks)); |
|
|
|
|
|
|
|
|
|
|
|
// Invalidate cache so next read gets fresh data
|
|
|
|
// Invalidate cache so next read gets fresh data
|
|
|
|
invalidateBookmarkCache(); |
|
|
|
invalidateBookmarkCache(); |
|
|
|
|
|
|
|
|
|
|
|
return !isCurrentlyBookmarked; |
|
|
|
return result; |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
console.error('Failed to toggle bookmark:', error); |
|
|
|
console.error('Failed to toggle bookmark:', error); |
|
|
|
// Return current state on error
|
|
|
|
return { success: [], failed: [{ relay: 'unknown', error: error instanceof Error ? error.message : String(error) }] }; |
|
|
|
const currentBookmarks = await getBookmarkedEvents(); |
|
|
|
|
|
|
|
return currentBookmarks.has(eventId); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Publish bookmark list event (kind 10003) |
|
|
|
* Publish bookmark list event (kind 10003) |
|
|
|
|
|
|
|
* Returns publication results |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
async function publishBookmarkList(eventIds: string[]): Promise<void> { |
|
|
|
async function publishBookmarkList(eventIds: string[]): Promise<{ success: string[]; failed: Array<{ relay: string; error: string }> }> { |
|
|
|
try { |
|
|
|
try { |
|
|
|
const session = sessionManager.getSession(); |
|
|
|
const session = sessionManager.getSession(); |
|
|
|
if (!session) return; |
|
|
|
if (!session) return { success: [], failed: [] }; |
|
|
|
|
|
|
|
|
|
|
|
// Deduplicate input eventIds first
|
|
|
|
// Deduplicate input eventIds first
|
|
|
|
const deduplicatedEventIds = Array.from(new Set(eventIds)); |
|
|
|
const deduplicatedEventIds = Array.from(new Set(eventIds)); |
|
|
|
@ -379,7 +380,7 @@ async function publishBookmarkList(eventIds: string[]): Promise<void> { |
|
|
|
const removedEventIds = [...existingEventIds].filter(id => !deduplicatedEventIds.includes(id)); |
|
|
|
const removedEventIds = [...existingEventIds].filter(id => !deduplicatedEventIds.includes(id)); |
|
|
|
|
|
|
|
|
|
|
|
if (newEventIds.length === 0 && removedEventIds.length === 0 && existingLists.length > 0) { |
|
|
|
if (newEventIds.length === 0 && removedEventIds.length === 0 && existingLists.length > 0) { |
|
|
|
return; // No changes, cancel operation
|
|
|
|
return { success: [], failed: [] }; // No changes, cancel operation
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Build final tags: preserve all a-tags, add/update e-tags
|
|
|
|
// Build final tags: preserve all a-tags, add/update e-tags
|
|
|
|
@ -436,9 +437,11 @@ async function publishBookmarkList(eventIds: string[]): Promise<void> { |
|
|
|
|
|
|
|
|
|
|
|
// Publish to write relays
|
|
|
|
// Publish to write relays
|
|
|
|
const writeRelays = relayManager.getPublishRelays(relays, true); |
|
|
|
const writeRelays = relayManager.getPublishRelays(relays, true); |
|
|
|
await signAndPublish(listEvent, writeRelays); |
|
|
|
const result = await signAndPublish(listEvent, writeRelays); |
|
|
|
|
|
|
|
return result; |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
console.error('Failed to publish bookmark list:', error); |
|
|
|
console.error('Failed to publish bookmark list:', error); |
|
|
|
|
|
|
|
return { success: [], failed: [{ relay: 'unknown', error: error instanceof Error ? error.message : String(error) }] }; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|