patch RN to remove JS hack for selectTextOnFocus
This commit is contained in:
@@ -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..34cb289 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);
|
||||||
+ }
|
+ }
|
||||||
|
|||||||
@@ -11,3 +11,23 @@ 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.
|
||||||
|
|
||||||
|
|
||||||
|
## RCTBaseTextInputView Patch - Move `selectAll` call to `reactFocus` method
|
||||||
|
|
||||||
|
Patching `RCTBaseTextInputView.m` to move the `selectAll` call to the `reactFocus` method. Currently, `selectAll` is
|
||||||
|
called in `textInputDidBeginEditing`. This would be fine, however, once `reactFocus` is later called (this happens every
|
||||||
|
time the text field is focused), the selection is reset/removed. The previous solution was to do this:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<TextInput
|
||||||
|
onFocus={() => {
|
||||||
|
if (Platform.OS === 'ios') {
|
||||||
|
textInput.current?.setSelection(0, searchText.length)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
This likely works, because by the time the `onFocus` event is called, `reactFocus` has also already been called. However
|
||||||
|
this is probably unreliable.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {NavigationProp} from '#/lib/routes/types'
|
|||||||
import {augmentSearchQuery} from '#/lib/strings/helpers'
|
import {augmentSearchQuery} from '#/lib/strings/helpers'
|
||||||
import {s} from '#/lib/styles'
|
import {s} from '#/lib/styles'
|
||||||
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 {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
||||||
import {useActorSearch} from '#/state/queries/actor-search'
|
import {useActorSearch} from '#/state/queries/actor-search'
|
||||||
@@ -671,7 +671,7 @@ export function SearchScreen(
|
|||||||
placeholder={_(msg`Search`)}
|
placeholder={_(msg`Search`)}
|
||||||
placeholderTextColor={pal.colors.textLight}
|
placeholderTextColor={pal.colors.textLight}
|
||||||
returnKeyType="search"
|
returnKeyType="search"
|
||||||
value={searchText}
|
// value={searchText}
|
||||||
style={[pal.text, styles.headerSearchInput]}
|
style={[pal.text, styles.headerSearchInput]}
|
||||||
keyboardAppearance={theme.colorScheme}
|
keyboardAppearance={theme.colorScheme}
|
||||||
selectTextOnFocus={isNative}
|
selectTextOnFocus={isNative}
|
||||||
@@ -684,12 +684,6 @@ export function SearchScreen(
|
|||||||
})
|
})
|
||||||
} 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}
|
||||||
|
|||||||
Reference in New Issue
Block a user