Skip to content

Commit ea09013

Browse files
authored
Merge pull request #45613 from margelo/fix/composer-not-clearing-force-clear-event
Composer: add clear command that bypasses the event count
2 parents 8e4dc0f + acae30c commit ea09013

File tree

4 files changed

+93
-4
lines changed

4 files changed

+93
-4
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
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
2+
index 7ce04da..123968f 100644
3+
--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
4+
+++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
5+
@@ -452,6 +452,12 @@ - (void)blur
6+
[_backedTextInputView resignFirstResponder];
7+
}
8+
9+
+- (void)clear
10+
+{
11+
+ [self setTextAndSelection:_mostRecentEventCount value:@"" start:0 end:0];
12+
+ _mostRecentEventCount++;
13+
+}
14+
+
15+
- (void)setTextAndSelection:(NSInteger)eventCount
16+
value:(NSString *__nullable)value
17+
start:(NSInteger)start
18+
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
19+
index fe3376a..6a9a45f 100644
20+
--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h
21+
+++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h
22+
@@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
23+
@protocol RCTTextInputViewProtocol <NSObject>
24+
- (void)focus;
25+
- (void)blur;
26+
+- (void)clear;
27+
- (void)setTextAndSelection:(NSInteger)eventCount
28+
value:(NSString *__nullable)value
29+
start:(NSInteger)start
30+
@@ -49,6 +50,19 @@ RCTTextInputHandleCommand(id<RCTTextInputViewProtocol> componentView, const NSSt
31+
return;
32+
}
33+
34+
+ if ([commandName isEqualToString:@"clear"]) {
35+
+#if RCT_DEBUG
36+
+ if ([args count] != 0) {
37+
+ RCTLogError(
38+
+ @"%@ command %@ received %d arguments, expected %d.", @"TextInput", commandName, (int)[args count], 0);
39+
+ return;
40+
+ }
41+
+#endif
42+
+
43+
+ [componentView clear];
44+
+ return;
45+
+ }
46+
+
47+
if ([commandName isEqualToString:@"setTextAndSelection"]) {
48+
#if RCT_DEBUG
49+
if ([args count] != 4) {
50+
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
51+
index 8496a7d..e6bcfc4 100644
52+
--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java
53+
+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java
54+
@@ -331,6 +331,12 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
55+
}
56+
reactEditText.maybeSetSelection(mostRecentEventCount, start, end);
57+
break;
58+
+ case "clear":
59+
+ int newEventCount = reactEditText.incrementAndGetEventCounter();
60+
+ ReactTextUpdate textUpdate = getReactTextUpdate("", newEventCount);
61+
+ reactEditText.maybeSetTextFromJS(textUpdate);
62+
+ reactEditText.maybeSetSelection(newEventCount, 0, 0);
63+
+ break;
64+
}
65+
}
66+
Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
1+
import type {Component} from 'react';
2+
import type {AnimatedRef} from 'react-native-reanimated';
3+
import {dispatchCommand} from 'react-native-reanimated';
14
import type {AccessibilityRoleForm, NewPasswordAutocompleteType, PasswordAutocompleteType} from './types';
25

36
const PASSWORD_AUTOCOMPLETE_TYPE: PasswordAutocompleteType = 'password';
47
const NEW_PASSWORD_AUTOCOMPLETE_TYPE: NewPasswordAutocompleteType = 'password-new';
58
const ACCESSIBILITY_ROLE_FORM: AccessibilityRoleForm = 'none';
69

7-
export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE};
10+
/**
11+
* Clears a text input on the UI thread using a custom clear command
12+
* that bypasses the event count check.
13+
*/
14+
function forceClearInput(animatedInputRef: AnimatedRef<Component>) {
15+
'worklet';
16+
17+
dispatchCommand(animatedInputRef, 'clear');
18+
}
19+
20+
export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE, forceClearInput};

src/libs/ComponentUtils/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import type {Component} from 'react';
2+
import type {AnimatedRef} from 'react-native-reanimated';
3+
import {setNativeProps} from 'react-native-reanimated';
14
import type {AccessibilityRoleForm, NewPasswordAutocompleteType, PasswordAutocompleteType} from './types';
25

36
/**
@@ -7,4 +10,10 @@ const PASSWORD_AUTOCOMPLETE_TYPE: PasswordAutocompleteType = 'current-password';
710
const NEW_PASSWORD_AUTOCOMPLETE_TYPE: NewPasswordAutocompleteType = 'new-password';
811
const ACCESSIBILITY_ROLE_FORM: AccessibilityRoleForm = 'form';
912

10-
export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE};
13+
function forceClearInput(animatedInputRef: AnimatedRef<Component>) {
14+
'worklet';
15+
16+
setNativeProps(animatedInputRef, {text: ''});
17+
}
18+
19+
export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE, forceClearInput};

src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type {MeasureInWindowOnSuccessCallback, NativeSyntheticEvent, TextInputFo
44
import {View} from 'react-native';
55
import type {OnyxEntry} from 'react-native-onyx';
66
import {withOnyx} from 'react-native-onyx';
7-
import {runOnJS, setNativeProps, useAnimatedRef} from 'react-native-reanimated';
7+
import {runOnJS, useAnimatedRef} from 'react-native-reanimated';
88
import type {Emoji} from '@assets/emojis/types';
99
import type {FileObject} from '@components/AttachmentModal';
1010
import AttachmentModal from '@components/AttachmentModal';
@@ -23,6 +23,7 @@ import useNetwork from '@hooks/useNetwork';
2323
import useThemeStyles from '@hooks/useThemeStyles';
2424
import useWindowDimensions from '@hooks/useWindowDimensions';
2525
import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus';
26+
import {forceClearInput} from '@libs/ComponentUtils';
2627
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
2728
import {getDraftComment} from '@libs/DraftCommentUtils';
2829
import getModalState from '@libs/getModalState';
@@ -366,7 +367,7 @@ function ReportActionCompose({
366367
// We are setting the isCommentEmpty flag to true so the status of it will be in sync of the native text input state
367368
runOnJS(setIsCommentEmpty)(true);
368369
runOnJS(resetFullComposerSize)();
369-
setNativeProps(animatedRef, {text: ''}); // clears native text input on the UI thread
370+
forceClearInput(animatedRef);
370371
runOnJS(submitForm)();
371372
}, [isSendDisabled, resetFullComposerSize, submitForm, animatedRef, isReportReadyForDisplay]);
372373

0 commit comments

Comments
 (0)