From 31127705e35132338e247dbead68439e5b9492a2 Mon Sep 17 00:00:00 2001 From: rory Date: Thu, 8 Aug 2024 13:31:08 -0700 Subject: [PATCH] Revert PR #45722 --- ...+0.73.4+024+Add-onPaste-to-TextInput.patch | 674 ------------------ src/components/Composer/index.native.tsx | 18 +- src/components/Composer/types.ts | 3 +- src/stories/Composer.stories.tsx | 5 +- 4 files changed, 4 insertions(+), 696 deletions(-) delete mode 100644 patches/react-native+0.73.4+024+Add-onPaste-to-TextInput.patch diff --git a/patches/react-native+0.73.4+024+Add-onPaste-to-TextInput.patch b/patches/react-native+0.73.4+024+Add-onPaste-to-TextInput.patch deleted file mode 100644 index 0107cb7eb660..000000000000 --- a/patches/react-native+0.73.4+024+Add-onPaste-to-TextInput.patch +++ /dev/null @@ -1,674 +0,0 @@ -diff --git a/node_modules/react-native/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js b/node_modules/react-native/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js -index 55b770d..6d86715 100644 ---- a/node_modules/react-native/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js -+++ b/node_modules/react-native/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js -@@ -464,6 +464,21 @@ export type NativeProps = $ReadOnly<{| - |}>, - >, - -+ /** -+ * Invoked when the user performs the paste action. -+ */ -+ onPaste?: ?DirectEventHandler< -+ $ReadOnly<{| -+ target: Int32, -+ items: $ReadOnlyArray< -+ $ReadOnly<{| -+ type: string, -+ data: string, -+ |}>, -+ >, -+ |}>, -+ >, -+ - /** - * The string that will be rendered before text input has been entered. - */ -@@ -668,6 +683,9 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = { - topScroll: { - registrationName: 'onScroll', - }, -+ topPaste: { -+ registrationName: 'onPaste', -+ }, - }, - validAttributes: { - maxFontSizeMultiplier: true, -@@ -719,6 +737,7 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = { - textBreakStrategy: true, - onScroll: true, - onContentSizeChange: true, -+ onPaste: true, - disableFullscreenUI: true, - includeFontPadding: true, - fontWeight: true, -diff --git a/node_modules/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js b/node_modules/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js -index 8e60c9e..ee383a4 100644 ---- a/node_modules/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js -+++ b/node_modules/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js -@@ -97,6 +97,9 @@ const RCTTextInputViewConfig = { - topChangeSync: { - registrationName: 'onChangeSync', - }, -+ topPaste: { -+ registrationName: 'onPaste', -+ }, - topClear: { - registrationName: 'onClear', - }, -@@ -165,6 +168,7 @@ const RCTTextInputViewConfig = { - onSelectionChange: true, - onContentSizeChange: true, - onScroll: true, -+ onPaste: true, - onChangeSync: true, - onKeyPressSync: true, - onTextInput: true, -diff --git a/node_modules/react-native/Libraries/Components/TextInput/TextInput.d.ts b/node_modules/react-native/Libraries/Components/TextInput/TextInput.d.ts -index 26a477f..280cbe2 100644 ---- a/node_modules/react-native/Libraries/Components/TextInput/TextInput.d.ts -+++ b/node_modules/react-native/Libraries/Components/TextInput/TextInput.d.ts -@@ -483,6 +483,16 @@ export interface TextInputTextInputEventData { - range: {start: number; end: number}; - } - -+/** -+ * @see TextInputProps.onPaste -+ */ -+export interface TextInputPasteEventData extends TargetedEvent { -+ items: Array<{ -+ type: string; -+ data: string; -+ }>; -+} -+ - /** - * @see https://reactnative.dev/docs/textinput#props - */ -@@ -811,6 +821,13 @@ export interface TextInputProps - | ((e: NativeSyntheticEvent) => void) - | undefined; - -+ /** -+ * Invoked when the user performs the paste action. -+ */ -+ onPaste?: -+ | ((e: NativeSyntheticEvent) => void) -+ | undefined; -+ - /** - * The string that will be rendered before text input has been entered - */ -diff --git a/node_modules/react-native/Libraries/Components/TextInput/TextInput.flow.js b/node_modules/react-native/Libraries/Components/TextInput/TextInput.flow.js -index 9adbfe9..b46437d 100644 ---- a/node_modules/react-native/Libraries/Components/TextInput/TextInput.flow.js -+++ b/node_modules/react-native/Libraries/Components/TextInput/TextInput.flow.js -@@ -94,6 +94,18 @@ export type EditingEvent = SyntheticEvent< - |}>, - >; - -+export type PasteEvent = SyntheticEvent< -+ $ReadOnly<{| -+ target: number, -+ items: $ReadOnlyArray< -+ $ReadOnly<{| -+ type: string, -+ data: string, -+ |}>, -+ >, -+ |}>, -+>; -+ - type DataDetectorTypesType = - | 'phoneNumber' - | 'link' -@@ -796,6 +808,11 @@ export type Props = $ReadOnly<{| - */ - onScroll?: ?(e: ScrollEvent) => mixed, - -+ /** -+ * Invoked when the user performs the paste action. -+ */ -+ onPaste?: ?(e: PasteEvent) => mixed, -+ - /** - * The string that will be rendered before text input has been entered. - */ -diff --git a/node_modules/react-native/Libraries/Components/TextInput/TextInput.js b/node_modules/react-native/Libraries/Components/TextInput/TextInput.js -index 346acaa..3ab56a2 100644 ---- a/node_modules/react-native/Libraries/Components/TextInput/TextInput.js -+++ b/node_modules/react-native/Libraries/Components/TextInput/TextInput.js -@@ -132,6 +132,18 @@ export type EditingEvent = SyntheticEvent< - |}>, - >; - -+export type PasteEvent = SyntheticEvent< -+ $ReadOnly<{| -+ target: number, -+ items: $ReadOnlyArray< -+ $ReadOnly<{| -+ type: string, -+ data: string, -+ |}>, -+ >, -+ |}>, -+>; -+ - type DataDetectorTypesType = - | 'phoneNumber' - | 'link' -diff --git a/node_modules/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm b/node_modules/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm -index 582b49c..ac31cb1 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm -+++ b/node_modules/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm -@@ -13,6 +13,9 @@ - #import - #import - -+#import -+#import -+ - @implementation RCTUITextView { - UILabel *_placeholderView; - UITextView *_detachedTextView; -@@ -166,7 +169,30 @@ - (void)setSelectedTextRange:(UITextRange *)selectedTextRange notifyDelegate:(BO - - (void)paste:(id)sender - { - _textWasPasted = YES; -- [super paste:sender]; -+ UIPasteboard *clipboard = [UIPasteboard generalPasteboard]; -+ if (clipboard.hasImages) { -+ for (NSItemProvider *itemProvider in [clipboard itemProviders]) { -+ if ([itemProvider canLoadObjectOfClass:[UIImage class]]) { -+ NSString *identifier = itemProvider.registeredTypeIdentifiers.firstObject; -+ if (identifier != nil) { -+ NSString *MIMEType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)identifier, kUTTagClassMIMEType); -+ NSString *fileExtension = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)identifier, kUTTagClassFilenameExtension); -+ NSString *fileName = [NSString stringWithFormat:@"%@.%@", itemProvider.suggestedName ?: @"file", fileExtension]; -+ NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; -+ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; -+ NSData *fileData = [clipboard dataForPasteboardType:identifier]; -+ [fileData writeToFile:filePath atomically:YES]; -+ [_textInputDelegateAdapter didPaste:MIMEType withData:[fileURL absoluteString]]; -+ } -+ break; -+ } -+ } -+ } else { -+ if (clipboard.hasStrings) { -+ [_textInputDelegateAdapter didPaste:@"text/plain" withData:clipboard.string]; -+ } -+ [super paste:sender]; -+ } - } - - // Turn off scroll animation to fix flaky scrolling. -@@ -258,6 +284,10 @@ - (BOOL)canPerformAction:(SEL)action withSender:(id)sender - return NO; - } - -+ if (action == @selector(paste:) && [UIPasteboard generalPasteboard].hasImages) { -+ return YES; -+ } -+ - return [super canPerformAction:action withSender:sender]; - } - -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h -index 7187177..748c4cc 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h -@@ -36,6 +36,7 @@ NS_ASSUME_NONNULL_BEGIN - - (void)textInputDidChange; - - - (void)textInputDidChangeSelection; -+- (void)textInputDidPaste:(NSString *)type withData:(NSString *)data; - - @optional - -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h -index f1c32e6..0ce9dfe 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h -@@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN - - - (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange; - - (void)selectedTextRangeWasSet; -+- (void)didPaste:(NSString *)type withData:(NSString *)data; - - @end - -@@ -30,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN - - (instancetype)initWithTextView:(UITextView *)backedTextInputView; - - - (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange; -+- (void)didPaste:(NSString *)type withData:(NSString *)data; - - @end - -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm -index 9dca6a5..bc43ab8 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm -@@ -147,6 +147,11 @@ - (void)selectedTextRangeWasSet - [self textFieldProbablyDidChangeSelection]; - } - -+- (void)didPaste:(NSString *)type withData:(NSString *)data -+{ -+ [_backedTextInputView.textInputDelegate textInputDidPaste:type withData:data]; -+} -+ - #pragma mark - Generalization - - - (void)textFieldProbablyDidChangeSelection -@@ -302,4 +307,9 @@ - (void)textViewProbablyDidChangeSelection - [_backedTextInputView.textInputDelegate textInputDidChangeSelection]; - } - -+- (void)didPaste:(NSString *)type withData:(NSString *)data -+{ -+ [_backedTextInputView.textInputDelegate textInputDidPaste:type withData:data]; -+} -+ - @end -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.h b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.h -index 209947d..5092dbd 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.h -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.h -@@ -38,6 +38,7 @@ NS_ASSUME_NONNULL_BEGIN - @property (nonatomic, copy, nullable) RCTDirectEventBlock onChangeSync; - @property (nonatomic, copy, nullable) RCTDirectEventBlock onTextInput; - @property (nonatomic, copy, nullable) RCTDirectEventBlock onScroll; -+@property (nonatomic, copy, nullable) RCTDirectEventBlock onPaste; - - @property (nonatomic, assign) NSInteger mostRecentEventCount; - @property (nonatomic, assign, readonly) NSInteger nativeEventCount; -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm -index b0d71dc..2e42fc9 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm -@@ -562,6 +562,26 @@ - (void)textInputDidChangeSelection - }); - } - -+- (void)textInputDidPaste:(NSString *)type withData:(NSString *)data -+{ -+ if (!_onPaste) { -+ return; -+ } -+ -+ NSMutableArray *items = [NSMutableArray new]; -+ [items addObject:@{ -+ @"type" : type, -+ @"data" : data, -+ }]; -+ -+ NSDictionary *payload = @{ -+ @"target" : self.reactTag, -+ @"items" : items, -+ }; -+ -+ _onPaste(payload); -+} -+ - - (void)updateLocalData - { - [self enforceTextAttributesIfNeeded]; -diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm -index 4785987..16a9b8e 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm -+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm -@@ -67,6 +67,7 @@ @implementation RCTBaseTextInputViewManager { - RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) - RCT_EXPORT_VIEW_PROPERTY(onTextInput, RCTDirectEventBlock) - RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) -+RCT_EXPORT_VIEW_PROPERTY(onPaste, RCTDirectEventBlock) - - RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger) - -diff --git a/node_modules/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.mm b/node_modules/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.mm -index 4d0afd9..a6afc7b 100644 ---- a/node_modules/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.mm -+++ b/node_modules/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.mm -@@ -12,6 +12,9 @@ - #import - #import - -+#import -+#import -+ - @implementation RCTUITextField { - RCTBackedTextFieldDelegateAdapter *_textInputDelegateAdapter; - NSDictionary *_defaultTextAttributes; -@@ -139,6 +142,10 @@ - (BOOL)canPerformAction:(SEL)action withSender:(id)sender - return NO; - } - -+ if (action == @selector(paste:) && [UIPasteboard generalPasteboard].hasImages) { -+ return YES; -+ } -+ - return [super canPerformAction:action withSender:sender]; - } - -@@ -204,7 +211,30 @@ - (void)setSelectedTextRange:(UITextRange *)selectedTextRange notifyDelegate:(BO - - (void)paste:(id)sender - { - _textWasPasted = YES; -- [super paste:sender]; -+ UIPasteboard *clipboard = [UIPasteboard generalPasteboard]; -+ if (clipboard.hasImages) { -+ for (NSItemProvider *itemProvider in [clipboard itemProviders]) { -+ if ([itemProvider canLoadObjectOfClass:[UIImage class]]) { -+ NSString *identifier = itemProvider.registeredTypeIdentifiers.firstObject; -+ if (identifier != nil) { -+ NSString *MIMEType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)identifier, kUTTagClassMIMEType); -+ NSString *fileExtension = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)identifier, kUTTagClassFilenameExtension); -+ NSString *fileName = [NSString stringWithFormat:@"%@.%@", itemProvider.suggestedName ?: @"file", fileExtension]; -+ NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; -+ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; -+ NSData *fileData = [clipboard dataForPasteboardType:identifier]; -+ [fileData writeToFile:filePath atomically:YES]; -+ [_textInputDelegateAdapter didPaste:MIMEType withData:[fileURL absoluteString]]; -+ } -+ break; -+ } -+ } -+ } else { -+ if (clipboard.hasStrings) { -+ [_textInputDelegateAdapter didPaste:@"text/plain" withData:clipboard.string]; -+ } -+ [super paste:sender]; -+ } - } - - #pragma mark - Layout -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 70754bf..3ab2c6a 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 -@@ -426,6 +426,13 @@ - (void)textInputDidChangeSelection - } - } - -+- (void)textInputDidPaste:(NSString *)type withData:(NSString *)data -+{ -+ if (_eventEmitter) { -+ static_cast(*_eventEmitter).onPaste(std::string([type UTF8String]), std::string([data UTF8String])); -+ } -+} -+ - #pragma mark - RCTBackedTextInputDelegate (UIScrollViewDelegate) - - - (void)scrollViewDidScroll:(UIScrollView *)scrollView -diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/PasteWatcher.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/PasteWatcher.java -new file mode 100644 -index 0000000..62f7e35 ---- /dev/null -+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/PasteWatcher.java -@@ -0,0 +1,17 @@ -+/* -+ * Copyright (c) Meta Platforms, Inc. and affiliates. -+ * -+ * This source code is licensed under the MIT license found in the -+ * LICENSE file in the root directory of this source tree. -+ */ -+ -+package com.facebook.react.views.textinput; -+ -+/** -+ * Implement this interface to be informed of paste event in the -+ * ReactTextEdit This is used by the ReactTextInputManager to forward events -+ * from the EditText to JS -+ */ -+interface PasteWatcher { -+ public void onPaste(String type, String data); -+} -\ No newline at end of file -diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java -index 081f2b8..ff91d47 100644 ---- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java -+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java -@@ -9,14 +9,17 @@ package com.facebook.react.views.textinput; - - import static com.facebook.react.uimanager.UIManagerHelper.getReactContext; - --import android.content.ClipData; - import android.content.ClipboardManager; -+import android.content.ClipData; -+import android.content.ClipDescription; -+import android.content.ContentResolver; - import android.content.Context; - import android.graphics.Color; - import android.graphics.Paint; - import android.graphics.Rect; - import android.graphics.Typeface; - import android.graphics.drawable.Drawable; -+import android.net.Uri; - import android.os.Build; - import android.os.Bundle; - import android.text.Editable; -@@ -110,6 +113,7 @@ public class ReactEditText extends AppCompatEditText { - private @Nullable SelectionWatcher mSelectionWatcher; - private @Nullable ContentSizeWatcher mContentSizeWatcher; - private @Nullable ScrollWatcher mScrollWatcher; -+ private @Nullable PasteWatcher mPasteWatcher; - private InternalKeyListener mKeyListener; - private boolean mDetectScrollMovement = false; - private boolean mOnKeyPress = false; -@@ -153,6 +157,7 @@ public class ReactEditText extends AppCompatEditText { - mKeyListener = new InternalKeyListener(); - } - mScrollWatcher = null; -+ mPasteWatcher = null; - mTextAttributes = new TextAttributes(); - - applyTextAttributes(); -@@ -307,10 +312,31 @@ public class ReactEditText extends AppCompatEditText { - */ - @Override - public boolean onTextContextMenuItem(int id) { -- if (id == android.R.id.paste) { -+ if (id == android.R.id.paste || id == android.R.id.pasteAsPlainText) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - id = android.R.id.pasteAsPlainText; -- } else { -+ if (mPasteWatcher != null) { -+ ClipboardManager clipboardManager = -+ (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); -+ ClipData clipData = clipboardManager.getPrimaryClip(); -+ String type = null; -+ String data = null; -+ if (clipData.getDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) { -+ type = ClipDescription.MIMETYPE_TEXT_PLAIN; -+ data = clipData.getItemAt(0).getText().toString(); -+ } else { -+ Uri itemUri = clipData.getItemAt(0).getUri(); -+ if (itemUri != null) { -+ ContentResolver cr = getReactContext(this).getContentResolver(); -+ type = cr.getType(itemUri); -+ data = itemUri.toString(); -+ } -+ } -+ if (type != null && data != null) { -+ mPasteWatcher.onPaste(type, data); -+ } -+ } -+ } else if (id == android.R.id.paste) { - ClipboardManager clipboard = - (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); - ClipData previousClipData = clipboard.getPrimaryClip(); -@@ -389,6 +415,10 @@ public class ReactEditText extends AppCompatEditText { - mScrollWatcher = scrollWatcher; - } - -+ public void setPasteWatcher(PasteWatcher pasteWatcher) { -+ mPasteWatcher = pasteWatcher; -+ } -+ - /** - * Attempt to set a selection or fail silently. Intentionally meant to handle bad inputs. - * EventCounter is the same one used as with text. -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 53e5c49..26dc163 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 -@@ -277,6 +277,9 @@ public class ReactTextInputManager extends BaseViewManager { -+ -+ private static final String EVENT_NAME = "topPaste"; -+ -+ private String mType; -+ private String mData; -+ -+ @Deprecated -+ public ReactTextInputPasteEvent(int viewId, String type, String data) { -+ this(ViewUtil.NO_SURFACE_ID, viewId, type, data); -+ } -+ -+ public ReactTextInputPasteEvent(int surfaceId, int viewId, String type, String data) { -+ super(surfaceId, viewId); -+ mType = type; -+ mData = data; -+ } -+ -+ @Override -+ public String getEventName() { -+ return EVENT_NAME; -+ } -+ -+ @Override -+ public boolean canCoalesce() { -+ return false; -+ } -+ -+ @Nullable -+ @Override -+ protected WritableMap getEventData() { -+ WritableMap eventData = Arguments.createMap(); -+ -+ WritableArray items = Arguments.createArray(); -+ WritableMap item = Arguments.createMap(); -+ item.putString("type", mType); -+ item.putString("data", mData); -+ items.pushMap(item); -+ -+ eventData.putArray("items", items); -+ -+ return eventData; -+ } -+} -\ No newline at end of file -diff --git a/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.cpp b/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.cpp -index 1c10b11..de51df9 100644 ---- a/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.cpp -+++ b/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.cpp -@@ -198,6 +198,19 @@ void TextInputEventEmitter::onScroll( - }); - } - -+void TextInputEventEmitter::onPaste(const std::string& type, const std::string& data) const { -+ dispatchEvent("onPaste", [type, data](jsi::Runtime& runtime) { -+ auto payload = jsi::Object(runtime); -+ auto items = jsi::Array(runtime, 1); -+ auto item = jsi::Object(runtime); -+ item.setProperty(runtime, "type", type); -+ item.setProperty(runtime, "data", data); -+ items.setValueAtIndex(runtime, 0, item); -+ payload.setProperty(runtime, "items", items); -+ return payload; -+ }); -+} -+ - void TextInputEventEmitter::dispatchTextInputEvent( - const std::string& name, - const TextInputMetrics& textInputMetrics, -diff --git a/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.h b/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.h -index bc5e624..07ccabc 100644 ---- a/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.h -+++ b/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.h -@@ -48,6 +48,7 @@ class TextInputEventEmitter : public ViewEventEmitter { - void onKeyPress(const KeyPressMetrics& keyPressMetrics) const; - void onKeyPressSync(const KeyPressMetrics& keyPressMetrics) const; - void onScroll(const TextInputMetrics& textInputMetrics) const; -+ void onPaste(const std::string& type, const std::string& data) const; - - private: - void dispatchTextInputEvent( diff --git a/src/components/Composer/index.native.tsx b/src/components/Composer/index.native.tsx index c932c5d798f7..a9b888a26959 100644 --- a/src/components/Composer/index.native.tsx +++ b/src/components/Composer/index.native.tsx @@ -1,9 +1,8 @@ import type {MarkdownStyle} from '@expensify/react-native-live-markdown'; import type {ForwardedRef} from 'react'; import React, {useCallback, useMemo, useRef} from 'react'; -import type {NativeSyntheticEvent, TextInput, TextInputChangeEventData, TextInputPasteEventData} from 'react-native'; +import type {TextInput} from 'react-native'; import {StyleSheet} from 'react-native'; -import type {FileObject} from '@components/AttachmentModal'; import type {AnimatedMarkdownTextInputRef} from '@components/RNMarkdownTextInput'; import RNMarkdownTextInput from '@components/RNMarkdownTextInput'; import useMarkdownStyle from '@hooks/useMarkdownStyle'; @@ -21,7 +20,6 @@ const excludeReportMentionStyle: Array = ['mentionReport']; function Composer( { onClear: onClearProp = () => {}, - onPasteFile = () => {}, isDisabled = false, maxLines, isComposerFullSize = false, @@ -71,19 +69,6 @@ function Composer( }, [onClearProp], ); - const pasteFile = useCallback( - (e: NativeSyntheticEvent) => { - const clipboardContent = e.nativeEvent.items[0]; - if (clipboardContent.type === 'text/plain') { - return; - } - const fileURI = clipboardContent.data; - const fileName = fileURI.split('/').pop(); - const file: FileObject = {uri: fileURI, name: fileName, type: clipboardContent.type}; - onPasteFile(file); - }, - [onPasteFile], - ); const maxHeightStyle = useMemo(() => StyleUtils.getComposerMaxHeightStyle(maxLines, isComposerFullSize), [StyleUtils, isComposerFullSize, maxLines]); const composerStyle = useMemo(() => StyleSheet.flatten([style, textContainsOnlyEmojis ? styles.onlyEmojisTextLineHeight : {}]), [style, textContainsOnlyEmojis, styles]); @@ -105,7 +90,6 @@ function Composer( /* eslint-disable-next-line react/jsx-props-no-spreading */ {...props} readOnly={isDisabled} - onPaste={pasteFile} onBlur={(e) => { if (!isFocused) { // eslint-disable-next-line react-compiler/react-compiler diff --git a/src/components/Composer/types.ts b/src/components/Composer/types.ts index 8287e2de3f2d..e6d8a882f3b8 100644 --- a/src/components/Composer/types.ts +++ b/src/components/Composer/types.ts @@ -1,5 +1,4 @@ import type {NativeSyntheticEvent, StyleProp, TextInputProps, TextInputSelectionChangeEventData, TextStyle} from 'react-native'; -import type {FileObject} from '@components/AttachmentModal'; type TextSelection = { start: number; @@ -38,7 +37,7 @@ type ComposerProps = Omit & { onChangeText?: (numberOfLines: string) => void; /** Callback method to handle pasting a file */ - onPasteFile?: (file: FileObject) => void; + onPasteFile?: (file: File) => void; /** General styles to apply to the text input */ // eslint-disable-next-line react/forbid-prop-types diff --git a/src/stories/Composer.stories.tsx b/src/stories/Composer.stories.tsx index a92dc0e789a0..805f2b4c7448 100644 --- a/src/stories/Composer.stories.tsx +++ b/src/stories/Composer.stories.tsx @@ -3,7 +3,6 @@ import type {Meta} from '@storybook/react'; import {ExpensiMark} from 'expensify-common'; import React, {useState} from 'react'; import {Image, View} from 'react-native'; -import type {FileObject} from '@components/AttachmentModal'; import Composer from '@components/Composer'; import type {ComposerProps} from '@components/Composer/types'; import RenderHTML from '@components/RenderHTML'; @@ -30,7 +29,7 @@ const parser = new ExpensiMark(); function Default(props: ComposerProps) { const StyleUtils = useStyleUtils(); - const [pastedFile, setPastedFile] = useState(null); + const [pastedFile, setPastedFile] = useState(null); const [comment, setComment] = useState(props.defaultValue); const renderedHTML = parser.replace(comment ?? ''); @@ -54,7 +53,7 @@ function Default(props: ComposerProps) { Rendered Comment {!!renderedHTML && } - {!!pastedFile && pastedFile instanceof File && ( + {!!pastedFile && (