Message List: Disable scrolling in small lists

This commit is contained in:
Alexander Zinchuk 2021-12-04 13:44:41 +01:00
parent 5f988d47b3
commit fadfd6fb74

View File

@ -97,7 +97,7 @@ const BOTTOM_THRESHOLD = 20;
const UNREAD_DIVIDER_TOP = 10; const UNREAD_DIVIDER_TOP = 10;
const UNREAD_DIVIDER_TOP_WITH_TOOLS = 60; const UNREAD_DIVIDER_TOP_WITH_TOOLS = 60;
const SCROLL_DEBOUNCE = 200; const SCROLL_DEBOUNCE = 200;
const FOCUSING_DURATION = 1000; const MESSAGE_ANIMATION_DURATION = 500;
const BOTTOM_FOCUS_MARGIN = 20; const BOTTOM_FOCUS_MARGIN = 20;
const SELECT_MODE_ANIMATION_DURATION = 200; const SELECT_MODE_ANIMATION_DURATION = 200;
const UNREAD_DIVIDER_CLASS = 'unread-divider'; const UNREAD_DIVIDER_CLASS = 'unread-divider';
@ -325,10 +325,20 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
return; return;
} }
const hasLastMessageChanged = (
messageIds && prevMessageIds && messageIds[messageIds.length - 1] !== prevMessageIds[prevMessageIds.length - 1]
);
const hasViewportShifted = (
messageIds?.[0] !== prevMessageIds?.[0] && messageIds?.length === (MESSAGE_LIST_SLICE / 2 + 1)
);
const wasMessageAdded = hasLastMessageChanged && !hasViewportShifted;
const isAlreadyFocusing = messageIds && memoFocusingIdRef.current === messageIds[messageIds.length - 1];
// Add extra height when few messages to allow smooth scroll animation. Uses assumption that `parentElement` // Add extra height when few messages to allow smooth scroll animation. Uses assumption that `parentElement`
// is a Transition slide and its CSS class can not be reset in a declarative way. // is a Transition slide and its CSS class can not be reset in a declarative way.
const shouldForceScroll = ( const shouldForceScroll = (
isViewportNewest isViewportNewest
&& wasMessageAdded
&& (messageIds && messageIds.length < MESSAGE_LIST_SLICE / 2) && (messageIds && messageIds.length < MESSAGE_LIST_SLICE / 2)
&& !container.parentElement!.classList.contains('force-messages-scroll') && !container.parentElement!.classList.contains('force-messages-scroll')
&& (container.firstElementChild as HTMLDivElement)!.clientHeight <= container.offsetHeight * 2 && (container.firstElementChild as HTMLDivElement)!.clientHeight <= container.offsetHeight * 2
@ -341,18 +351,9 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
if (container.parentElement) { if (container.parentElement) {
container.parentElement.classList.remove('force-messages-scroll'); container.parentElement.classList.remove('force-messages-scroll');
} }
}, FOCUSING_DURATION); }, MESSAGE_ANIMATION_DURATION);
} }
const hasLastMessageChanged = (
messageIds && prevMessageIds && messageIds[messageIds.length - 1] !== prevMessageIds[prevMessageIds.length - 1]
);
const hasViewportShifted = (
messageIds?.[0] !== prevMessageIds?.[0] && messageIds?.length === (MESSAGE_LIST_SLICE / 2 + 1)
);
const wasMessageAdded = hasLastMessageChanged && !hasViewportShifted;
const isAlreadyFocusing = messageIds && memoFocusingIdRef.current === messageIds[messageIds.length - 1];
const { scrollTop, scrollHeight, offsetHeight } = container; const { scrollTop, scrollHeight, offsetHeight } = container;
const scrollOffset = scrollOffsetRef.current!; const scrollOffset = scrollOffsetRef.current!;
const lastItemElement = listItemElementsRef.current[listItemElementsRef.current.length - 1]; const lastItemElement = listItemElementsRef.current[listItemElementsRef.current.length - 1];