From a3e28478bd82db226defef3d643beea4ab8ad7ca Mon Sep 17 00:00:00 2001 From: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:13:37 -0800 Subject: [PATCH] Fix message reaction picker moving when typing stops --- stylesheets/_modules.scss | 4 ++++ ts/components/conversation/Timeline.tsx | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss index b7b5446f2e80..5098219c2a1f 100644 --- a/stylesheets/_modules.scss +++ b/stylesheets/_modules.scss @@ -5946,6 +5946,10 @@ button.module-calling-participants-list__contact { overflow-anchor: auto; } } + &--scroll-locked { + // Component also applies flex-basis to prevent shrinkage + flex-shrink: 0; + } &--have-oldest { justify-content: flex-start; diff --git a/ts/components/conversation/Timeline.tsx b/ts/components/conversation/Timeline.tsx index 0ab49beebaf4..12afbe11abbc 100644 --- a/ts/components/conversation/Timeline.tsx +++ b/ts/components/conversation/Timeline.tsx @@ -167,6 +167,7 @@ export type PropsType = PropsDataType & type StateType = { scrollLocked: boolean; + scrollLockHeight: number | undefined; hasDismissedDirectContactSpoofingWarning: boolean; hasRecentlyScrolled: boolean; lastMeasuredWarningHeight: number; @@ -205,6 +206,7 @@ export class Timeline extends React.Component< // eslint-disable-next-line react/state-in-constructor override state: StateType = { scrollLocked: false, + scrollLockHeight: undefined, hasRecentlyScrolled: true, hasDismissedDirectContactSpoofingWarning: false, @@ -214,8 +216,16 @@ export class Timeline extends React.Component< }; #onScrollLockChange = (): void => { - this.setState({ - scrollLocked: this.#scrollerLock.isLocked(), + const scrollLocked = this.#scrollerLock.isLocked(); + this.setState(() => { + // Prevent scroll due to elements shrinking or disappearing (e.g. typing indicators) + const scrollLockHeight = scrollLocked + ? this.#messagesRef.current?.offsetHeight + : undefined; + return { + scrollLocked, + scrollLockHeight, + }; }); }; @@ -841,6 +851,7 @@ export class Timeline extends React.Component< } = this.props; const { scrollLocked, + scrollLockHeight, hasRecentlyScrolled, lastMeasuredWarningHeight, newestBottomVisibleMessageId, @@ -1142,6 +1153,11 @@ export class Timeline extends React.Component< )} ref={this.#messagesRef} role="list" + style={ + scrollLockHeight + ? { flexBasis: scrollLockHeight } + : undefined + } > {haveOldest && ( <>