move loadMore button to TimelineRenderer
This commit is contained in:
35
packages/app/src/Components/Event/LoadMore.tsx
Normal file
35
packages/app/src/Components/Event/LoadMore.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
import { useEffect } from "react";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
interface ShowMoreProps {
|
||||
text?: string;
|
||||
className?: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
const LoadMore = ({ text, onClick, className = "" }: ShowMoreProps) => {
|
||||
return (
|
||||
<button type="button" className={className} onClick={onClick}>
|
||||
{text || <FormattedMessage defaultMessage="Load more" id="00LcfG" />}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoadMore;
|
||||
|
||||
export function AutoLoadMore({ text, onClick, className }: ShowMoreProps) {
|
||||
const { ref, inView } = useInView({ rootMargin: "2000px" });
|
||||
|
||||
useEffect(() => {
|
||||
if (inView) {
|
||||
onClick();
|
||||
}
|
||||
}, [inView]);
|
||||
|
||||
return (
|
||||
<div ref={ref}>
|
||||
<LoadMore onClick={onClick} text={text} className={className} />
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
import classNames from "classnames";
|
||||
import { useEffect } from "react";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
interface ShowMoreProps {
|
||||
text?: string;
|
||||
className?: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
const ShowMore = ({ text, onClick, className = "" }: ShowMoreProps) => {
|
||||
return (
|
||||
<div className="show-more-container">
|
||||
<button type="button" className={classNames("show-more", className)} onClick={onClick}>
|
||||
{text || <FormattedMessage defaultMessage="Show More" id="O8Z8t9" />}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShowMore;
|
||||
|
||||
export function AutoShowMore({ text, onClick, className }: ShowMoreProps) {
|
||||
const { ref, inView } = useInView({ rootMargin: "2000px" });
|
||||
|
||||
useEffect(() => {
|
||||
if (inView) {
|
||||
onClick();
|
||||
}
|
||||
}, [inView]);
|
||||
|
||||
return (
|
||||
<div ref={ref}>
|
||||
<ShowMore onClick={onClick} text={text} className={className} />
|
||||
</div>
|
||||
);
|
||||
}
|
@ -31,16 +31,6 @@
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.thread-container .show-more {
|
||||
background: var(--gray-superdark);
|
||||
padding-left: 76px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
border-radius: 0;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.subthread-container {
|
||||
position: relative;
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ import "./Timeline.css";
|
||||
|
||||
import { socialGraphInstance, TaggedNostrEvent } from "@snort/system";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector";
|
||||
import { TimelineRenderer } from "@/Components/Feed/TimelineRenderer";
|
||||
@ -18,7 +17,6 @@ export interface TimelineProps {
|
||||
ignoreModeration?: boolean;
|
||||
window?: number;
|
||||
now?: number;
|
||||
loadMore?: boolean;
|
||||
noSort?: boolean;
|
||||
displayAs?: DisplayAs;
|
||||
showDisplayAsSelector?: boolean;
|
||||
@ -91,14 +89,8 @@ const Timeline = (props: TimelineProps) => {
|
||||
latest={latestAuthors}
|
||||
showLatest={t => onShowLatest(t)}
|
||||
displayAs={displayAs}
|
||||
loadMore={() => feed.loadMore()}
|
||||
/>
|
||||
{(props.loadMore === undefined || props.loadMore === true) && (
|
||||
<div className="flex items-center px-3 py-4">
|
||||
<button type="button" onClick={() => feed.loadMore()}>
|
||||
<FormattedMessage defaultMessage="Load more" id="00LcfG" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -4,7 +4,6 @@ import { EventKind, NostrEvent, TaggedNostrEvent } from "@snort/system";
|
||||
import { ReactNode, useCallback, useMemo, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { AutoShowMore } from "@/Components/Event/ShowMore";
|
||||
import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector";
|
||||
import { TimelineRenderer } from "@/Components/Feed/TimelineRenderer";
|
||||
import useTimelineFeed, { TimelineFeedOptions, TimelineSubject } from "@/Feed/TimelineFeed";
|
||||
@ -98,15 +97,8 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
|
||||
}
|
||||
}}
|
||||
displayAs={displayAs}
|
||||
loadMore={() => feed.loadMore()}
|
||||
/>
|
||||
{mainFeed.length > 0 && (
|
||||
<AutoShowMore
|
||||
onClick={() => {
|
||||
feed.loadMore();
|
||||
}}
|
||||
className="mx-3 my-4"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import { useInView } from "react-intersection-observer";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import ErrorBoundary from "@/Components/ErrorBoundary";
|
||||
import { AutoLoadMore } from "@/Components/Event/LoadMore";
|
||||
import { DisplayAs } from "@/Components/Feed/DisplayAsSelector";
|
||||
import ImageGridItem from "@/Components/Feed/ImageGridItem";
|
||||
import { TimelineFragment } from "@/Components/Feed/TimelineFragment";
|
||||
@ -23,6 +24,7 @@ export interface TimelineRendererProps {
|
||||
noteOnClick?: (ev: TaggedNostrEvent) => void;
|
||||
noteContext?: (ev: TaggedNostrEvent) => ReactNode;
|
||||
displayAs?: DisplayAs;
|
||||
loadMore?: () => void;
|
||||
}
|
||||
|
||||
// filter frags[0].events that have media
|
||||
@ -151,6 +153,7 @@ export function TimelineRenderer(props: TimelineRendererProps) {
|
||||
</>
|
||||
)}
|
||||
{props.displayAs === "grid" ? <Grid frags={props.frags} /> : renderNotes()}
|
||||
{props.loadMore && <AutoLoadMore className="mx-3 my-4" onClick={props.loadMore} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user