Fix linked-comment auto scroll
## Ticket 6946: Linked-comment scroll position is inconsistent ## Issues - If it is a deeply-nested reply, the positioning is incorrect. - If there are pinned comments, the positioning is way off. - If there is a delay in mounting, the positioning doesn't happen. - When clicking on the comment's date to highlight it, the comment goes missing and the scroll position is weird. ## Changes - Take into account that replies can be linked-comments. - Perform a "one-time" search for the linked-comment after the initial fetch, if necessary. The expensive DOM search is only be executed minimally.
This commit is contained in:
parent
a9672a4b5c
commit
be9dca362d
3 changed files with 22 additions and 7 deletions
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import * as ICONS from 'constants/icons';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import { COMMENT_HIGHLIGHTED } from 'constants/classnames';
|
||||
import { SORT_BY, COMMENT_PAGE_SIZE_REPLIES } from 'constants/comment';
|
||||
import { FF_MAX_CHARS_IN_COMMENT } from 'constants/form-field';
|
||||
import { SITE_NAME, SIMPLE_SITE, ENABLE_COMMENT_REACTIONS } from 'config';
|
||||
|
@ -220,7 +221,7 @@ function Comment(props: Props) {
|
|||
>
|
||||
<div
|
||||
className={classnames('comment__content', {
|
||||
'comment--highlighted': linkedCommentId && linkedCommentId === commentId,
|
||||
[COMMENT_HIGHLIGHTED]: linkedCommentId && linkedCommentId === commentId,
|
||||
'comment--slimed': slimedToDeath && !displayDeadComment,
|
||||
})}
|
||||
>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import * as REACTION_TYPES from 'constants/reactions';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import { COMMENT_HIGHLIGHTED } from 'constants/classnames';
|
||||
import { COMMENT_PAGE_SIZE_TOP_LEVEL, SORT_BY } from 'constants/comment';
|
||||
import React, { useEffect } from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
@ -18,6 +19,9 @@ import { getChannelIdFromClaim } from 'util/claim';
|
|||
|
||||
const DEBOUNCE_SCROLL_HANDLER_MS = 200;
|
||||
|
||||
// "3" due to 2 separate fetches needed + 1 buffer just in case.
|
||||
const MAX_LINKED_COMMENT_SCROLL_ATTEMPTS = 3;
|
||||
|
||||
function scaleToDevicePixelRatio(value) {
|
||||
const devicePixelRatio = window.devicePixelRatio || 1.0;
|
||||
if (devicePixelRatio < 1.0) {
|
||||
|
@ -75,11 +79,13 @@ function CommentList(props: Props) {
|
|||
settingsByChannelId,
|
||||
} = props;
|
||||
|
||||
const commentRef = React.useRef();
|
||||
const spinnerRef = React.useRef();
|
||||
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 [lcScrollAttempts, setLcScrollAttempts] = React.useState(
|
||||
linkedCommentId ? 0 : MAX_LINKED_COMMENT_SCROLL_ATTEMPTS
|
||||
);
|
||||
const isMobile = useIsMobile();
|
||||
const [expandedComments, setExpandedComments] = React.useState(!isMobile);
|
||||
const totalFetchedComments = allCommentIds ? allCommentIds.length : 0;
|
||||
|
@ -196,11 +202,19 @@ function CommentList(props: Props) {
|
|||
|
||||
// Scroll to linked-comment
|
||||
useEffect(() => {
|
||||
if (readyToDisplayComments && linkedCommentId && commentRef && commentRef.current) {
|
||||
commentRef.current.scrollIntoView({ block: 'start' });
|
||||
window.scrollBy(0, -125);
|
||||
if (lcScrollAttempts < MAX_LINKED_COMMENT_SCROLL_ATTEMPTS && readyToDisplayComments && !isFetchingComments) {
|
||||
const elems = document.getElementsByClassName(COMMENT_HIGHLIGHTED);
|
||||
if (elems.length > 0) {
|
||||
setLcScrollAttempts(MAX_LINKED_COMMENT_SCROLL_ATTEMPTS);
|
||||
const linkedComment = elems[0];
|
||||
linkedComment.scrollIntoView({ block: 'start' });
|
||||
window.scrollBy(0, -125);
|
||||
} else {
|
||||
setLcScrollAttempts(lcScrollAttempts + 1);
|
||||
}
|
||||
}
|
||||
}, [readyToDisplayComments, linkedCommentId]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [readyToDisplayComments, isFetchingComments]); // We just want to respond to these, nothing else.
|
||||
|
||||
// Infinite scroll
|
||||
useEffect(() => {
|
||||
|
@ -321,7 +335,6 @@ function CommentList(props: Props) {
|
|||
comments: expandedComments,
|
||||
'comments--contracted': !expandedComments,
|
||||
})}
|
||||
ref={commentRef}
|
||||
>
|
||||
{readyToDisplayComments && pinnedComments && getCommentElems(pinnedComments)}
|
||||
{readyToDisplayComments && topLevelComments && getCommentElems(topLevelComments)}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export const COMMENT_HIGHLIGHTED = 'comment--highlighted';
|
Loading…
Add table
Reference in a new issue