Browse Source

bug-fixes

imwald
Silberengel 1 month ago
parent
commit
e9686c9193
  1. 18
      src/components/NoteList/index.tsx
  2. 21
      src/components/Relay/index.tsx
  3. 4
      src/components/Settings/SettingsMenuBody.tsx
  4. 2
      src/constants.ts
  5. 32
      src/services/client.service.ts

18
src/components/NoteList/index.tsx

@ -2054,8 +2054,15 @@ const NoteList = forwardRef( @@ -2054,8 +2054,15 @@ const NoteList = forwardRef(
if (oneShotFetch || mappedSubRequests.length === 0) return
if (isSpellPageLocalWarmup) return
const diskReq = mappedSubRequests as Array<{ urls: string[]; filter: TSubRequestFilter }>
const strictSingleRelayShard =
mappedSubRequests.length === 1 &&
mappedSubRequests[0]!.urls.length === 1 &&
(hostPrimaryPageNameRef.current === 'relay' ||
(allowKindlessRelayExploreRef.current && useFilterAsIsRef.current))
void client
.getLocalFeedEvents(diskReq)
.getLocalFeedEvents(diskReq, {
strictRelayShardSourcesOnly: strictSingleRelayShard
})
.then((diskRaw) => {
if (!effectActive || timelineEffectStale()) return
const diskNarrowed = narrowLiveBatch(diskRaw)
@ -2429,8 +2436,15 @@ const NoteList = forwardRef( @@ -2429,8 +2436,15 @@ const NoteList = forwardRef(
urls: string[]
filter: TSubRequestFilter
}>
const strictSingleRelayShardOneShot =
mappedSubRequests.length === 1 &&
mappedSubRequests[0]!.urls.length === 1 &&
(hostPrimaryPageNameRef.current === 'relay' ||
(allowKindlessRelayExploreRef.current && useFilterAsIsRef.current))
void client
.getLocalFeedEvents(diskReqOneShot)
.getLocalFeedEvents(diskReqOneShot, {
strictRelayShardSourcesOnly: strictSingleRelayShardOneShot
})
.then((diskRaw) => {
if (!effectActive || timelineEffectStale()) return
if (diskRaw.length === 0) return

21
src/components/Relay/index.tsx

@ -7,8 +7,10 @@ import type { TPrimaryPageName } from '@/PageManager' @@ -7,8 +7,10 @@ import type { TPrimaryPageName } from '@/PageManager'
import { SINGLE_RELAY_KINDLESS_REQ_LIMIT } from '@/constants'
import { normalizeAnyRelayUrl } from '@/lib/url'
import { useCurrentRelays } from '@/providers/CurrentRelaysProvider'
import client from '@/services/client.service'
import type { TFeedSubRequest } from '@/types'
import { forwardRef, useEffect, useMemo, useRef, useState } from 'react'
import type { Event } from 'nostr-tools'
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import NotFound from '../NotFound'
@ -77,6 +79,21 @@ const Relay = forwardRef< @@ -77,6 +79,21 @@ const Relay = forwardRef<
]
}, [normalizedUrl, debouncedInput])
/** When we know delivery relays, drop rows that never arrived from this feed’s relay (stale cache / mis-tagged). */
const relaySeenMatchKey = useMemo(
() => (normalizedUrl ? (normalizeAnyRelayUrl(normalizedUrl) || normalizedUrl).toLowerCase() : ''),
[normalizedUrl]
)
const shouldHideEventNotFromThisRelay = useCallback(
(ev: Event) => {
if (!relaySeenMatchKey) return false
const seen = client.getSeenEventRelayUrls(ev.id)
if (seen.length === 0) return false
return !seen.some((u) => (normalizeAnyRelayUrl(u) || u).toLowerCase() === relaySeenMatchKey)
},
[relaySeenMatchKey]
)
if (!normalizedUrl) {
return <NotFound />
}
@ -101,6 +118,8 @@ const Relay = forwardRef< @@ -101,6 +118,8 @@ const Relay = forwardRef<
showAllKinds
showFeedClientFilter
hostPrimaryPageName={hostPrimaryPageName}
extraShouldHideEvent={shouldHideEventNotFromThisRelay}
extraShouldHideRepliesEvent={shouldHideEventNotFromThisRelay}
/>
</div>
)

4
src/components/Settings/SettingsMenuBody.tsx

@ -144,10 +144,6 @@ export default function SettingsMenuBody({ className }: { className?: string }) @@ -144,10 +144,6 @@ export default function SettingsMenuBody({ className }: { className?: string })
</div>
</SettingItem>
</AboutInfoDialog>
<div className="py-6 text-center text-muted-foreground">
<div className="app-chrome-title">Imwald</div>
<div className="font-semibold text-green-600 dark:text-green-500">Im Wald</div>
</div>
</div>
)
}

2
src/constants.ts

@ -73,7 +73,7 @@ export const DESKTOP_APP_DOWNLOAD_URL_DEFAULT = @@ -73,7 +73,7 @@ export const DESKTOP_APP_DOWNLOAD_URL_DEFAULT =
export const DEFAULT_FAVORITE_RELAYS = [
'wss://theforest.nostr1.com',
'wss://orly-relay.imwald.eu',
'wss://christpill.nostr1.com',
'wss://nostr.land',
'wss://nostr21.com'
]

32
src/services/client.service.ts

@ -1895,7 +1895,16 @@ class ClientService extends EventTarget { @@ -1895,7 +1895,16 @@ class ClientService extends EventTarget {
async getLocalFeedEvents(
subRequests: { urls: string[]; filter: TSubRequestFilter }[],
options?: { maxRowsScanned?: number; maxMatches?: number }
options?: {
maxRowsScanned?: number
maxMatches?: number
/**
* When true, only load rows persisted for this feeds timeline shard(s) no global session scan or
* archive/publication sweeps. Used for single-relay explore so kindless `{ limit }` does not match every
* cached note while the UI is scoped to one relay.
*/
strictRelayShardSourcesOnly?: boolean
}
): Promise<NEvent[]> {
if (!subRequests.length) return []
const filters = subRequests.map(({ filter }) => filter as Filter)
@ -1921,6 +1930,14 @@ class ClientService extends EventTarget { @@ -1921,6 +1930,14 @@ class ClientService extends EventTarget {
}
}
if (options?.strictRelayShardSourcesOnly) {
const timelineRows = await this.getTimelineDiskSnapshotEvents(subRequests).catch(() => [] as NEvent[])
add(timelineRows)
return [...byId.values()]
.sort((a, b) => b.created_at - a.created_at || b.id.localeCompare(a.id))
.slice(0, maxMatches)
}
add(this.eventService.getSessionEventsMatchingFilters(filters, maxMatches))
const [timelineRows, archiveRows, publicationRows] = await Promise.all([
@ -3285,6 +3302,7 @@ class ClientService extends EventTarget { @@ -3285,6 +3302,7 @@ class ClientService extends EventTarget {
})
let relayListResolved = 0
let contactsResolved = 0
let profileResolved = 0
const chunkSize = 20
for (let i = 0; i * chunkSize < followings.length; i++) {
if (signal.aborted) {
@ -3292,20 +3310,24 @@ class ClientService extends EventTarget { @@ -3292,20 +3310,24 @@ class ClientService extends EventTarget {
return
}
const chunk = followings.slice(i * chunkSize, (i + 1) * chunkSize)
const [relayListEvents, contactsEvents] = await Promise.all([
const [relayListEvents, contactsEvents, metadataEvents] = await Promise.all([
this.replaceableEventService.fetchReplaceableEventsFromProfileFetchRelays(chunk, kinds.RelayList),
this.replaceableEventService.fetchReplaceableEventsFromProfileFetchRelays(chunk, kinds.Contacts),
Promise.all(chunk.map((pk) => this.fetchProfileEvent(pk)))
this.replaceableEventService.fetchReplaceableEventsFromProfileFetchRelays(chunk, kinds.Metadata)
])
relayListResolved += relayListEvents.filter(Boolean).length
contactsResolved += contactsEvents.filter(Boolean).length
await new Promise((resolve) => setTimeout(resolve, 1000))
const profiles = metadataEvents.filter((ev): ev is NEvent => Boolean(ev))
profileResolved += profiles.length
await Promise.allSettled(profiles.map((ev) => this.addUsernameToIndex(ev)))
profiles.forEach((ev) => this.updateProfileEventCache(ev))
}
logger.info('[client] Prewarm: following profile + contacts + NIP-65 fetch finished', {
pubkeySlice: pubkey.slice(0, 12),
followingCount: followings.length,
relayListEventsResolved: relayListResolved,
contactsEventsResolved: contactsResolved
contactsEventsResolved: contactsResolved,
profileEventsResolved: profileResolved
})
}

Loading…
Cancel
Save