You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.9 KiB
84 lines
2.9 KiB
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 |
|
} |
|
}
|
|
|