Skip to content

Commit

Permalink
Merge pull request #45613 from margelo/fix/composer-not-clearing-forc…
Browse files Browse the repository at this point in the history
…e-clear-event

Composer: add clear command that bypasses the event count
  • Loading branch information
MariaHCD authored Jul 23, 2024
2 parents 8e4dc0f + acae30c commit ea09013
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 4 deletions.
66 changes: 66 additions & 0 deletions patches/react-native+0.73.4+018+textInputClear.patch
Original file line number Diff line number Diff line change
@@ -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 <NSObject>
- (void)focus;
- (void)blur;
+- (void)clear;
- (void)setTextAndSelection:(NSInteger)eventCount
value:(NSString *__nullable)value
start:(NSInteger)start
@@ -49,6 +50,19 @@ RCTTextInputHandleCommand(id<RCTTextInputViewProtocol> 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<ReactEditText, Layout
}
reactEditText.maybeSetSelection(mostRecentEventCount, start, end);
break;
+ case "clear":
+ int newEventCount = reactEditText.incrementAndGetEventCounter();
+ ReactTextUpdate textUpdate = getReactTextUpdate("", newEventCount);
+ reactEditText.maybeSetTextFromJS(textUpdate);
+ reactEditText.maybeSetSelection(newEventCount, 0, 0);
+ break;
}
}

15 changes: 14 additions & 1 deletion src/libs/ComponentUtils/index.native.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import type {Component} from 'react';
import type {AnimatedRef} from 'react-native-reanimated';
import {dispatchCommand} from 'react-native-reanimated';
import type {AccessibilityRoleForm, NewPasswordAutocompleteType, PasswordAutocompleteType} from './types';

const PASSWORD_AUTOCOMPLETE_TYPE: PasswordAutocompleteType = 'password';
const NEW_PASSWORD_AUTOCOMPLETE_TYPE: NewPasswordAutocompleteType = 'password-new';
const ACCESSIBILITY_ROLE_FORM: AccessibilityRoleForm = 'none';

export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE};
/**
* Clears a text input on the UI thread using a custom clear command
* that bypasses the event count check.
*/
function forceClearInput(animatedInputRef: AnimatedRef<Component>) {
'worklet';

dispatchCommand(animatedInputRef, 'clear');
}

export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE, forceClearInput};
11 changes: 10 additions & 1 deletion src/libs/ComponentUtils/index.ts
Original file line number Diff line number Diff line change
@@ -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';

/**
Expand All @@ -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<Component>) {
'worklet';

setNativeProps(animatedInputRef, {text: ''});
}

export {PASSWORD_AUTOCOMPLETE_TYPE, ACCESSIBILITY_ROLE_FORM, NEW_PASSWORD_AUTOCOMPLETE_TYPE, forceClearInput};
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -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]);

Expand Down

0 comments on commit ea09013

Please sign in to comment.