diff --git a/patches/react-native+0.73.4+018+textInputClear.patch b/patches/react-native+0.73.4+018+textInputClear.patch new file mode 100644 index 000000000000..1cadce6a0783 --- /dev/null +++ b/patches/react-native+0.73.4+018+textInputClear.patch @@ -0,0 +1,66 @@ +diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +index 7ce04da..123968f 100644 +--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm ++++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +@@ -452,6 +452,12 @@ - (void)blur + [_backedTextInputView resignFirstResponder]; + } + ++- (void)clear ++{ ++ [self setTextAndSelection:_mostRecentEventCount value:@"" start:0 end:0]; ++ _mostRecentEventCount++; ++} ++ + - (void)setTextAndSelection:(NSInteger)eventCount + value:(NSString *__nullable)value + start:(NSInteger)start +diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h +index fe3376a..6a9a45f 100644 +--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h ++++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h +@@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN + @protocol RCTTextInputViewProtocol + - (void)focus; + - (void)blur; ++- (void)clear; + - (void)setTextAndSelection:(NSInteger)eventCount + value:(NSString *__nullable)value + start:(NSInteger)start +@@ -49,6 +50,19 @@ RCTTextInputHandleCommand(id componentView, const NSSt + return; + } + ++ if ([commandName isEqualToString:@"clear"]) { ++#if RCT_DEBUG ++ if ([args count] != 0) { ++ RCTLogError( ++ @"%@ command %@ received %d arguments, expected %d.", @"TextInput", commandName, (int)[args count], 0); ++ return; ++ } ++#endif ++ ++ [componentView clear]; ++ return; ++ } ++ + if ([commandName isEqualToString:@"setTextAndSelection"]) { + #if RCT_DEBUG + if ([args count] != 4) { +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +index 8496a7d..e6bcfc4 100644 +--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +@@ -331,6 +331,12 @@ public class ReactTextInputManager extends BaseViewManager) { + 'worklet'; + + dispatchCommand(animatedInputRef, 'clear'); +} + +export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE, forceClearInput}; diff --git a/src/libs/ComponentUtils/index.ts b/src/libs/ComponentUtils/index.ts index 38abb98594da..38179d0fe361 100644 --- a/src/libs/ComponentUtils/index.ts +++ b/src/libs/ComponentUtils/index.ts @@ -1,3 +1,6 @@ +import type {Component} from 'react'; +import type {AnimatedRef} from 'react-native-reanimated'; +import {setNativeProps} from 'react-native-reanimated'; import type {AccessibilityRoleForm, NewPasswordAutocompleteType, PasswordAutocompleteType} from './types'; /** @@ -7,4 +10,10 @@ const PASSWORD_AUTOCOMPLETE_TYPE: PasswordAutocompleteType = 'current-password'; const NEW_PASSWORD_AUTOCOMPLETE_TYPE: NewPasswordAutocompleteType = 'new-password'; const ACCESSIBILITY_ROLE_FORM: AccessibilityRoleForm = 'form'; -export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE}; +function forceClearInput(animatedInputRef: AnimatedRef) { + 'worklet'; + + setNativeProps(animatedInputRef, {text: ''}); +} + +export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE, forceClearInput}; diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index 6ff163f6ec37..479d7faddc1f 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -4,7 +4,7 @@ import type {MeasureInWindowOnSuccessCallback, NativeSyntheticEvent, TextInputFo import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; -import {runOnJS, setNativeProps, useAnimatedRef} from 'react-native-reanimated'; +import {runOnJS, useAnimatedRef} from 'react-native-reanimated'; import type {Emoji} from '@assets/emojis/types'; import type {FileObject} from '@components/AttachmentModal'; import AttachmentModal from '@components/AttachmentModal'; @@ -23,6 +23,7 @@ import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; +import {forceClearInput} from '@libs/ComponentUtils'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import {getDraftComment} from '@libs/DraftCommentUtils'; import getModalState from '@libs/getModalState'; @@ -366,7 +367,7 @@ function ReportActionCompose({ // We are setting the isCommentEmpty flag to true so the status of it will be in sync of the native text input state runOnJS(setIsCommentEmpty)(true); runOnJS(resetFullComposerSize)(); - setNativeProps(animatedRef, {text: ''}); // clears native text input on the UI thread + forceClearInput(animatedRef); runOnJS(submitForm)(); }, [isSendDisabled, resetFullComposerSize, submitForm, animatedRef, isReportReadyForDisplay]);