7 changed files with 204 additions and 77 deletions
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
import { |
||||
isSocialKindBlockedKind, |
||||
MAX_PUBLISH_RELAYS, |
||||
READ_ONLY_RELAY_URLS, |
||||
SOCIAL_KIND_BLOCKED_RELAY_URLS |
||||
} from '@/constants' |
||||
import { dedupeNormalizeRelayUrlsOrdered } from '@/lib/relay-url-priority' |
||||
import { normalizeAnyRelayUrl, normalizeHttpRelayUrl, normalizeUrl } from '@/lib/url' |
||||
import type { NostrEvent } from 'nostr-tools' |
||||
|
||||
export type TPrePublishRelayCapPreview = { |
||||
outboxSlotsInPublish: number |
||||
selectedContacted: number |
||||
selectedTotal: number |
||||
showCapHint: boolean |
||||
/** True when not every checked relay in the picker can be included in the capped publish list. */ |
||||
blocksPublish: boolean |
||||
} |
||||
|
||||
/** |
||||
* Pre-publish preview: mirrors merge + cap order in {@link ClientService.publishEvent}: NIP-65 write list first, then |
||||
* relays checked in the post relay picker, capped at {@link MAX_PUBLISH_RELAYS}. |
||||
*/ |
||||
export function computePrePublishRelayCapPreview({ |
||||
relayListWrite, |
||||
relayListHttpWrite, |
||||
selectedRelayUrls, |
||||
isPublicMessage, |
||||
parentEvent, |
||||
isDiscussionReply |
||||
}: { |
||||
relayListWrite?: string[] |
||||
relayListHttpWrite?: string[] |
||||
selectedRelayUrls: string[] |
||||
isPublicMessage: boolean |
||||
parentEvent?: NostrEvent |
||||
isDiscussionReply: boolean |
||||
}): TPrePublishRelayCapPreview { |
||||
const applySocialOutboxFilter = |
||||
!isPublicMessage && |
||||
(parentEvent == null || |
||||
isDiscussionReply || |
||||
(parentEvent != null && isSocialKindBlockedKind(parentEvent.kind))) |
||||
|
||||
const wsOut = (relayListWrite ?? []) |
||||
.map((u) => normalizeUrl(u) || u) |
||||
.filter((u): u is string => !!u) |
||||
const httpOut = (relayListHttpWrite ?? []) |
||||
.map((u) => normalizeHttpRelayUrl(u) || u) |
||||
.filter((u): u is string => !!u) |
||||
let outbox = dedupeNormalizeRelayUrlsOrdered([...httpOut, ...wsOut]) |
||||
const readOnlySet = new Set(READ_ONLY_RELAY_URLS.map((u) => normalizeAnyRelayUrl(u) || u)) |
||||
const socialBlockedSet = new Set(SOCIAL_KIND_BLOCKED_RELAY_URLS.map((u) => normalizeUrl(u) || u)) |
||||
outbox = dedupeNormalizeRelayUrlsOrdered( |
||||
outbox.filter((url) => { |
||||
const n = normalizeAnyRelayUrl(url) || url |
||||
if (readOnlySet.has(n)) return false |
||||
if (applySocialOutboxFilter && socialBlockedSet.has(n)) return false |
||||
return true |
||||
}) |
||||
) |
||||
|
||||
const merged = dedupeNormalizeRelayUrlsOrdered([...outbox, ...selectedRelayUrls]) |
||||
const capped = merged.slice(0, MAX_PUBLISH_RELAYS) |
||||
const outboxNormSet = new Set(outbox) |
||||
const outboxSlotsInPublish = capped.filter((u) => outboxNormSet.has(u)).length |
||||
const selectedNorm = selectedRelayUrls.map((u) => normalizeAnyRelayUrl(u) || u) |
||||
const selectedContacted = selectedNorm.filter((u) => capped.includes(u)).length |
||||
|
||||
const showCapHint = |
||||
merged.length > MAX_PUBLISH_RELAYS || |
||||
selectedRelayUrls.length >= MAX_PUBLISH_RELAYS || |
||||
selectedContacted < selectedRelayUrls.length |
||||
|
||||
const blocksPublish = selectedContacted < selectedRelayUrls.length |
||||
|
||||
return { |
||||
outboxSlotsInPublish, |
||||
selectedContacted, |
||||
selectedTotal: selectedRelayUrls.length, |
||||
showCapHint, |
||||
blocksPublish |
||||
} |
||||
} |
||||
Loading…
Reference in new issue