Browse Source

bug-fixes

imwald
Silberengel 1 month ago
parent
commit
30e7cde493
  1. 17
      src/components/KindFilter/index.tsx
  2. 43
      src/components/NormalFeed/index.tsx
  3. 82
      src/components/Note/UnknownNote.tsx
  4. 105
      src/components/NoteList/index.tsx
  5. 2
      src/components/Relay/index.tsx
  6. 1
      src/i18n/locales/de.ts
  7. 1
      src/i18n/locales/en.ts
  8. 11
      src/pages/primary/NoteListPage/RelaysFeed.tsx

17
src/components/KindFilter/index.tsx

@ -308,11 +308,13 @@ export default function KindFilter({ @@ -308,11 +308,13 @@ export default function KindFilter({
{trigger}
<Drawer open={open} onOpenChange={setOpen}>
<DrawerTrigger asChild></DrawerTrigger>
<DrawerContent className="px-4">
<DrawerContent className="flex max-h-[90dvh] flex-col px-4 min-h-0">
<DrawerHeader className="sr-only">
<DrawerTitle>Filter</DrawerTitle>
</DrawerHeader>
{content}
<div className="min-h-0 flex-1 overflow-y-auto overscroll-contain pb-4">
{content}
</div>
</DrawerContent>
</Drawer>
</>
@ -322,8 +324,15 @@ export default function KindFilter({ @@ -322,8 +324,15 @@ export default function KindFilter({
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>{trigger}</PopoverTrigger>
<PopoverContent className="w-96" collisionPadding={16} sideOffset={0}>
{content}
<PopoverContent
className="flex w-96 max-h-[min(85dvh,calc(100dvh-6rem))] flex-col gap-0 overflow-hidden p-0"
collisionPadding={{ top: 80, bottom: 20, left: 16, right: 16 }}
side="bottom"
align="end"
sideOffset={6}
sticky="always"
>
<div className="min-h-0 flex-1 overflow-y-auto overscroll-contain p-4">{content}</div>
</PopoverContent>
</Popover>
)

43
src/components/NormalFeed/index.tsx

@ -26,6 +26,10 @@ const NormalFeed = forwardRef<TNoteListRef, { @@ -26,6 +26,10 @@ const NormalFeed = forwardRef<TNoteListRef, {
mergeTimelineWhenSubRequestFiltersMatch?: boolean
/** Home favorite-relays chip scope; see {@link NoteList} `feedTimelineScopeKey`. */
feedTimelineScopeKey?: string
/** Single-relay Explore / chip: kindless REQ (limit 200), no feed kind filter. */
useFilterAsIs?: boolean
clientSideKindFilter?: boolean
allowKindlessRelayExplore?: boolean
}>(function NormalFeed(
{
subRequests,
@ -36,7 +40,10 @@ const NormalFeed = forwardRef<TNoteListRef, { @@ -36,7 +40,10 @@ const NormalFeed = forwardRef<TNoteListRef, {
onSubHeaderRefresh,
preserveTimelineOnSubRequestsChange = false,
mergeTimelineWhenSubRequestFiltersMatch = false,
feedTimelineScopeKey
feedTimelineScopeKey,
useFilterAsIs = false,
clientSideKindFilter = false,
allowKindlessRelayExplore = false
},
ref
) {
@ -84,6 +91,10 @@ const NormalFeed = forwardRef<TNoteListRef, { @@ -84,6 +91,10 @@ const NormalFeed = forwardRef<TNoteListRef, {
const showKindsKey = useMemo(() => JSON.stringify(showKinds), [showKinds])
const subHeaderFilterDepsKey = allowKindlessRelayExplore
? 'kindless-relay-explore'
: `${showKindsKey}|${feedKindFilterBypass}`
const tabsElement = (
<Tabs
value={listMode}
@ -92,7 +103,9 @@ const NormalFeed = forwardRef<TNoteListRef, { @@ -92,7 +103,9 @@ const NormalFeed = forwardRef<TNoteListRef, {
options={
<div className="flex items-center gap-1">
{onSubHeaderRefresh != null && <RefreshButton onClick={onSubHeaderRefresh} />}
<KindFilter showKinds={showKinds} onShowKindsChange={handleShowKindsChange} />
{!allowKindlessRelayExplore && (
<KindFilter showKinds={showKinds} onShowKindsChange={handleShowKindsChange} />
)}
</div>
}
/>
@ -100,11 +113,28 @@ const NormalFeed = forwardRef<TNoteListRef, { @@ -100,11 +113,28 @@ const NormalFeed = forwardRef<TNoteListRef, {
useLayoutEffect(() => {
if (!isMainFeed || !setSubHeader) return
if (allowKindlessRelayExplore) {
setSubHeader(
onSubHeaderRefresh != null ? (
<div className="flex w-full items-center justify-end gap-1">
<RefreshButton onClick={onSubHeaderRefresh} />
</div>
) : null
)
return () => setSubHeader(null)
}
setSubHeader(tabsElement)
return () => setSubHeader(null)
}, [isMainFeed, setSubHeader, listMode, showKindsKey, feedKindFilterBypass, onSubHeaderRefresh])
}, [
isMainFeed,
setSubHeader,
listMode,
subHeaderFilterDepsKey,
onSubHeaderRefresh,
allowKindlessRelayExplore
])
const renderTabsInFeed = !(isMainFeed && setSubHeader)
const renderTabsInFeed = !(isMainFeed && setSubHeader) && !allowKindlessRelayExplore
return (
<>
@ -118,13 +148,16 @@ const NormalFeed = forwardRef<TNoteListRef, { @@ -118,13 +148,16 @@ const NormalFeed = forwardRef<TNoteListRef, {
showKind1111={showKind1111}
seeAllFeedEvents={feedKindFilterBypass}
subRequests={subRequests}
hideReplies={listMode === 'posts'}
hideReplies={allowKindlessRelayExplore ? false : listMode === 'posts'}
hideUntrustedNotes={hideUntrustedNotes}
areAlgoRelays={areAlgoRelays}
relayCapabilityReady={relayCapabilityReady}
preserveTimelineOnSubRequestsChange={preserveTimelineOnSubRequestsChange}
mergeTimelineWhenSubRequestFiltersMatch={mergeTimelineWhenSubRequestFiltersMatch}
feedTimelineScopeKey={feedTimelineScopeKey}
useFilterAsIs={useFilterAsIs}
clientSideKindFilter={clientSideKindFilter}
allowKindlessRelayExplore={allowKindlessRelayExplore}
/>
</div>
</>

82
src/components/Note/UnknownNote.tsx

@ -34,6 +34,9 @@ const ELEVATED_TAG_NAMES = new Set([ @@ -34,6 +34,9 @@ const ELEVATED_TAG_NAMES = new Set([
'pubkey'
])
/** e / p / q / a: thread & pubkey refs — noisy in preview; show under Technical details only. */
const TECHNICAL_ONLY_TAG_NAMES = new Set(['e', 'p', 'q', 'a'])
function truncatePreview(text: string, max: number): string {
const t = text.trim()
if (t.length <= max) return t
@ -166,7 +169,17 @@ export default function UnknownNote({ @@ -166,7 +169,17 @@ export default function UnknownNote({
const elevated = useMemo(() => extractElevatedTags(event.tags), [event.tags])
const remainderTags = useMemo(
() => event.tags.filter(tag => tag[0] && !ELEVATED_TAG_NAMES.has(tag[0])),
() => event.tags.filter((tag) => tag[0] && !ELEVATED_TAG_NAMES.has(tag[0])),
[event.tags]
)
const mainCardTags = useMemo(
() => remainderTags.filter((tag) => !TECHNICAL_ONLY_TAG_NAMES.has(tag[0])),
[remainderTags]
)
const technicalReferenceTags = useMemo(
() => event.tags.filter((tag) => tag[0] && TECHNICAL_ONLY_TAG_NAMES.has(tag[0])),
[event.tags]
)
@ -199,22 +212,23 @@ export default function UnknownNote({ @@ -199,22 +212,23 @@ export default function UnknownNote({
const showNoTextPlaceholder =
!contentRaw && !hasAnyElevatedCopy && !isBookstrEvent
const proseClass = 'text-sm leading-relaxed whitespace-pre-wrap break-words text-foreground/95'
const proseClass =
'text-xs leading-snug whitespace-pre-wrap break-words text-foreground/95'
return (
<div
className={cn(
'flex flex-col gap-3 my-4',
'flex flex-col gap-2 my-2',
className
)}
>
<div className="rounded-lg border border-border bg-card px-4 py-3 text-card-foreground shadow-sm space-y-3">
<p className="text-sm text-muted-foreground leading-snug">
<div className="rounded-lg border border-border bg-card px-3 py-2 text-card-foreground shadow-sm space-y-2">
<p className="text-xs text-muted-foreground leading-snug">
{t('Unsupported event preview')}
</p>
{showAuthorSummary && isValidPubkey(event.pubkey) ? (
<div className="flex min-w-0 items-center gap-2 border-b border-border/60 pb-3">
<div className="flex min-w-0 items-center gap-2 border-b border-border/60 pb-2">
<UserAvatar userId={event.pubkey} size="medium" className="shrink-0" />
<Username
userId={event.pubkey}
@ -225,12 +239,12 @@ export default function UnknownNote({ @@ -225,12 +239,12 @@ export default function UnknownNote({
) : null}
<div>
<h3 className="text-base font-semibold leading-tight text-foreground">{headline}</h3>
<h3 className="text-sm font-semibold leading-tight text-foreground">{headline}</h3>
{!omitKindLabel ? (
<NoteKindLabel kind={event.kind} event={event} size="small" className="mt-1" />
<NoteKindLabel kind={event.kind} event={event} size="small" className="mt-0.5" />
) : null}
{elevated.title?.trim() && !omitKindLabel ? (
<p className="mt-0.5 text-xs text-muted-foreground">
<p className="mt-0.5 text-[11px] text-muted-foreground leading-snug">
<span className="text-foreground/80">{kindLabel.description}</span>
<span className="mx-1.5 text-border">·</span>
<span className="font-mono tabular-nums">{t('Event kind label', { kind: event.kind })}</span>
@ -252,12 +266,12 @@ export default function UnknownNote({ @@ -252,12 +266,12 @@ export default function UnknownNote({
{elevated.topics.length > 0 ? (
<div>
<p className="text-xs font-medium uppercase tracking-wide text-muted-foreground mb-2">
<p className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground mb-1">
{t('Topics')}
</p>
<div className="flex flex-wrap gap-1.5">
<div className="flex flex-wrap gap-1">
{elevated.topics.map((topic, i) => (
<Badge key={`${topic}-${i}`} variant="secondary" className="font-normal">
<Badge key={`${topic}-${i}`} variant="secondary" className="font-normal text-xs py-0">
{topic}
</Badge>
))}
@ -272,7 +286,7 @@ export default function UnknownNote({ @@ -272,7 +286,7 @@ export default function UnknownNote({
key={`${url}-${i}`}
src={url}
alt=""
className="max-h-52 w-full rounded-md border border-border object-cover bg-muted"
className="max-h-40 w-full rounded-md border border-border object-cover bg-muted"
loading="lazy"
referrerPolicy="no-referrer"
/>
@ -282,7 +296,7 @@ export default function UnknownNote({ @@ -282,7 +296,7 @@ export default function UnknownNote({
{elevated.summary ? (
<div>
<p className="text-xs font-medium uppercase tracking-wide text-muted-foreground mb-1">
<p className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground mb-0.5">
{t('Summary')}
</p>
<p className={cn(proseClass, 'text-muted-foreground')}>{truncatePreview(elevated.summary, CONTENT_PREVIEW_MAX)}</p>
@ -291,7 +305,7 @@ export default function UnknownNote({ @@ -291,7 +305,7 @@ export default function UnknownNote({
{elevated.description ? (
<div>
<p className="text-xs font-medium uppercase tracking-wide text-muted-foreground mb-1">
<p className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground mb-0.5">
{t('Description')}
</p>
<p className={proseClass}>{truncatePreview(elevated.description, CONTENT_PREVIEW_MAX)}</p>
@ -300,7 +314,7 @@ export default function UnknownNote({ @@ -300,7 +314,7 @@ export default function UnknownNote({
{elevated.tagContent && normText(elevated.tagContent) !== contentNorm ? (
<div>
<p className="text-xs font-medium uppercase tracking-wide text-muted-foreground mb-1">
<p className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground mb-0.5">
{t('Unknown note tagged content')}
</p>
<p className={proseClass}>{truncatePreview(elevated.tagContent, CONTENT_PREVIEW_MAX)}</p>
@ -322,17 +336,17 @@ export default function UnknownNote({ @@ -322,17 +336,17 @@ export default function UnknownNote({
) : null}
{showNoTextPlaceholder ? (
<p className="text-sm text-muted-foreground italic">{t('No text content in event')}</p>
<p className="text-xs text-muted-foreground italic">{t('No text content in event')}</p>
) : null}
{remainderTags.length > 0 ? (
<div className="border-t border-border/80 pt-3">
<p className="text-xs font-medium uppercase tracking-wide text-muted-foreground mb-2">
{mainCardTags.length > 0 ? (
<div className="border-t border-border/80 pt-2">
<p className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground mb-1">
{t('Tags')}
</p>
<ul className="space-y-1.5 text-sm">
{remainderTags.map((tag, i) => (
<li key={i} className="flex gap-2 rounded-md bg-muted/40 px-2 py-1.5">
<ul className="space-y-0.5 text-xs">
{mainCardTags.map((tag, i) => (
<li key={i} className="flex gap-1.5 rounded bg-muted/40 px-1.5 py-0.5">
<span className="shrink-0 font-medium text-foreground/90">{tag[0]}</span>
<span className="min-w-0 break-all text-muted-foreground">
{tag.length > 1 ? tag.slice(1).join(' · ') : '—'}
@ -362,7 +376,27 @@ export default function UnknownNote({ @@ -362,7 +376,27 @@ export default function UnknownNote({
)}
</Button>
</CollapsibleTrigger>
<CollapsibleContent className="mt-2">
<CollapsibleContent className="mt-2 space-y-2">
{technicalReferenceTags.length > 0 ? (
<div className="rounded-md border border-border bg-muted/25 px-2 py-1.5">
<p className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground mb-1">
{t('Unknown note reference tags')}
</p>
<ul className="space-y-0.5 font-mono text-[11px] leading-snug text-muted-foreground">
{technicalReferenceTags.map((tag, i) => (
<li key={i} className="break-all">
<span className="text-foreground/80">{tag[0]}</span>
{tag.length > 1 ? (
<>
{' '}
{tag.slice(1).join(' · ')}
</>
) : null}
</li>
))}
</ul>
</div>
) : null}
<EventViewer event={displayEvent} />
</CollapsibleContent>
</Collapsible>

105
src/components/NoteList/index.tsx

@ -61,6 +61,8 @@ import NoteCard, { NoteCardLoadingSkeleton } from '../NoteCard' @@ -61,6 +61,8 @@ import NoteCard, { NoteCardLoadingSkeleton } from '../NoteCard'
const LIMIT = 100 // Increased from 200 to load more events per request
const ALGO_LIMIT = 200 // Increased from 500 for algorithm feeds
/** Single-relay explore: kindless REQ cap (relay returns whatever it has, up to this many). */
const RELAY_EXPLORE_LIMIT = 200
/**
* Vite HMR replaces this module and remounts NoteList; timeline refs reset while the subscription can briefly look
@ -97,11 +99,13 @@ function mergeEventBatchesById(prev: Event[], incoming: Event[], cap: number): E @@ -97,11 +99,13 @@ function mergeEventBatchesById(prev: Event[], incoming: Event[], cap: number): E
/** When omitting `kinds` from a live REQ, require another scope so we never subscribe to a whole relay. */
function timelineFilterHasNonKindScope(f: Filter): boolean {
const search = f.search
return (
(Array.isArray(f.authors) && f.authors.length > 0) ||
(Array.isArray(f.ids) && f.ids.length > 0) ||
(Array.isArray(f['#p']) && f['#p']!.length > 0) ||
(Array.isArray(f['#e']) && f['#e']!.length > 0)
(Array.isArray(f['#e']) && f['#e']!.length > 0) ||
(typeof search === 'string' && search.trim().length > 0)
)
}
@ -114,6 +118,10 @@ const NoteList = forwardRef( @@ -114,6 +118,10 @@ const NoteList = forwardRef(
showKind1Replies = true,
showKind1111 = true,
seeAllFeedEvents = false,
/**
* Single-relay Explore / home chip: REQ omits `kinds`, limit 200, no feed kind filter (relay decides what to send).
*/
allowKindlessRelayExplore = false,
filterMutedNotes = true,
hideReplies = false,
hideUntrustedNotes = false,
@ -184,6 +192,7 @@ const NoteList = forwardRef( @@ -184,6 +192,7 @@ const NoteList = forwardRef(
showKind1111?: boolean
/** Omit REQ kinds and skip client-side kind filtering (main feed testing). Ignored when useFilterAsIs. */
seeAllFeedEvents?: boolean
allowKindlessRelayExplore?: boolean
filterMutedNotes?: boolean
hideReplies?: boolean
hideUntrustedNotes?: boolean
@ -376,11 +385,15 @@ const NoteList = forwardRef( @@ -376,11 +385,15 @@ const NoteList = forwardRef(
() =>
JSON.stringify({
feed: timelineSubscriptionKey,
kinds: showKindsKey,
op: showKind1OPs,
rep: showKind1Replies,
c1111: showKind1111,
seeAll: seeAllFeedEvents
...(allowKindlessRelayExplore
? { relayKindless: true }
: {
kinds: showKindsKey,
op: showKind1OPs,
rep: showKind1Replies,
c1111: showKind1111,
seeAll: seeAllFeedEvents
})
}),
[
timelineSubscriptionKey,
@ -388,14 +401,22 @@ const NoteList = forwardRef( @@ -388,14 +401,22 @@ const NoteList = forwardRef(
showKind1OPs,
showKind1Replies,
showKind1111,
seeAllFeedEvents
seeAllFeedEvents,
allowKindlessRelayExplore
]
)
/** Kindless relay explore ignores the feed kind picker; avoid re-subscribing when it changes. */
const timelineResubscribeKindKey = allowKindlessRelayExplore
? 'kindless-relay-explore'
: `${showKindsKey}|${showKind1OPs}|${showKind1Replies}|${showKind1111}`
const showKindsRef = useRef(showKinds)
showKindsRef.current = showKinds
const seeAllFeedEventsRef = useRef(seeAllFeedEvents)
seeAllFeedEventsRef.current = seeAllFeedEvents
const allowKindlessRelayExploreRef = useRef(allowKindlessRelayExplore)
allowKindlessRelayExploreRef.current = allowKindlessRelayExplore
const useFilterAsIsRef = useRef(useFilterAsIs)
useFilterAsIsRef.current = useFilterAsIs
const clientSideKindFilterRef = useRef(clientSideKindFilter)
@ -464,7 +485,7 @@ const NoteList = forwardRef( @@ -464,7 +485,7 @@ const NoteList = forwardRef(
const idSet = new Set<string>()
return events.slice(0, showCount).filter((evt) => {
if (!seeAllFeedEvents) {
if (!seeAllFeedEvents && !allowKindlessRelayExplore) {
if (!showKinds.includes(evt.kind)) return false
// Kind 1: show only OPs if showKind1OPs, only replies if showKind1Replies
if (evt.kind === kinds.ShortTextNote) {
@ -492,7 +513,8 @@ const NoteList = forwardRef( @@ -492,7 +513,8 @@ const NoteList = forwardRef(
showKind1OPs,
showKind1Replies,
showKind1111,
seeAllFeedEvents
seeAllFeedEvents,
allowKindlessRelayExplore
])
useLayoutEffect(() => {
@ -538,7 +560,7 @@ const NoteList = forwardRef( @@ -538,7 +560,7 @@ const NoteList = forwardRef(
const idSet = new Set<string>()
return newEvents.filter((event: Event) => {
if (!seeAllFeedEvents) {
if (!seeAllFeedEvents && !allowKindlessRelayExplore) {
if (!showKinds.includes(event.kind)) return false
if (event.kind === kinds.ShortTextNote) {
const isReply = isReplyNoteEvent(event)
@ -565,7 +587,8 @@ const NoteList = forwardRef( @@ -565,7 +587,8 @@ const NoteList = forwardRef(
showKind1OPs,
showKind1Replies,
showKind1111,
seeAllFeedEvents
seeAllFeedEvents,
allowKindlessRelayExplore
])
useLayoutEffect(() => {
@ -792,8 +815,16 @@ const NoteList = forwardRef( @@ -792,8 +815,16 @@ const NoteList = forwardRef(
const mappedSubRequests = subRequestsRef.current.map(({ urls, filter }) => {
const baseLimit = filter.limit ?? (areAlgoRelays ? ALGO_LIMIT : LIMIT)
if (useFilterAsIs) {
const finalFilter: Filter = { ...filter, limit: baseLimit }
const hasKindsInRequest = Array.isArray(filter.kinds) && filter.kinds.length > 0
if (allowKindlessRelayExplore && urls.length === 1 && !hasKindsInRequest) {
const finalFilter: Filter = {
...filter,
limit: filter.limit ?? RELAY_EXPLORE_LIMIT
}
delete finalFilter.kinds
return { urls, filter: finalFilter }
}
const finalFilter: Filter = { ...filter, limit: baseLimit }
if (clientSideKindFilter) {
if (hasKindsInRequest) {
finalFilter.kinds = filter.kinds
@ -828,10 +859,13 @@ const NoteList = forwardRef( @@ -828,10 +859,13 @@ const NoteList = forwardRef(
})
const filterMissingKinds = (f: Filter) => !f.kinds || f.kinds.length === 0
const invalidFilters = mappedSubRequests.filter(({ filter: f }) => {
const invalidFilters = mappedSubRequests.filter(({ urls, filter: f }) => {
if (seeAllNoSpell) return false
if (!filterMissingKinds(f)) return false
if (useFilterAsIs && clientSideKindFilter && timelineFilterHasNonKindScope(f)) return false
if (useFilterAsIs && allowKindlessRelayExplore && urls.length === 1) {
return false
}
return true
})
if (invalidFilters.length > 0) {
@ -849,7 +883,7 @@ const NoteList = forwardRef( @@ -849,7 +883,7 @@ const NoteList = forwardRef(
}
const narrowLiveBatch = (evs: Event[]) => {
if (seeAllNoSpell) return evs
if (seeAllFeedEventsRef.current || allowKindlessRelayExploreRef.current) return evs
if (!useFilterAsIs || !clientSideKindFilter) return evs
return evs.filter((e) => showKinds.includes(e.kind))
}
@ -886,7 +920,12 @@ const NoteList = forwardRef( @@ -886,7 +920,12 @@ const NoteList = forwardRef(
let merged = [...byId.values()]
.sort((a, b) => b.created_at - a.created_at)
.slice(0, cap)
if (useFilterAsIs && clientSideKindFilter) {
if (
useFilterAsIs &&
clientSideKindFilter &&
!seeAllFeedEventsRef.current &&
!allowKindlessRelayExploreRef.current
) {
merged = merged.filter((e) => showKinds.includes(e.kind))
}
if (sessionSnap?.length && !userPulledRefresh) {
@ -970,7 +1009,11 @@ const NoteList = forwardRef( @@ -970,7 +1009,11 @@ const NoteList = forwardRef(
}, subscribeSetupRaceMs)
})
const eventCap = areAlgoRelays ? ALGO_LIMIT : LIMIT
const eventCap = allowKindlessRelayExplore
? RELAY_EXPLORE_LIMIT
: areAlgoRelays
? ALGO_LIMIT
: LIMIT
timelineSubscribePromise = client.subscribeTimeline(
mappedSubRequests as Array<{ urls: string[]; filter: TSubRequestFilter }>,
@ -1084,10 +1127,9 @@ const NoteList = forwardRef( @@ -1084,10 +1127,9 @@ const NoteList = forwardRef(
onNew: (event: Event) => {
if (!effectActive) return
feedRelayReturnedAnyEventRef.current = true
const seeAll = seeAllFeedEventsRef.current && !useFilterAsIs
if (!seeAll && !useFilterAsIs && !showKinds.includes(event.kind)) return
if (clientSideKindFilter && useFilterAsIs && !showKinds.includes(event.kind)) return
if (!seeAll) {
if (!seeAllFeedEventsRef.current && !allowKindlessRelayExploreRef.current) {
if (!useFilterAsIs && !showKinds.includes(event.kind)) return
if (clientSideKindFilter && useFilterAsIs && !showKinds.includes(event.kind)) return
if (event.kind === kinds.ShortTextNote) {
const isReply = isReplyNoteEvent(event)
if (isReply && !showKind1Replies) return
@ -1179,10 +1221,7 @@ const NoteList = forwardRef( @@ -1179,10 +1221,7 @@ const NoteList = forwardRef(
mergeTimelineWhenSubRequestFiltersMatch,
feedTimelineScopeKey,
refreshCount,
showKindsKey,
showKind1OPs,
showKind1Replies,
showKind1111,
timelineResubscribeKindKey,
seeAllFeedEvents,
useFilterAsIs,
areAlgoRelays,
@ -1194,7 +1233,8 @@ const NoteList = forwardRef( @@ -1194,7 +1233,8 @@ const NoteList = forwardRef(
oneShotGlobalTimeoutMs,
oneShotEoseTimeoutMs,
oneShotFirstRelayGraceMs,
clientSideKindFilter
clientSideKindFilter,
allowKindlessRelayExplore
])
const oneShotDebugPrevLoadingRef = useRef(false)
@ -1458,14 +1498,17 @@ const NoteList = forwardRef( @@ -1458,14 +1498,17 @@ const NoteList = forwardRef(
}
let fetchBatch = newEvents
let toAppend =
useFilterAsIsRef.current && clientSideKindFilterRef.current
? fetchBatch.filter((e) => showKindsRef.current.includes(e.kind))
: fetchBatch
if (
const narrowLoadMore =
useFilterAsIsRef.current &&
clientSideKindFilterRef.current &&
!seeAllFeedEventsRef.current &&
!allowKindlessRelayExploreRef.current
let toAppend = narrowLoadMore
? fetchBatch.filter((e) => showKindsRef.current.includes(e.kind))
: fetchBatch
if (
narrowLoadMore &&
toAppend.length === 0 &&
fetchBatch.length > 0
) {

2
src/components/Relay/index.tsx

@ -82,6 +82,8 @@ const Relay = forwardRef<TNoteListRef, { url?: string; className?: string }>(fun @@ -82,6 +82,8 @@ const Relay = forwardRef<TNoteListRef, { url?: string; className?: string }>(fun
subRequests={[
{ urls: [normalizedUrl], filter: debouncedInput ? { search: debouncedInput } : {} }
]}
useFilterAsIs
allowKindlessRelayExplore
/>
</div>
)

1
src/i18n/locales/de.ts

@ -1437,6 +1437,7 @@ export default { @@ -1437,6 +1437,7 @@ export default {
'Subscribed to topic (local)': 'Subscribed to topic (local)',
'Subscribing...': 'Subscribing...',
Summary: 'Summary',
'Unknown note reference tags': 'Referenz-Tags (e, p, q, a)',
'Supported Event Types': 'Supported Event Types',
'Take a note': 'Take a note',
'The full prompt conversation (optional)': 'The full prompt conversation (optional)',

1
src/i18n/locales/en.ts

@ -412,6 +412,7 @@ export default { @@ -412,6 +412,7 @@ export default {
'Unknown note declared kind tag': 'Tagged kind: {{value}}',
'Unknown note tagged pubkey': 'Tagged pubkey',
'Unknown note tagged content': 'Content',
'Unknown note reference tags': 'Reference tags (e, p, q, a)',
'Copy JSON': 'Copy JSON',
Verse: 'Verse',
'Notification reaction summary': 'reacted to this note.',

11
src/pages/primary/NoteListPage/RelaysFeed.tsx

@ -75,6 +75,10 @@ const RelaysFeed = forwardRef< @@ -75,6 +75,10 @@ const RelaysFeed = forwardRef<
? showKinds
: [kinds.ShortTextNote]
/** One relay + user kind filter: avoid huge `kinds` REQ (many relays error with "too many kinds"). */
const singleRelayKindlessExplore =
feedInfo.feedType === 'relay' && relayUrls.length === 1 && !kindsOverride?.length
const canRenderFeed =
(feedInfo.feedType === 'relay' ||
feedInfo.feedType === 'relays' ||
@ -95,6 +99,9 @@ const RelaysFeed = forwardRef< @@ -95,6 +99,9 @@ const RelaysFeed = forwardRef<
// Hooks must run every render — never place useMemo after conditional returns.
const subRequests = useMemo(() => {
if (!canRenderFeed) return []
if (singleRelayKindlessExplore) {
return [{ urls: relayUrls, filter: {} }]
}
return [
{
urls: relayUrls,
@ -103,7 +110,7 @@ const RelaysFeed = forwardRef< @@ -103,7 +110,7 @@ const RelaysFeed = forwardRef<
}
}
]
}, [canRenderFeed, relayUrls, defaultKinds, kindsOverride])
}, [canRenderFeed, relayUrls, defaultKinds, kindsOverride, singleRelayKindlessExplore])
if (!canRenderFeed) {
return null
@ -123,6 +130,8 @@ const RelaysFeed = forwardRef< @@ -123,6 +130,8 @@ const RelaysFeed = forwardRef<
onSubHeaderRefresh={onSubHeaderRefresh}
preserveTimelineOnSubRequestsChange
feedTimelineScopeKey={feedTimelineScopeKey}
useFilterAsIs={singleRelayKindlessExplore}
allowKindlessRelayExplore={singleRelayKindlessExplore}
/>
)
})

Loading…
Cancel
Save