Skip to content

Commit

Permalink
Merge pull request Expensify#29434 from HardikChoudhary24/fix/28149-w…
Browse files Browse the repository at this point in the history
…rong-RTL-text-cursor-position

RTL Text gets renderd properly
  • Loading branch information
neil-marcellini authored Oct 27, 2023
2 parents b15fc21 + ec7860f commit eef8347
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/components/Composer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ function Composer({

StyleSheet.flatten([style, {outline: 'none'}]),
StyleUtils.getComposeTextAreaPadding(numberOfLines, isComposerFullSize),
Browser.isMobileSafari() || Browser.isSafari() ? styles.rtlTextRenderForSafari : {},
],
[style, maxLines, numberOfLines, isComposerFullSize],
);
Expand Down
8 changes: 8 additions & 0 deletions src/libs/convertToLTRForComposer/index.android.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import ConvertToLTRForComposer from './types';

/**
* Android only - Do not convert RTL text to a LTR text for input box using Unicode controls.
* Android does not properly support bidirectional text for mixed content for input box
*/
const convertToLTRForComposer: ConvertToLTRForComposer = (text) => text;
export default convertToLTRForComposer;
34 changes: 34 additions & 0 deletions src/libs/convertToLTRForComposer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import CONST from '../../CONST';
import ConvertToLTRForComposer from './types';

function hasLTRorRTLCharacters(text: string): boolean {
// Regular expressions to match LTR and RTL character ranges.
// eslint-disable-next-line no-control-regex
const ltrPattern = /[\u0001-\u05FF\u0600-\u06FF\u0750-\u077F\uFB50-\uFDFF\uFE70-\uFEFF]/;
const rtlPattern = /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/;

return ltrPattern.test(text) || rtlPattern.test(text);
}

// Converts a given text to ensure it starts with the LTR (Left-to-Right) marker.
const convertToLTRForComposer: ConvertToLTRForComposer = (text) => {
// Ensure the text contains LTR or RTL characters to avoid an unwanted special character at the beginning, even after a backspace deletion.
if (!hasLTRorRTLCharacters(text)) {
return '';
}

// Check if the text contains only spaces. If it does, we do not concatenate it with CONST.UNICODE.LTR,
// as doing so would alter the normal behavior of the input box.
if (/^\s*$/.test(text)) {
return text;
}

// Check if the text already starts with the LTR marker (if so, return as is).
if (text.startsWith(CONST.UNICODE.LTR)) {
return text;
}

// Add the LTR marker to the beginning of the text.
return `${CONST.UNICODE.LTR}${text}`;
};
export default convertToLTRForComposer;
3 changes: 3 additions & 0 deletions src/libs/convertToLTRForComposer/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type ConvertToLTRForComposer = (text: string) => string;

export default ConvertToLTRForComposer;
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import focusWithDelay from '../../../../libs/focusWithDelay';
import useDebounce from '../../../../hooks/useDebounce';
import updateMultilineInputRange from '../../../../libs/UpdateMultilineInputRange';
import * as InputFocus from '../../../../libs/actions/InputFocus';
import convertToLTRForComposer from '../../../../libs/convertToLTRForComposer';

const {RNTextInputReset} = NativeModules;

Expand Down Expand Up @@ -213,7 +214,6 @@ function ComposerWithSuggestions({
(commentValue, shouldDebounceSaveComment) => {
raiseIsScrollLikelyLayoutTriggered();
const {text: newComment, emojis} = EmojiUtils.replaceAndExtractEmojis(commentValue, preferredSkinTone, preferredLocale);

if (!_.isEmpty(emojis)) {
const newEmojis = EmojiUtils.getAddedEmojis(emojis, emojisPresentBefore.current);
if (!_.isEmpty(newEmojis)) {
Expand All @@ -225,9 +225,10 @@ function ComposerWithSuggestions({
debouncedUpdateFrequentlyUsedEmojis();
}
}
const newCommentConverted = convertToLTRForComposer(newComment);
emojisPresentBefore.current = emojis;
setIsCommentEmpty(!!newComment.match(/^(\s)*$/));
setValue(newComment);
setIsCommentEmpty(!!newCommentConverted.match(/^(\s)*$/));
setValue(newCommentConverted);
if (commentValue !== newComment) {
const remainder = ComposerUtils.getCommonSuffixLength(commentValue, newComment);
setSelection({
Expand All @@ -237,22 +238,22 @@ function ComposerWithSuggestions({
}

// Indicate that draft has been created.
if (commentRef.current.length === 0 && newComment.length !== 0) {
if (commentRef.current.length === 0 && newCommentConverted.length !== 0) {
Report.setReportWithDraft(reportID, true);
}

// The draft has been deleted.
if (newComment.length === 0) {
if (newCommentConverted.length === 0) {
Report.setReportWithDraft(reportID, false);
}

commentRef.current = newComment;
commentRef.current = newCommentConverted;
if (shouldDebounceSaveComment) {
debouncedSaveReportComment(reportID, newComment);
debouncedSaveReportComment(reportID, newCommentConverted);
} else {
Report.saveReportComment(reportID, newComment || '');
Report.saveReportComment(reportID, newCommentConverted || '');
}
if (newComment) {
if (newCommentConverted) {
debouncedBroadcastUserIsTyping(reportID);
}
},
Expand Down
5 changes: 5 additions & 0 deletions src/styles/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ const styles = (theme: ThemeDefault) =>
alignItems: 'center',
},

rtlTextRenderForSafari: {
textAlign: 'left',
...writingDirection.ltr,
},

emojiSuggestionsEmoji: {
fontSize: variables.fontSizeMedium,
width: 51,
Expand Down

0 comments on commit eef8347

Please sign in to comment.