Browse Source

bug-fix

imwald
Silberengel 3 weeks ago
parent
commit
fd54a07f5b
  1. 20
      src/components/PostEditor/PostContent.tsx
  2. 2
      src/pages/secondary/RelayPage/index.tsx
  3. 36
      src/services/client.service.ts

20
src/components/PostEditor/PostContent.tsx

@ -1408,6 +1408,15 @@ export default function PostContent({
if (parentEvent) { if (parentEvent) {
mergePublishedReplyIntoThread(cleanEvent, relayStatuses) mergePublishedReplyIntoThread(cleanEvent, relayStatuses)
} else {
client.addEventToCache(cleanEvent)
if (openFrom?.length) {
for (const relayUrl of openFrom) {
window.dispatchEvent(
new CustomEvent('relay-refresh-needed', { detail: { relayUrl } })
)
}
}
} }
onPublishSuccess?.() onPublishSuccess?.()
@ -1452,6 +1461,17 @@ export default function PostContent({
const clean = { ...partialEvent } const clean = { ...partialEvent }
delete (clean as any).relayStatuses delete (clean as any).relayStatuses
mergePublishedReplyIntoThread(clean, (error as any).relayStatuses) mergePublishedReplyIntoThread(clean, (error as any).relayStatuses)
} else if (partialEvent) {
const clean = { ...partialEvent }
delete (clean as any).relayStatuses
client.addEventToCache(clean)
if (openFrom?.length) {
for (const relayUrl of openFrom) {
window.dispatchEvent(
new CustomEvent('relay-refresh-needed', { detail: { relayUrl } })
)
}
}
} }
postEditorCache.clearPostCache({ kind: getDeterminedKind, defaultContent, parentEvent }) postEditorCache.clearPostCache({ kind: getDeterminedKind, defaultContent, parentEvent })
if (isDiscussionThread && !parentEvent) { if (isDiscussionThread && !parentEvent) {

2
src/pages/secondary/RelayPage/index.tsx

@ -39,7 +39,7 @@ const RelayPage = forwardRef(({ url, index, hideTitlebar = false }: { url?: stri
controls={hideTitlebar ? undefined : <RefreshButton onClick={bumpFeed} />} controls={hideTitlebar ? undefined : <RefreshButton onClick={bumpFeed} />}
displayScrollToTopButton displayScrollToTopButton
> >
<Relay ref={feedRef} url={normalizedUrl} /> <Relay ref={feedRef} url={normalizedUrl} hostPrimaryPageName="relay" />
</SecondaryPageLayout> </SecondaryPageLayout>
) )
}) })

36
src/services/client.service.ts

@ -2848,28 +2848,31 @@ class ClientService extends EventTarget {
connectionSlotPriority?: boolean connectionSlotPriority?: boolean
} = {} } = {}
) { ) {
let relays = Array.from(new Set(urls)) const originalDedupedRelays = Array.from(new Set(urls))
let wsRelayUrls = originalDedupedRelays
if (navigator.onLine) { if (navigator.onLine) {
relays = stripLocalNetworkRelaysForWssReq(relays) // HTTPS index relays are polled via HTTP API — never WebSocket REQ (see httpTimelinePollBases below).
wsRelayUrls = stripLocalNetworkRelaysForWssReq(originalDedupedRelays)
} else { } else {
// While offline, strip non-local relays before any further processing so the // While offline, strip non-local relays before any further processing so the
// capital-letter-tag fallback below cannot re-introduce internet relays. // capital-letter-tag fallback below cannot re-introduce internet relays.
relays = relays.filter((url) => isLocalNetworkUrl(url)) wsRelayUrls = originalDedupedRelays.filter((url) => isLocalNetworkUrl(url))
} }
if (relayFiltersUseCapitalLetterTagKeys(filter as Filter)) { if (relayFiltersUseCapitalLetterTagKeys(filter as Filter)) {
relays = relayUrlsStripExtendedTagReqBlocked(relays) wsRelayUrls = relayUrlsStripExtendedTagReqBlocked(wsRelayUrls)
if (relays.length === 0 && navigator.onLine && !relayAuthoritativeTimeline) { if (wsRelayUrls.length === 0 && navigator.onLine && !relayAuthoritativeTimeline) {
relays = relayUrlsStripExtendedTagReqBlocked([...FAST_READ_RELAY_URLS]) wsRelayUrls = relayUrlsStripExtendedTagReqBlocked([...FAST_READ_RELAY_URLS])
} }
} }
const key = this.generateTimelineKey(relays, filter) const timelineUrls = originalDedupedRelays
const key = this.generateTimelineKey(timelineUrls, filter)
let timeline = this.timelines[key] let timeline = this.timelines[key]
if (!timeline || Array.isArray(timeline)) { if (!timeline || Array.isArray(timeline)) {
this.timelines[key] = { this.timelines[key] = {
refs: [], refs: [],
filter, filter,
urls: relays, urls: timelineUrls,
...(relayAuthoritativeTimeline ? { disablePersist: true as const } : {}) ...(relayAuthoritativeTimeline ? { disablePersist: true as const } : {})
} }
timeline = this.timelines[key] timeline = this.timelines[key]
@ -2879,7 +2882,7 @@ class ClientService extends EventTarget {
// relay sent a full `limit` batch whose newest row was still older than that head, `newRefs` became // relay sent a full `limit` batch whose newest row was still older than that head, `newRefs` became
// empty and `tl.refs` was replaced with [] or failed to adopt fresh rows (feed looked permanently stale). // empty and `tl.refs` was replaced with [] or failed to adopt fresh rows (feed looked permanently stale).
timeline.filter = filter timeline.filter = filter
timeline.urls = relays timeline.urls = timelineUrls
timeline.refs = [] timeline.refs = []
if (relayAuthoritativeTimeline) { if (relayAuthoritativeTimeline) {
timeline.disablePersist = true timeline.disablePersist = true
@ -2898,7 +2901,10 @@ class ClientService extends EventTarget {
let eosedAt: number | null = null let eosedAt: number | null = null
let eventIds = new Set<string>() let eventIds = new Set<string>()
const httpTimelinePollBases = httpIndexBasesForRelayQuery(relays, this.viewerHttpIndexRelayBases) const httpTimelinePollBases = httpIndexBasesForRelayQuery(
originalDedupedRelays,
this.viewerHttpIndexRelayBases
).filter((u) => !relaySessionStrikes.isReadHttpSkipped(u))
let httpPollIntervalId: ReturnType<typeof setInterval> | null = null let httpPollIntervalId: ReturnType<typeof setInterval> | null = null
let httpPollCursorUnix = 0 let httpPollCursorUnix = 0
const clearHttpTimelinePoll = () => { const clearHttpTimelinePoll = () => {
@ -3112,7 +3118,7 @@ class ClientService extends EventTarget {
that.timelines[key] = { that.timelines[key] = {
refs: events.map((evt) => [evt.id, evt.created_at]), refs: events.map((evt) => [evt.id, evt.created_at]),
filter, filter,
urls: relays, urls: timelineUrls,
...(relayAuthoritativeTimeline ? { disablePersist: true as const } : {}) ...(relayAuthoritativeTimeline ? { disablePersist: true as const } : {})
} }
} else if (tl.refs.length === 0) { } else if (tl.refs.length === 0) {
@ -3134,12 +3140,8 @@ class ClientService extends EventTarget {
} }
// HTTP index relays are handled via httpTimelinePollBases above — never pass them to the WS subscribe path. // HTTP index relays are handled via httpTimelinePollBases above — never pass them to the WS subscribe path.
const httpPollKeys = new Set( const httpPollKeys = new Set(httpTimelinePollBases.map((u) => canonicalRelaySessionKey(u)))
httpIndexBasesForRelayQuery(relays, this.viewerHttpIndexRelayBases).map((u) => const wsRelays = wsRelayUrls.filter((u) => !httpPollKeys.has(canonicalRelaySessionKey(u)))
canonicalRelaySessionKey(u)
)
)
const wsRelays = relays.filter((u) => !httpPollKeys.has(canonicalRelaySessionKey(u)))
// When there are HTTP relays but NO WS relays, subscribe([]) would fire oneose + onBatchEnd // When there are HTTP relays but NO WS relays, subscribe([]) would fire oneose + onBatchEnd
// immediately (via microtask) — before the HTTP initial poll returns any events. That causes: // immediately (via microtask) — before the HTTP initial poll returns any events. That causes:

Loading…
Cancel
Save