feat: defer loading notes
This commit is contained in:
parent
0d9aa0d5ca
commit
dda07d66d5
@ -1,18 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
|
||||
export default function LazyImage(props: any) {
|
||||
const { ref, inView, entry } = useInView();
|
||||
const [shown, setShown] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setShown(s => {
|
||||
if (!s && inView) {
|
||||
return true;
|
||||
}
|
||||
return s;
|
||||
})
|
||||
}, [inView]);
|
||||
|
||||
return shown ? <img {...props} /> : <div ref={ref}></div>
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
.note {
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid var(--gray);
|
||||
min-height: 140px;
|
||||
}
|
||||
|
||||
.note.thread {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import "./Note.css";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { default as NEvent } from "../nostr/Event";
|
||||
@ -11,6 +11,7 @@ import NoteTime from "./NoteTime";
|
||||
import EventKind from "../nostr/EventKind";
|
||||
import useProfile from "../feed/ProfileFeed";
|
||||
import { TaggedRawEvent, u256 } from "../nostr";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
|
||||
export interface NoteProps {
|
||||
data?: TaggedRawEvent,
|
||||
@ -32,6 +33,8 @@ export default function Note(props: NoteProps) {
|
||||
const pubKeys = useMemo(() => ev.Thread?.PubKeys || [], [ev]);
|
||||
const users = useProfile(pubKeys);
|
||||
const deletions = useMemo(() => getReactions(related, ev.Id, EventKind.Deletion), [related]);
|
||||
const { ref, inView } = useInView();
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
const options = {
|
||||
showHeader: true,
|
||||
@ -46,7 +49,13 @@ export default function Note(props: NoteProps) {
|
||||
return (<b className="error">Deleted</b>);
|
||||
}
|
||||
return <Text content={body} tags={ev.Tags} users={users || new Map()} />;
|
||||
}, [props]);
|
||||
}, [ev]);
|
||||
|
||||
useEffect(() => {
|
||||
if (inView && !visible) {
|
||||
setVisible(true);
|
||||
}
|
||||
}, [inView]);
|
||||
|
||||
function goToEvent(e: any, id: u256) {
|
||||
if (!window.location.pathname.startsWith("/e/")) {
|
||||
@ -92,8 +101,10 @@ export default function Note(props: NoteProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function content() {
|
||||
if (!visible) return null;
|
||||
return (
|
||||
<div className={`note ${highlight ? "active" : ""} ${isThread ? "thread" : ""}`}>
|
||||
<>
|
||||
{options.showHeader ?
|
||||
<div className="header flex">
|
||||
<ProfileImage pubkey={ev.RootPubKey} subHeader={replyTag() ?? undefined} />
|
||||
@ -106,6 +117,13 @@ export default function Note(props: NoteProps) {
|
||||
{transformBody()}
|
||||
</div>
|
||||
{options.showFooter ? <NoteFooter ev={ev} related={related} /> : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`note${highlight ? " active" : ""}${isThread ? " thread" : ""}`} ref={ref}>
|
||||
{content()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import { TwitterTweetEmbed } from "react-twitter-embed";
|
||||
import { UrlRegex, FileExtensionRegex, MentionRegex, InvoiceRegex, YoutubeUrlRegex, TweetUrlRegex, HashtagRegex } from "../Const";
|
||||
import { eventLink, hexToBech32 } from "../Util";
|
||||
import Invoice from "./Invoice";
|
||||
import LazyImage from "./LazyImage";
|
||||
import Hashtag from "./Hashtag";
|
||||
|
||||
import './Text.css'
|
||||
@ -28,7 +27,7 @@ function transformHttpLink(a: string) {
|
||||
case "png":
|
||||
case "bmp":
|
||||
case "webp": {
|
||||
return <LazyImage key={url} src={url} />;
|
||||
return <img key={url.toString()} src={url.toString()} />;
|
||||
}
|
||||
case "mp4":
|
||||
case "mov":
|
||||
|
Loading…
Reference in New Issue
Block a user