Skip to content

Commit eff69d6

Browse files
authored
Merge pull request #50520 from FitseTLT/fix-scroll-problem-on-composer-size-change
Fix - Chat - Compose box stays in the middle when reduced with a several lines message
2 parents 25bd09c + 6542b02 commit eff69d6

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

src/components/Composer/implementation/index.native.tsx

+19
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,25 @@ function Composer(
5757
inputCallbackRef(autoFocus ? textInput.current : null);
5858
}, [autoFocus, inputCallbackRef, autoFocusInputRef]);
5959

60+
useEffect(() => {
61+
if (!textInput.current || !textInput.current.setSelection || !selection || isComposerFullSize) {
62+
return;
63+
}
64+
65+
// We need the delay for setSelection to properly work for IOS in bridgeless mode due to a react native
66+
// internal bug of dispatching the event before the component is ready for it.
67+
// (see https://github.com/Expensify/App/pull/50520#discussion_r1861960311 for more context)
68+
const timeoutID = setTimeout(() => {
69+
// We are setting selection twice to trigger a scroll to the cursor on toggling to smaller composer size.
70+
textInput.current?.setSelection((selection.start || 1) - 1, selection.start);
71+
textInput.current?.setSelection(selection.start, selection.start);
72+
}, 0);
73+
74+
return () => clearTimeout(timeoutID);
75+
76+
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
77+
}, [isComposerFullSize]);
78+
6079
/**
6180
* Set the TextInput Ref
6281
* @param {Element} el

src/components/Composer/implementation/index.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ function Composer(
7575
const [isRendered, setIsRendered] = useState(false);
7676
const isScrollBarVisible = useIsScrollBarVisible(textInput, value ?? '');
7777
const [prevScroll, setPrevScroll] = useState<number | undefined>();
78+
const [prevHeight, setPrevHeight] = useState<number | undefined>();
7879
const isReportFlatListScrolling = useRef(false);
7980

8081
useEffect(() => {
@@ -243,11 +244,11 @@ function Composer(
243244
}, []);
244245

245246
useEffect(() => {
246-
if (!textInput.current || prevScroll === undefined) {
247+
if (!textInput.current || prevScroll === undefined || prevHeight === undefined) {
247248
return;
248249
}
249250
// eslint-disable-next-line react-compiler/react-compiler
250-
textInput.current.scrollTop = prevScroll;
251+
textInput.current.scrollTop = prevScroll + prevHeight - textInput.current.clientHeight;
251252
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
252253
}, [isComposerFullSize]);
253254

@@ -353,6 +354,7 @@ function Composer(
353354
{...props}
354355
onSelectionChange={addCursorPositionToSelectionChange}
355356
onContentSizeChange={(e) => {
357+
setPrevHeight(e.nativeEvent.contentSize.height);
356358
setHasMultipleLines(e.nativeEvent.contentSize.height > variables.componentSizeLarge);
357359
}}
358360
disabled={isDisabled}

0 commit comments

Comments
 (0)