Fix expanding comments and scroll pagination

This commit is contained in:
saltrafael 2021-10-14 08:54:07 -03:00 committed by infinite-persistence
parent a3302b1be8
commit 03ea298236
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
2 changed files with 33 additions and 8 deletions

View file

@ -92,6 +92,7 @@ function CommentList(props: Props) {
const DEFAULT_SORT = ENABLE_COMMENT_REACTIONS ? SORT_BY.POPULARITY : SORT_BY.NEWEST;
const [sort, setSort] = usePersistedState('comment-sort-by', DEFAULT_SORT);
const [page, setPage] = React.useState(0);
const [commentsToDisplay, setCommentsToDisplay] = React.useState(topLevelComments);
const fetchedCommentsOnce = useFetched(isFetchingComments);
const fetchedReactsOnce = useFetched(isFetchingReacts);
const fetchedLinkedComment = useFetched(isFetchingCommentsById);
@ -103,6 +104,7 @@ function CommentList(props: Props) {
const moreBelow = page < topLevelTotalPages;
const isResolvingComments = topLevelComments && resolvedComments.length !== topLevelComments.length;
const alreadyResolved = !isResolvingComments && resolvedComments.length !== 0;
const canDisplayComments = commentsToDisplay && commentsToDisplay.length === topLevelComments.length;
// Display comments immediately if not fetching reactions
// If not, wait to show comments until reactions are fetched
@ -213,12 +215,12 @@ function CommentList(props: Props) {
}
const handleCommentScroll = debounce(() => {
if (hasDefaultExpansion && shouldFetchNextPage(page, topLevelTotalPages, window, document)) {
if (shouldFetchNextPage(page, topLevelTotalPages, window, document)) {
setPage(page + 1);
}
}, DEBOUNCE_SCROLL_HANDLER_MS);
if (!isFetchingComments && readyToDisplayComments && moreBelow && spinnerRef && spinnerRef.current) {
if (hasDefaultExpansion && !isFetchingComments && canDisplayComments && readyToDisplayComments && moreBelow) {
if (shouldFetchNextPage(page, topLevelTotalPages, window, document, 0)) {
setPage(page + 1);
} else {
@ -226,7 +228,21 @@ function CommentList(props: Props) {
return () => window.removeEventListener('scroll', handleCommentScroll);
}
}
}, [hasDefaultExpansion, isFetchingComments, moreBelow, page, readyToDisplayComments, topLevelTotalPages]);
}, [
canDisplayComments,
hasDefaultExpansion,
isFetchingComments,
moreBelow,
page,
readyToDisplayComments,
topLevelTotalPages,
]);
// Wait to only display topLevelComments after resolved or else
// other components will try to resolve again, like channelThumbnail
useEffect(() => {
if (!isResolvingComments) setCommentsToDisplay(topLevelComments);
}, [isResolvingComments, topLevelComments]);
// Batch resolve comment channel urls
useEffect(() => {
@ -313,7 +329,7 @@ function CommentList(props: Props) {
})}
>
{readyToDisplayComments && pinnedComments && getCommentElems(pinnedComments)}
{readyToDisplayComments && resolvedComments && getCommentElems(resolvedComments)}
{readyToDisplayComments && commentsToDisplay && getCommentElems(commentsToDisplay)}
</ul>
{!hasDefaultExpansion && (
@ -337,7 +353,7 @@ function CommentList(props: Props) {
</div>
)}
{(isFetchingComments || (hasDefaultExpansion && moreBelow)) && (
{(isFetchingComments || (hasDefaultExpansion && moreBelow) || !canDisplayComments) && (
<div className="main--empty" ref={spinnerRef}>
<Spinner type="small" />
</div>

View file

@ -43,8 +43,10 @@ function CommentsReplies(props: Props) {
} = props;
const [isExpanded, setExpanded] = React.useState(true);
const [commentsToDisplay, setCommentsToDisplay] = React.useState(fetchedReplies);
const isResolvingReplies = fetchedReplies && resolvedReplies.length !== fetchedReplies.length;
const alreadyResolved = !isResolvingReplies && resolvedReplies.length !== 0;
const canDisplayComments = commentsToDisplay && commentsToDisplay.length === fetchedReplies.length;
// Batch resolve comment channel urls
React.useEffect(() => {
@ -56,6 +58,12 @@ function CommentsReplies(props: Props) {
if (urisToResolve.length > 0) doResolveUris(urisToResolve);
}, [alreadyResolved, doResolveUris, fetchedReplies]);
// Wait to only display topLevelComments after resolved or else
// other components will try to resolve again, like channelThumbnail
React.useEffect(() => {
if (!isResolvingReplies) setCommentsToDisplay(fetchedReplies);
}, [isResolvingReplies, fetchedReplies]);
return !numDirectReplies ? null : (
<div className="comment__replies-container">
{!isExpanded ? (
@ -73,8 +81,9 @@ function CommentsReplies(props: Props) {
<ul className="comments--replies">
{!isResolvingReplies &&
resolvedReplies.length > 0 &&
resolvedReplies.map((comment) => (
commentsToDisplay &&
commentsToDisplay.length > 0 &&
commentsToDisplay.map((comment) => (
<Comment
threadDepth={threadDepth}
uri={uri}
@ -113,7 +122,7 @@ function CommentsReplies(props: Props) {
/>
</div>
)}
{(isFetchingByParentId[parentId] || isResolvingReplies) && (
{(isFetchingByParentId[parentId] || isResolvingReplies || !canDisplayComments) && (
<div className="comment__replies-container">
<div className="comment__actions--nested">
<Spinner type="small" />