diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m b/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m index e916023..5049c33 100644 --- a/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m +++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m @@ -4,6 +4,7 @@ // // Created by Elias Nahum on 04-11-20. // Copyright © 2020 Facebook. All rights reserved. +// Updated to remove parent’s default text view // #import "PasteInputView.h" @@ -12,49 +13,78 @@ @implementation PasteInputView { - PasteInputTextView *_backedTextInputView; + // We'll store the custom text view in this ivar + PasteInputTextView *_customBackedTextView; } - (instancetype)initWithBridge:(RCTBridge *)bridge { + // Must call the super’s designated initializer if (self = [super initWithBridge:bridge]) { - _backedTextInputView = [[PasteInputTextView alloc] initWithFrame:self.bounds]; - _backedTextInputView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _backedTextInputView.textInputDelegate = self; + // 1. The parent (RCTMultilineTextInputView) has already created + // its own _backedTextInputView = [RCTUITextView new] in super init. + // We can remove that subview: - [self addSubview:_backedTextInputView]; - } + id parentInputView = super.backedTextInputView; + if ([parentInputView isKindOfClass:[UIView class]]) { + UIView *parentSubview = (UIView *)parentInputView; + if (parentSubview.superview == self) { + [parentSubview removeFromSuperview]; + } + } + // 2. Now create our custom PasteInputTextView + _customBackedTextView = [[PasteInputTextView alloc] initWithFrame:self.bounds]; + _customBackedTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _customBackedTextView.textInputDelegate = self; + + // Optional: disable inline predictions for iOS 17+ + if (@available(iOS 17.0, *)) { + _customBackedTextView.inlinePredictionType = UITextInlinePredictionTypeNo; + } + + // 3. Add your custom text view as the only subview + [self addSubview:_customBackedTextView]; + } return self; } +/** + * Override the parent's accessor so that anywhere in RN that calls + * `self.backedTextInputView` will get the custom PasteInputTextView. + */ - (id)backedTextInputView { - return _backedTextInputView; + return _customBackedTextView; } -- (void)setDisableCopyPaste:(BOOL)disableCopyPaste { - _backedTextInputView.disableCopyPaste = disableCopyPaste; +#pragma mark - Setters for React Props + +- (void)setDisableCopyPaste:(BOOL)disableCopyPaste +{ + _customBackedTextView.disableCopyPaste = disableCopyPaste; } -- (void)setOnPaste:(RCTDirectEventBlock)onPaste { - _backedTextInputView.onPaste = onPaste; +- (void)setOnPaste:(RCTDirectEventBlock)onPaste +{ + _customBackedTextView.onPaste = onPaste; } -- (void)setSmartPunctuation:(NSString *)smartPunctuation { - if ([smartPunctuation isEqualToString:@"enable"]) { - [_backedTextInputView setSmartDashesType:UITextSmartDashesTypeYes]; - [_backedTextInputView setSmartQuotesType:UITextSmartQuotesTypeYes]; - [_backedTextInputView setSmartInsertDeleteType:UITextSmartInsertDeleteTypeYes]; - } else if ([smartPunctuation isEqualToString:@"disable"]) { - [_backedTextInputView setSmartDashesType:UITextSmartDashesTypeNo]; - [_backedTextInputView setSmartQuotesType:UITextSmartQuotesTypeNo]; - [_backedTextInputView setSmartInsertDeleteType:UITextSmartInsertDeleteTypeNo]; - } else { - [_backedTextInputView setSmartDashesType:UITextSmartDashesTypeDefault]; - [_backedTextInputView setSmartQuotesType:UITextSmartQuotesTypeDefault]; - [_backedTextInputView setSmartInsertDeleteType:UITextSmartInsertDeleteTypeDefault]; - } +- (void)setSmartPunctuation:(NSString *)smartPunctuation +{ + if ([smartPunctuation isEqualToString:@"enable"]) { + [_customBackedTextView setSmartDashesType:UITextSmartDashesTypeYes]; + [_customBackedTextView setSmartQuotesType:UITextSmartQuotesTypeYes]; + [_customBackedTextView setSmartInsertDeleteType:UITextSmartInsertDeleteTypeYes]; + } else if ([smartPunctuation isEqualToString:@"disable"]) { + [_customBackedTextView setSmartDashesType:UITextSmartDashesTypeNo]; + [_customBackedTextView setSmartQuotesType:UITextSmartQuotesTypeNo]; + [_customBackedTextView setSmartInsertDeleteType:UITextSmartInsertDeleteTypeNo]; + } else { + [_customBackedTextView setSmartDashesType:UITextSmartDashesTypeDefault]; + [_customBackedTextView setSmartQuotesType:UITextSmartQuotesTypeDefault]; + [_customBackedTextView setSmartInsertDeleteType:UITextSmartInsertDeleteTypeDefault]; + } } #pragma mark - UIScrollViewDelegate @@ -62,7 +92,6 @@ - (void)setSmartPunctuation:(NSString *)smartPunctuation { - (void)scrollViewDidScroll:(UIScrollView *)scrollView { RCTDirectEventBlock onScroll = self.onScroll; - if (onScroll) { CGPoint contentOffset = scrollView.contentOffset; CGSize contentSize = scrollView.contentSize; @@ -71,22 +100,22 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView onScroll(@{ @"contentOffset": @{ - @"x": @(contentOffset.x), - @"y": @(contentOffset.y) + @"x": @(contentOffset.x), + @"y": @(contentOffset.y) }, @"contentInset": @{ - @"top": @(contentInset.top), - @"left": @(contentInset.left), - @"bottom": @(contentInset.bottom), - @"right": @(contentInset.right) + @"top": @(contentInset.top), + @"left": @(contentInset.left), + @"bottom": @(contentInset.bottom), + @"right": @(contentInset.right) }, @"contentSize": @{ - @"width": @(contentSize.width), - @"height": @(contentSize.height) + @"width": @(contentSize.width), + @"height": @(contentSize.height) }, @"layoutMeasurement": @{ - @"width": @(size.width), - @"height": @(size.height) + @"width": @(size.width), + @"height": @(size.height) }, @"zoomScale": @(scrollView.zoomScale ?: 1), }); diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm index dd50053..2ed7017 100644 --- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm +++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm @@ -122,8 +122,8 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & const auto &newTextInputProps = static_cast(*props); // Traits: - if (newTextInputProps.traits.multiline != oldTextInputProps.traits.multiline) { - [self _setMultiline:newTextInputProps.traits.multiline]; + if (newTextInputProps.multiline != oldTextInputProps.multiline) { + [self _setMultiline:newTextInputProps.multiline]; } if (newTextInputProps.traits.autocapitalizationType != oldTextInputProps.traits.autocapitalizationType) { @@ -421,7 +421,7 @@ - (void)textInputDidChangeSelection return; } const auto &props = static_cast(*_props); - if (props.traits.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) { + if (props.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) { [self textInputDidChange]; _ignoreNextTextInputCall = YES; } @@ -708,11 +708,11 @@ - (BOOL)_textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldTe - (SubmitBehavior)getSubmitBehavior { const auto &props = static_cast(*_props); - const SubmitBehavior submitBehaviorDefaultable = props.traits.submitBehavior; + const SubmitBehavior submitBehaviorDefaultable = props.submitBehavior; // We should always have a non-default `submitBehavior`, but in case we don't, set it based on multiline. if (submitBehaviorDefaultable == SubmitBehavior::Default) { - return props.traits.multiline ? SubmitBehavior::Newline : SubmitBehavior::BlurAndSubmit; + return props.multiline ? SubmitBehavior::Newline : SubmitBehavior::BlurAndSubmit; } return submitBehaviorDefaultable; diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp index 29e094f..7ef519a 100644 --- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp +++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp @@ -22,8 +22,7 @@ PasteTextInputProps::PasteTextInputProps( const PropsParserContext &context, const PasteTextInputProps &sourceProps, const RawProps& rawProps) - : ViewProps(context, sourceProps, rawProps), - BaseTextProps(context, sourceProps, rawProps), + : BaseTextInputProps(context, sourceProps, rawProps), traits(convertRawProp(context, rawProps, sourceProps.traits, {})), smartPunctuation(convertRawProp(context, rawProps, "smartPunctuation", sourceProps.smartPunctuation, {})), disableCopyPaste(convertRawProp(context, rawProps, "disableCopyPaste", sourceProps.disableCopyPaste, {false})), @@ -133,7 +132,7 @@ TextAttributes PasteTextInputProps::getEffectiveTextAttributes(Float fontSizeMul ParagraphAttributes PasteTextInputProps::getEffectiveParagraphAttributes() const { auto result = paragraphAttributes; - if (!traits.multiline) { + if (!multiline) { result.maximumNumberOfLines = 1; } diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h index 723d00c..31cfe66 100644 --- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h +++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,7 @@ namespace facebook::react { -class PasteTextInputProps final : public ViewProps, public BaseTextProps { +class PasteTextInputProps final : public BaseTextInputProps { public: PasteTextInputProps() = default; PasteTextInputProps(const PropsParserContext& context, const PasteTextInputProps& sourceProps, const RawProps& rawProps); diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp index 31e07e3..7f0ebfb 100644 --- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp +++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp @@ -91,20 +91,11 @@ void PasteTextInputShadowNode::updateStateIfNeeded( const auto& state = getStateData(); react_native_assert(textLayoutManager_); - react_native_assert( - (!state.layoutManager || state.layoutManager == textLayoutManager_) && - "`StateData` refers to a different `TextLayoutManager`"); - - if (state.reactTreeAttributedString == reactTreeAttributedString && - state.layoutManager == textLayoutManager_) { - return; - } auto newState = TextInputState{}; newState.attributedStringBox = AttributedStringBox{reactTreeAttributedString}; newState.paragraphAttributes = getConcreteProps().paragraphAttributes; newState.reactTreeAttributedString = reactTreeAttributedString; - newState.layoutManager = textLayoutManager_; newState.mostRecentEventCount = getConcreteProps().mostRecentEventCount; setStateData(std::move(newState)); }