Add patch for `RCTBaseTextInput` fixing `selectTextOnFocus` prop (#4533)

* create patch

* remove js fix in `SearchScreen`
zio/stable
Hailey 2024-06-17 00:56:02 -07:00 committed by GitHub
parent 10c6035f31
commit 89be5a442c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 17 deletions

View File

@ -1,3 +1,29 @@
diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
index b0d71dc..9974932 100644
--- a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
@@ -377,10 +377,6 @@ - (void)textInputDidBeginEditing
self.backedTextInputView.attributedText = [NSAttributedString new];
}
- if (_selectTextOnFocus) {
- [self.backedTextInputView selectAll:nil];
- }
-
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeFocus
reactTag:self.reactTag
text:[self.backedTextInputView.attributedText.string copy]
@@ -611,6 +607,10 @@ - (UIView *)reactAccessibilityElement
- (void)reactFocus
{
[self.backedTextInputView reactFocus];
+
+ if (_selectTextOnFocus) {
+ [self.backedTextInputView selectAll:nil];
+ }
}
- (void)reactBlur
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
index e9b330f..1ecdf0a 100644 index e9b330f..1ecdf0a 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
@ -5,7 +31,7 @@ index e9b330f..1ecdf0a 100644
@@ -16,4 +16,6 @@ @@ -16,4 +16,6 @@
@property (nonatomic, copy) RCTDirectEventBlock onRefresh; @property (nonatomic, copy) RCTDirectEventBlock onRefresh;
@property (nonatomic, weak) UIScrollView *scrollView; @property (nonatomic, weak) UIScrollView *scrollView;
+- (void)forwarderBeginRefreshing; +- (void)forwarderBeginRefreshing;
+ +
@end @end
@ -16,7 +42,7 @@ index b09e653..4c32b31 100644
@@ -198,9 +198,53 @@ - (void)refreshControlValueChanged @@ -198,9 +198,53 @@ - (void)refreshControlValueChanged
[self setCurrentRefreshingState:super.refreshing]; [self setCurrentRefreshingState:super.refreshing];
_refreshingProgrammatically = NO; _refreshingProgrammatically = NO;
+ if (@available(iOS 17.4, *)) { + if (@available(iOS 17.4, *)) {
+ if (_currentRefreshingState) { + if (_currentRefreshingState) {
+ UIImpactFeedbackGenerator *feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; + UIImpactFeedbackGenerator *feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
@ -29,7 +55,7 @@ index b09e653..4c32b31 100644
_onRefresh(nil); _onRefresh(nil);
} }
} }
+/* +/*
+ This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native + This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native
+ libraries to perform a refresh of a scrollview and access the refresh control's onRefresh + libraries to perform a refresh of a scrollview and access the refresh control's onRefresh
@ -38,15 +64,15 @@ index b09e653..4c32b31 100644
+- (void)forwarderBeginRefreshing +- (void)forwarderBeginRefreshing
+{ +{
+ _refreshingProgrammatically = NO; + _refreshingProgrammatically = NO;
+ +
+ [self sizeToFit]; + [self sizeToFit];
+ +
+ if (!self.scrollView) { + if (!self.scrollView) {
+ return; + return;
+ } + }
+ +
+ UIScrollView *scrollView = (UIScrollView *)self.scrollView; + UIScrollView *scrollView = (UIScrollView *)self.scrollView;
+ +
+ [UIView animateWithDuration:0.3 + [UIView animateWithDuration:0.3
+ delay:0 + delay:0
+ options:UIViewAnimationOptionBeginFromCurrentState + options:UIViewAnimationOptionBeginFromCurrentState
@ -58,7 +84,7 @@ index b09e653..4c32b31 100644
+ completion:^(__unused BOOL finished) { + completion:^(__unused BOOL finished) {
+ [super beginRefreshing]; + [super beginRefreshing];
+ [self setCurrentRefreshingState:super.refreshing]; + [self setCurrentRefreshingState:super.refreshing];
+ +
+ if (self->_onRefresh) { + if (self->_onRefresh) {
+ self->_onRefresh(nil); + self->_onRefresh(nil);
+ } + }
@ -73,7 +99,7 @@ index 5f5e1ab..aac00b6 100644
+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java +++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java
@@ -99,8 +99,9 @@ public class JavaTimerManager { @@ -99,8 +99,9 @@ public class JavaTimerManager {
} }
// If the JS thread is busy for multiple frames we cancel any other pending runnable. // If the JS thread is busy for multiple frames we cancel any other pending runnable.
- if (mCurrentIdleCallbackRunnable != null) { - if (mCurrentIdleCallbackRunnable != null) {
- mCurrentIdleCallbackRunnable.cancel(); - mCurrentIdleCallbackRunnable.cancel();
@ -81,5 +107,5 @@ index 5f5e1ab..aac00b6 100644
+ if (currentRunnable != null) { + if (currentRunnable != null) {
+ currentRunnable.cancel(); + currentRunnable.cancel();
} }
mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos); mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos);

View File

@ -11,3 +11,10 @@ in the RN repo: https://github.com/facebook/react-native/issues/43388
Patching `RCTRefreshControl.m` and `RCTRefreshControl.h` to add a new `forwarderBeginRefreshing` method to the class. Patching `RCTRefreshControl.m` and `RCTRefreshControl.h` to add a new `forwarderBeginRefreshing` method to the class.
This method is used by `ExpoScrollForwarder` to initiate a refresh of the underlying `UIScrollView` from inside that This method is used by `ExpoScrollForwarder` to initiate a refresh of the underlying `UIScrollView` from inside that
module. module.
## TextInput Patch - `selectTextOnFocus` fix
Patching `RCTBaseTextInputView.m` to fix an issue where `selectTextOnFocus` does not work as expected on iOS 17. This
patch _only_ fixes the Paper version of `TextInput`. If we migrate to Fabric and the fix has not been made upstream,
we can apply the same fix. See https://github.com/facebook/react-native/pull/44307.

View File

@ -30,7 +30,7 @@ import {makeProfileLink} from '#/lib/routes/links'
import {NavigationProp} from '#/lib/routes/types' import {NavigationProp} from '#/lib/routes/types'
import {augmentSearchQuery} from '#/lib/strings/helpers' import {augmentSearchQuery} from '#/lib/strings/helpers'
import {logger} from '#/logger' import {logger} from '#/logger'
import {isIOS, isNative, isWeb} from '#/platform/detection' import {isNative, isWeb} from '#/platform/detection'
import {listenSoftReset} from '#/state/events' import {listenSoftReset} from '#/state/events'
import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete' import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
@ -802,12 +802,6 @@ let SearchInputBox = ({
}) })
} else { } else {
setShowAutocomplete(true) setShowAutocomplete(true)
if (isIOS) {
// We rely on selectTextOnFocus, but it's broken on iOS:
// https://github.com/facebook/react-native/issues/41988
textInput.current?.setSelection(0, searchText.length)
// We still rely on selectTextOnFocus for it to be instant on Android.
}
} }
}} }}
onChangeText={onChangeText} onChangeText={onChangeText}