feat: Implement inertial horizontal scrolling for carousel components and enhance text selection handling
This commit is contained in:
@@ -52,7 +52,7 @@ import { eventWithShortcode, factoryEventSentBy, getMxIdLocalPart } from '../../
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { useVirtualPaginator, ItemRange } from '../../hooks/useVirtualPaginator';
|
||||
import { useAlive } from '../../hooks/useAlive';
|
||||
import { autoScrollToBottom, editableActiveElement } from '../../utils/dom';
|
||||
import { autoScrollToBottom, editableActiveElement, isScrolledToBottom } from '../../utils/dom';
|
||||
import {
|
||||
DefaultPlaceholder,
|
||||
CompactPlaceholder,
|
||||
@@ -110,6 +110,7 @@ import { useDocumentFocusChange } from '../../hooks/useDocumentFocusChange';
|
||||
import { RenderMessageContent } from '../../components/RenderMessageContent';
|
||||
import { Image } from '../../components/media';
|
||||
import { ImageViewer } from '../../components/image-viewer';
|
||||
import { useInertialHorizontalScroll } from '../../hooks/useInertialHorizontalScroll';
|
||||
import { roomToParentsAtom } from '../../state/room/roomToParents';
|
||||
import { useRoomUnread } from '../../state/hooks/unread';
|
||||
import { roomToUnreadAtom } from '../../state/room/roomToUnread';
|
||||
@@ -651,7 +652,9 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
useCallback(
|
||||
(mEvt: MatrixEvent) => {
|
||||
const isOwnMessage = mEvt.getSender() === mx.getUserId();
|
||||
const shouldStickToBottom = atBottomRef.current || isOwnMessage;
|
||||
const isBottomPinnedEvent =
|
||||
mEvt.getType() === MessageEvent.RoomMessage || mEvt.getType() === MessageEvent.Sticker;
|
||||
const shouldStickToBottom = atBottomRef.current || (isOwnMessage && isBottomPinnedEvent);
|
||||
|
||||
// Always update timeline with new message
|
||||
setTimeline((ct) => ({
|
||||
@@ -676,10 +679,12 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
setUnreadInfo(getRoomUnreadInfo(room));
|
||||
}
|
||||
|
||||
// Preserve the pre-update bottom state so a newly added message keeps the view pinned.
|
||||
scrollToBottomRef.current.count += 1;
|
||||
scrollToBottomRef.current.smooth = !isOwnMessage;
|
||||
scrollToBottomRef.current.force = shouldStickToBottom;
|
||||
// Preserve the pre-update bottom state so newly added chat messages keep the view pinned.
|
||||
if (shouldStickToBottom) {
|
||||
scrollToBottomRef.current.count += 1;
|
||||
scrollToBottomRef.current.smooth = !isOwnMessage;
|
||||
scrollToBottomRef.current.force = true;
|
||||
}
|
||||
|
||||
// Show unread message preview for incoming messages when not at bottom
|
||||
if (!isOwnMessage && !atBottomRef.current) {
|
||||
@@ -753,7 +758,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
const scrollElement = getScrollElement();
|
||||
if (!editorBaseEntry || !scrollElement) return;
|
||||
|
||||
if (atBottomRef.current) {
|
||||
if (isScrolledToBottom(scrollElement)) {
|
||||
autoScrollToBottom(scrollElement, false, true);
|
||||
}
|
||||
};
|
||||
@@ -774,7 +779,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
const previousHeight = timelineContentHeightRef.current;
|
||||
timelineContentHeightRef.current = nextHeight;
|
||||
|
||||
if (previousHeight === 0 || nextHeight <= previousHeight || !atBottomRef.current) {
|
||||
if (previousHeight === 0 || nextHeight <= previousHeight || !isScrolledToBottom(scrollElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2023,7 +2028,12 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
ref={timelineContentRef}
|
||||
direction="Column"
|
||||
justifyContent="End"
|
||||
style={{ minHeight: '100%', padding: `${config.space.S600} 0` }}
|
||||
style={{
|
||||
minHeight: '100%',
|
||||
padding: `${config.space.S600} 0`,
|
||||
userSelect: 'none',
|
||||
WebkitUserSelect: 'none',
|
||||
}}
|
||||
>
|
||||
{!canPaginateBack && rangeAtStart && getItems().length > 0 && (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user