diff --git a/src/classes/event-store.ts b/src/classes/event-store.ts index 0a5e2f635..4446c691b 100644 --- a/src/classes/event-store.ts +++ b/src/classes/event-store.ts @@ -25,6 +25,9 @@ export default class EventStore { this.onEvent.next(event); } } + getEvent(id:string){ + return this.events.get(id) + } clear() { this.events.clear(); diff --git a/src/classes/timeline-loader.ts b/src/classes/timeline-loader.ts index 40a2fa0f7..1e503691f 100644 --- a/src/classes/timeline-loader.ts +++ b/src/classes/timeline-loader.ts @@ -17,15 +17,12 @@ function addToQuery(filter: NostrRequestFilter, query: NostrQuery) { return { ...filter, ...query }; } -const BLOCK_SIZE = 20; +const BLOCK_SIZE = 30; -type EventFilter = (event: NostrEvent) => boolean; - -class RelayTimelineLoader { +export class RelayTimelineLoader { relay: string; query: NostrRequestFilter; blockSize = BLOCK_SIZE; - private name?: string; private log: Debugger; loading = false; @@ -35,12 +32,11 @@ class RelayTimelineLoader { onBlockFinish = new Subject(); - constructor(relay: string, query: NostrRequestFilter, name: string, log?: Debugger) { + constructor(relay: string, query: NostrRequestFilter, log?: Debugger) { this.relay = relay; this.query = query; - this.name = name; - this.log = log || logger.extend(this.name); + this.log = log || logger.extend(relay); this.events = new EventStore(relay); } @@ -76,6 +72,9 @@ class RelayTimelineLoader { return this.events.addEvent(event); } + getFirstEvent(nth = 0) { + return this.events.getFirstEvent(nth); + } getLastEvent(nth = 0) { return this.events.getLastEvent(nth); } @@ -98,7 +97,7 @@ export class TimelineLoader { private log: Debugger; private subscription: NostrMultiSubscription; - private relayTimelineLoaders = new Map(); + relayTimelineLoaders = new Map(); constructor(name: string) { this.name = name; @@ -131,7 +130,7 @@ export class TimelineLoader { for (const relay of this.relays) { if (!this.relayTimelineLoaders.has(relay)) { - const loader = new RelayTimelineLoader(relay, this.query, this.name, this.log.extend(relay)); + const loader = new RelayTimelineLoader(relay, this.query, this.log.extend(relay)); this.relayTimelineLoaders.set(relay, loader); this.events.connect(loader.events); loader.onBlockFinish.subscribe(this.updateLoading, this); diff --git a/src/hooks/use-timeline-cursor-intersection-callback.ts b/src/hooks/use-timeline-cursor-intersection-callback.ts index 1807f0aa3..3000df21d 100644 --- a/src/hooks/use-timeline-cursor-intersection-callback.ts +++ b/src/hooks/use-timeline-cursor-intersection-callback.ts @@ -1,7 +1,7 @@ import { useInterval } from "react-use"; import { TimelineLoader } from "../classes/timeline-loader"; import { useIntersectionMapCallback } from "../providers/intersection-observer"; -import { getEventUID } from "../helpers/nostr/events"; +import { NostrEvent } from "../types/nostr-event"; export function useTimelineCurserIntersectionCallback(timeline: TimelineLoader) { // if the cursor is set too far ahead and the last block did not overlap with the cursor @@ -13,15 +13,20 @@ export function useTimelineCurserIntersectionCallback(timeline: TimelineLoader) return useIntersectionMapCallback( (map) => { // find oldest event that is visible - for (let i = timeline.timeline.value.length - 1; i >= 0; i--) { - const event = timeline.timeline.value[i]; - - if (map.get(getEventUID(event))?.isIntersecting) { - timeline.setCursor(event.created_at); - timeline.loadNextBlocks(); - return; + let oldestEvent: NostrEvent | undefined = undefined; + for (const [id, intersection] of map) { + if (!intersection.isIntersecting) continue; + const event = timeline.events.getEvent(id); + if (!event) continue; + if (!oldestEvent || event.created_at < oldestEvent.created_at) { + oldestEvent = event; } } + + if (oldestEvent) { + timeline.setCursor(oldestEvent.created_at); + timeline.loadNextBlocks(); + } }, [timeline], ); diff --git a/src/providers/people-list-provider.tsx b/src/providers/people-list-provider.tsx index 975d28cfa..c226cc073 100644 --- a/src/providers/people-list-provider.tsx +++ b/src/providers/people-list-provider.tsx @@ -45,11 +45,9 @@ export type PeopleListProviderProps = PropsWithChildren & { initList?: ListId; }; export default function PeopleListProvider({ children, initList = "following" }: PeopleListProviderProps) { - const [params, setParams] = useSearchParams({ - people: initList, - }); + const [params, setParams] = useSearchParams(); - const selected = params.get("people") as ListId; + const selected = params.get("people") || (initList as ListId); const setSelected = useCallback( (value: ListId) => { setParams((p) => ({ ...searchParamsToJson(p), people: value }));