15 changed files with 250 additions and 44 deletions
@ -0,0 +1,7 @@ |
|||||||
|
import { getReplaceableCoordinateFromEvent, isReplaceableEvent } from '@/lib/event' |
||||||
|
import { NostrEvent } from 'nostr-tools' |
||||||
|
|
||||||
|
/** Key used when optimistically marking an event deleted in UI (matches tombstone / filter lookup). */ |
||||||
|
export function getKeyForDeletedLookup(event: NostrEvent): string { |
||||||
|
return isReplaceableEvent(event.kind) ? getReplaceableCoordinateFromEvent(event) : event.id |
||||||
|
} |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
import { buildDeletionRelayUrls } from '@/lib/tombstone-events' |
||||||
|
import client from '@/services/client.service' |
||||||
|
import type { TRelayList } from '@/types' |
||||||
|
|
||||||
|
/** Re-fetch the current user's kind-5 events, update IndexedDB tombstones, and notify UI (via tombstonesUpdated). */ |
||||||
|
export async function syncUserDeletionTombstones( |
||||||
|
pubkey: string | undefined | null, |
||||||
|
relayList: TRelayList | null | undefined |
||||||
|
): Promise<void> { |
||||||
|
if (!pubkey) return |
||||||
|
await client.fetchDeletionEvents(buildDeletionRelayUrls(relayList ?? null), pubkey) |
||||||
|
} |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
import { PROFILE_FETCH_RELAY_URLS } from '@/constants' |
||||||
|
import { normalizeUrl } from '@/lib/url' |
||||||
|
import type { TRelayList } from '@/types' |
||||||
|
|
||||||
|
/** Dispatched after tombstones in IndexedDB change (kind-5 sync or local apply). */ |
||||||
|
export const TOMBSTONES_UPDATED_EVENT = 'jumble:tombstonesUpdated' |
||||||
|
|
||||||
|
export function dispatchTombstonesUpdated(): void { |
||||||
|
if (typeof window === 'undefined') return |
||||||
|
window.dispatchEvent(new CustomEvent(TOMBSTONES_UPDATED_EVENT)) |
||||||
|
} |
||||||
|
|
||||||
|
/** Relay set for querying the current user's kind-5 events (aligned with login sync). */ |
||||||
|
export function buildDeletionRelayUrls(relayList: TRelayList | null | undefined): string[] { |
||||||
|
if (!relayList?.read?.length && !relayList?.write?.length) { |
||||||
|
return Array.from( |
||||||
|
new Set(PROFILE_FETCH_RELAY_URLS.map((url) => normalizeUrl(url) || url).filter(Boolean)) |
||||||
|
).slice(0, 20) |
||||||
|
} |
||||||
|
return Array.from( |
||||||
|
new Set([ |
||||||
|
...relayList.write.map((url: string) => normalizeUrl(url) || url), |
||||||
|
...relayList.read.slice(0, 8).map((url: string) => normalizeUrl(url) || url), |
||||||
|
...PROFILE_FETCH_RELAY_URLS.map((url: string) => normalizeUrl(url) || url) |
||||||
|
]) |
||||||
|
).slice(0, 20) |
||||||
|
} |
||||||
Loading…
Reference in new issue