Skip to content

Commit

Permalink
Merge pull request #30835 from roksanaz/29405-ios-emoji-cursor
Browse files Browse the repository at this point in the history
Fix 29405 cursor displayed before emoji on ios native
  • Loading branch information
youssef-lr authored Dec 28, 2023
2 parents 573f6b7 + 98436b7 commit 88d837c
Showing 1 changed file with 31 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {useIsFocused, useNavigation} from '@react-navigation/native';
import lodashGet from 'lodash/get';
import React, {useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
import {findNodeHandle, NativeModules, View} from 'react-native';
import {findNodeHandle, InteractionManager, NativeModules, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import Composer from '@components/Composer';
Expand All @@ -21,6 +21,7 @@ import getDraftComment from '@libs/ComposerUtils/getDraftComment';
import convertToLTRForComposer from '@libs/convertToLTRForComposer';
import * as EmojiUtils from '@libs/EmojiUtils';
import focusComposerWithDelay from '@libs/focusComposerWithDelay';
import getPlatform from '@libs/getPlatform';
import * as KeyDownListener from '@libs/KeyboardShortcut/KeyDownPressListener';
import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
Expand All @@ -40,6 +41,8 @@ import {defaultProps, propTypes} from './composerWithSuggestionsProps';

const {RNTextInputReset} = NativeModules;

const isIOSNative = getPlatform() === CONST.PLATFORM.IOS;

/**
* Broadcast that the user is typing. Debounced to limit how often we publish client events.
* @param {String} reportID
Expand Down Expand Up @@ -136,6 +139,8 @@ function ComposerWithSuggestions({
const textInputRef = useRef(null);
const insertedEmojisRef = useRef([]);

const syncSelectionWithOnChangeTextRef = useRef(null);

// A flag to indicate whether the onScroll callback is likely triggered by a layout change (caused by text change) or not
const isScrollLikelyLayoutTriggered = useRef(false);
const suggestions = lodashGet(suggestionsRef, 'current.getSuggestions', () => [])();
Expand Down Expand Up @@ -235,6 +240,11 @@ function ComposerWithSuggestions({
setValue(newCommentConverted);
if (commentValue !== newComment) {
const position = Math.max(selection.end + (newComment.length - commentRef.current.length), cursorPosition || 0);

if (isIOSNative) {
syncSelectionWithOnChangeTextRef.current = {position, value: newComment};
}

setSelection({
start: position,
end: position,
Expand Down Expand Up @@ -367,6 +377,25 @@ function ComposerWithSuggestions({
[isKeyboardShown, isSmallScreenWidth, parentReportActions, report, reportActions, reportID, handleSendMessage, suggestionsRef, valueRef],
);

const onChangeText = useCallback(
(commentValue) => {
updateComment(commentValue, true);

if (isIOSNative && syncSelectionWithOnChangeTextRef.current) {
const positionSnapshot = syncSelectionWithOnChangeTextRef.current.position;
syncSelectionWithOnChangeTextRef.current = null;

// ensure that selection is set imperatively after all state changes are effective
InteractionManager.runAfterInteractions(() => {
// note: this implementation is only available on non-web RN, thus the wrapping
// 'if' block contains a redundant (since the ref is only used on iOS) platform check
textInputRef.current.setSelection(positionSnapshot, positionSnapshot);
});
}
},
[updateComment],
);

const onSelectionChange = useCallback(
(e) => {
if (textInputRef.current && textInputRef.current.isFocused() && suggestionsRef.current.onSelectionChange(e)) {
Expand Down Expand Up @@ -531,7 +560,7 @@ function ComposerWithSuggestions({
ref={setTextInputRef}
placeholder={inputPlaceholder}
placeholderTextColor={theme.placeholderText}
onChangeText={(commentValue) => updateComment(commentValue, true)}
onChangeText={onChangeText}
onKeyPress={triggerHotkeyActions}
textAlignVertical="top"
style={[styles.textInputCompose, isComposerFullSize ? styles.textInputFullCompose : styles.textInputCollapseCompose]}
Expand Down

0 comments on commit 88d837c

Please sign in to comment.