mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-11 21:29:26 +02:00
improve dvm feed loading
This commit is contained in:
parent
d1f3e4dc2b
commit
c77a457972
@ -0,0 +1,64 @@
|
||||
import { ReactNode, memo, useRef } from "react";
|
||||
import { Kind } from "nostr-tools";
|
||||
import { Box, Text } from "@chakra-ui/react";
|
||||
|
||||
import { ErrorBoundary } from "../../error-boundary";
|
||||
import ReplyNote from "./reply-note";
|
||||
import Note from "../../note";
|
||||
import RepostNote from "./repost-note";
|
||||
import ArticleNote from "./article-note";
|
||||
import StreamNote from "./stream-note";
|
||||
import RelayRecommendation from "./relay-recommendation";
|
||||
import BadgeAwardCard from "../../../views/badges/components/badge-award-card";
|
||||
import { useRegisterIntersectionEntity } from "../../../providers/intersection-observer";
|
||||
import { getEventUID, isReply } from "../../../helpers/nostr/events";
|
||||
import { STREAM_KIND } from "../../../helpers/nostr/stream";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
|
||||
function GenericTimelineNote({
|
||||
event,
|
||||
visible,
|
||||
minHeight,
|
||||
}: {
|
||||
event: NostrEvent;
|
||||
visible: boolean;
|
||||
minHeight?: number;
|
||||
}) {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
useRegisterIntersectionEntity(ref, getEventUID(event));
|
||||
|
||||
let content: ReactNode | null = null;
|
||||
switch (event.kind) {
|
||||
case Kind.Text:
|
||||
content = isReply(event) ? <ReplyNote event={event} /> : <Note event={event} showReplyButton />;
|
||||
break;
|
||||
case Kind.Repost:
|
||||
content = <RepostNote event={event} />;
|
||||
break;
|
||||
case Kind.Article:
|
||||
content = <ArticleNote article={event} />;
|
||||
break;
|
||||
case STREAM_KIND:
|
||||
content = <StreamNote event={event} />;
|
||||
break;
|
||||
case Kind.RecommendRelay:
|
||||
content = <RelayRecommendation event={event} />;
|
||||
break;
|
||||
case Kind.BadgeAward:
|
||||
content = <BadgeAwardCard award={event} />;
|
||||
break;
|
||||
default:
|
||||
content = <Text>Unknown event kind: {event.kind}</Text>;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<Box minHeight={minHeight} ref={ref}>
|
||||
{visible && content}
|
||||
</Box>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(GenericTimelineNote);
|
@ -1,68 +1,15 @@
|
||||
import { ReactNode, memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Box, Button, Text } from "@chakra-ui/react";
|
||||
import { Kind } from "nostr-tools";
|
||||
import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Box, Button } from "@chakra-ui/react";
|
||||
import dayjs from "dayjs";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useThrottle } from "react-use";
|
||||
|
||||
import useSubject from "../../../hooks/use-subject";
|
||||
import TimelineLoader from "../../../classes/timeline-loader";
|
||||
import RepostNote from "./repost-note";
|
||||
import { Note } from "../../note";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import { STREAM_KIND } from "../../../helpers/nostr/stream";
|
||||
import StreamNote from "./stream-note";
|
||||
import { ErrorBoundary } from "../../error-boundary";
|
||||
import { getEventUID, isReply } from "../../../helpers/nostr/events";
|
||||
import ReplyNote from "./reply-note";
|
||||
import RelayRecommendation from "./relay-recommendation";
|
||||
import {
|
||||
ExtendedIntersectionObserverEntry,
|
||||
useIntersectionObserver,
|
||||
useRegisterIntersectionEntity,
|
||||
} from "../../../providers/intersection-observer";
|
||||
import BadgeAwardCard from "../../../views/badges/components/badge-award-card";
|
||||
import ArticleNote from "./article-note";
|
||||
import SuperMap from "../../../classes/super-map";
|
||||
import { useDebounce, useThrottle } from "react-use";
|
||||
|
||||
function RenderEvent({ event, visible, minHeight }: { event: NostrEvent; visible: boolean; minHeight?: number }) {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
useRegisterIntersectionEntity(ref, getEventUID(event));
|
||||
|
||||
let content: ReactNode | null = null;
|
||||
switch (event.kind) {
|
||||
case Kind.Text:
|
||||
content = isReply(event) ? <ReplyNote event={event} /> : <Note event={event} showReplyButton />;
|
||||
break;
|
||||
case Kind.Repost:
|
||||
content = <RepostNote event={event} />;
|
||||
break;
|
||||
case Kind.Article:
|
||||
content = <ArticleNote article={event} />;
|
||||
break;
|
||||
case STREAM_KIND:
|
||||
content = <StreamNote event={event} />;
|
||||
break;
|
||||
case Kind.RecommendRelay:
|
||||
content = <RelayRecommendation event={event} />;
|
||||
break;
|
||||
case Kind.BadgeAward:
|
||||
content = <BadgeAwardCard award={event} />;
|
||||
break;
|
||||
default:
|
||||
content = <Text>Unknown event kind: {event.kind}</Text>;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<Box minHeight={minHeight} ref={ref}>
|
||||
{visible && content}
|
||||
</Box>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
const RenderEventMemo = memo(RenderEvent);
|
||||
import { getEventUID } from "../../../helpers/nostr/events";
|
||||
import { ExtendedIntersectionObserverEntry, useIntersectionObserver } from "../../../providers/intersection-observer";
|
||||
import GenericTimelineNote from "./generic-timeline-note";
|
||||
|
||||
const NOTE_BUFFER = 5;
|
||||
const timelineNoteMinHeightCache = new WeakMap<TimelineLoader, Record<string, Record<string, number>>>();
|
||||
@ -206,7 +153,7 @@ function GenericNoteTimeline({ timeline }: { timeline: TimelineLoader }) {
|
||||
</Box>
|
||||
)}
|
||||
{notes.map((note) => (
|
||||
<RenderEventMemo
|
||||
<GenericTimelineNote
|
||||
key={note.id}
|
||||
event={note}
|
||||
visible={note.created_at <= maxDate}
|
||||
|
@ -1,26 +1,20 @@
|
||||
import { useCallback } from "react";
|
||||
|
||||
import { ChainedDVMJob, getEventIdsFromJobs } from "../../../helpers/nostr/dvm";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import FeedStatus from "./feed-status";
|
||||
import useTimelineLoader from "../../../hooks/use-timeline-loader";
|
||||
import GenericNoteTimeline from "../../../components/timeline-page/generic-note-timeline";
|
||||
import { AddressPointer } from "nostr-tools/lib/types/nip19";
|
||||
import useSingleEvents from "../../../hooks/use-single-events";
|
||||
import GenericTimelineNote from "../../../components/timeline-page/generic-note-timeline/generic-timeline-note";
|
||||
|
||||
function FeedEvents({ chain }: { chain: ChainedDVMJob[] }) {
|
||||
const eventIds = getEventIdsFromJobs(chain);
|
||||
const customSort = useCallback(
|
||||
(a: NostrEvent, b: NostrEvent) => {
|
||||
return eventIds.indexOf(a.id) - eventIds.indexOf(b.id);
|
||||
},
|
||||
[eventIds],
|
||||
const events = useSingleEvents(eventIds);
|
||||
|
||||
return (
|
||||
<>
|
||||
{events.map((event) => (
|
||||
<GenericTimelineNote event={event} visible />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const timeline = useTimelineLoader(`${chain[0].request.id}-events`, readRelays, { ids: eventIds }, { customSort });
|
||||
|
||||
return <GenericNoteTimeline timeline={timeline} />;
|
||||
}
|
||||
|
||||
export default function Feed({ chain, pointer }: { chain: ChainedDVMJob[]; pointer: AddressPointer }) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user