Compare commits

...

8 Commits

Author SHA1 Message Date
Samuel Newman 1be1590f0c replace paste-input with RN patch 2025-09-04 13:35:03 +03:00
Samuel Newman 2a91e3a692 Merge branch 'samuel/expo-54' of https://github.com/bluesky-social/social-app into samuel/expo-54 2025-09-04 08:17:31 +03:00
Samuel Newman 7b82cba3ca fix new arch optout 2025-09-04 08:17:28 +03:00
Samuel Newman 5ba314af73 update patches 2025-09-04 08:17:28 +03:00
Samuel Newman 4b9d707cd9 update deps 2025-09-04 08:17:28 +03:00
Samuel Newman 3bcae424e4 fix new arch optout 2025-08-29 09:31:07 +01:00
Samuel Newman bbab450306 update patches 2025-08-29 09:31:07 +01:00
Samuel Newman 6da666dc69 update deps 2025-08-29 09:31:07 +01:00
22 changed files with 2542 additions and 1108 deletions
+1 -2
View File
@@ -43,6 +43,7 @@ module.exports = function (_config) {
icon: './assets/app-icons/ios_icon_default_light.png',
userInterfaceStyle: 'automatic',
primaryColor: '#1083fe',
newArchEnabled: true,
ios: {
supportsTablet: false,
bundleIdentifier: 'xyz.blueskyweb.app',
@@ -207,13 +208,11 @@ module.exports = function (_config) {
{
ios: {
deploymentTarget: '15.1',
newArchEnabled: false,
},
android: {
compileSdkVersion: 35,
targetSdkVersion: 35,
buildToolsVersion: '35.0.0',
newArchEnabled: false,
},
},
],
+52 -53
View File
@@ -90,17 +90,16 @@
"@haileyok/bluesky-video": "0.3.2",
"@ipld/dag-cbor": "^9.2.0",
"@lingui/react": "^4.14.1",
"@mattermost/react-native-paste-input": "mattermost/react-native-paste-input",
"@miblanchard/react-native-slider": "^2.6.0",
"@mozzius/expo-dynamic-app-icon": "^1.7.1",
"@react-native-async-storage/async-storage": "2.1.2",
"@react-native-async-storage/async-storage": "2.2.0",
"@react-native-menu/menu": "^1.2.3",
"@react-native-picker/picker": "2.11.0",
"@react-native-picker/picker": "2.11.1",
"@react-navigation/bottom-tabs": "^7.3.13",
"@react-navigation/drawer": "^7.3.12",
"@react-navigation/native": "^7.1.9",
"@react-navigation/native-stack": "^7.3.13",
"@sentry/react-native": "~6.14.0",
"@sentry/react-native": "~6.20.0",
"@tanstack/query-async-storage-persister": "^5.25.0",
"@tanstack/react-query": "^5.8.1",
"@tanstack/react-query-persist-client": "^5.25.0",
@@ -132,35 +131,35 @@
"emoji-mart": "^5.5.2",
"emoji-regex": "^10.4.0",
"eventemitter3": "^5.0.1",
"expo": "53.0.11",
"expo-application": "~6.1.4",
"expo-blur": "~14.1.5",
"expo-build-properties": "~0.14.6",
"expo-camera": "~16.1.8",
"expo-clipboard": "~7.1.4",
"expo-dev-client": "~5.2.0",
"expo-device": "~7.1.4",
"expo-file-system": "~18.1.10",
"expo-font": "~13.3.1",
"expo-haptics": "~14.1.4",
"expo-image": "^2.4.0",
"expo": "^54.0.0-preview.11",
"expo-application": "~7.0.4",
"expo-blur": "~15.0.4",
"expo-build-properties": "~1.0.5",
"expo-camera": "~17.0.4",
"expo-clipboard": "~8.0.4",
"expo-dev-client": "~6.0.6",
"expo-device": "~8.0.4",
"expo-file-system": "~19.0.6",
"expo-font": "~14.0.5",
"expo-haptics": "~15.0.4",
"expo-image": "~3.0.4",
"expo-image-crop-tool": "^0.1.8",
"expo-image-manipulator": "~13.1.7",
"expo-image-manipulator": "~14.0.4",
"expo-image-picker": "17.0.5",
"expo-intent-launcher": "^12.1.5",
"expo-linear-gradient": "~14.1.5",
"expo-linking": "~7.1.5",
"expo-localization": "~16.1.5",
"expo-media-library": "~17.1.7",
"expo-notifications": "~0.31.3",
"expo-screen-orientation": "~8.1.7",
"expo-sharing": "~13.1.5",
"expo-splash-screen": "~0.30.9",
"expo-system-ui": "~5.0.8",
"expo-task-manager": "~13.1.5",
"expo-updates": "~0.28.14",
"expo-video": "~2.2.1",
"expo-web-browser": "~14.1.6",
"expo-intent-launcher": "~13.0.4",
"expo-linear-gradient": "~15.0.4",
"expo-linking": "~8.0.5",
"expo-localization": "~17.0.4",
"expo-media-library": "~18.0.4",
"expo-notifications": "~0.32.6",
"expo-screen-orientation": "~9.0.4",
"expo-sharing": "~14.0.4",
"expo-splash-screen": "~31.0.6",
"expo-system-ui": "~6.0.4",
"expo-task-manager": "~14.0.4",
"expo-updates": "~29.0.6",
"expo-video": "~3.0.7",
"expo-web-browser": "~15.0.4",
"fast-text-encoding": "^1.0.6",
"history": "^5.3.0",
"hls.js": "^1.6.2",
@@ -179,36 +178,36 @@
"postinstall-postinstall": "^2.1.0",
"psl": "^1.9.0",
"radix-ui": "^1.2.0",
"react": "19.0.0",
"react": "19.1.0",
"react-compiler-runtime": "^19.1.0-rc.1",
"react-dom": "19.0.0",
"react-dom": "19.1.0",
"react-image-crop": "^11.0.7",
"react-is": "19",
"react-keyed-flatten-children": "^5.0.0",
"react-native": "^0.79.3",
"react-native": "^0.81.1",
"react-native-compressor": "^1.11.0",
"react-native-date-picker": "^5.0.12",
"react-native-date-picker": "^5.0.13",
"react-native-device-attest": "^0.1.6",
"react-native-drawer-layout": "^4.1.8",
"react-native-edge-to-edge": "^1.6.0",
"react-native-gesture-handler": "2.25.0",
"react-native-gesture-handler": "~2.28.0",
"react-native-get-random-values": "~1.11.0",
"react-native-ios-context-menu": "^1.15.3",
"react-native-keyboard-controller": "^1.17.5",
"react-native-keyboard-controller": "1.18.5",
"react-native-mmkv": "^2.12.2",
"react-native-pager-view": "6.8.0",
"react-native-pager-view": "6.9.1",
"react-native-progress": "bluesky-social/react-native-progress",
"react-native-qrcode-styled": "^0.3.3",
"react-native-reanimated": "~3.17.5",
"react-native-reanimated": "~3.19.1",
"react-native-root-siblings": "^5.0.1",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "^4.11.1",
"react-native-svg": "15.12.0",
"react-native-safe-area-context": "~5.6.0",
"react-native-screens": "~4.15.4",
"react-native-svg": "15.12.1",
"react-native-uitextview": "^1.4.0",
"react-native-url-polyfill": "^1.3.0",
"react-native-uuid": "^2.0.3",
"react-native-view-shot": "^4.0.3",
"react-native-web": "~0.20.0",
"react-native-web": "^0.21.0",
"react-native-web-webview": "^1.0.2",
"react-native-webview": "^13.13.5",
"react-remove-scroll-bar": "^2.3.8",
@@ -228,13 +227,13 @@
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@babel/runtime": "^7.26.0",
"@expo/config-plugins": "~10.0.2",
"@expo/config-plugins": "~11.0.5",
"@lingui/cli": "^4.14.1",
"@lingui/macro": "^4.14.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
"@react-native/babel-preset": "0.79.3",
"@react-native/eslint-config": "^0.79.3",
"@react-native/typescript-config": "^0.79.3",
"@react-native/babel-preset": "0.81.1",
"@react-native/eslint-config": "^0.81.1",
"@react-native/typescript-config": "^0.81.1",
"@sentry/webpack-plugin": "^3.2.2",
"@testing-library/jest-native": "^5.4.3",
"@testing-library/react-native": "^13.2.0",
@@ -244,7 +243,7 @@
"@types/lodash.isequal": "^4.5.6",
"@types/lodash.shuffle": "^4.2.7",
"@types/psl": "^1.1.1",
"@types/react-dom": "^19.1.2",
"@types/react-dom": "~19.1.7",
"@types/react-responsive": "^8.0.5",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
@@ -252,7 +251,7 @@
"babel-plugin-macros": "^3.1.0",
"babel-plugin-module-resolver": "^5.0.2",
"babel-plugin-react-compiler": "^19.1.0-rc.1",
"babel-preset-expo": "~13.1.11",
"babel-preset-expo": "~14.0.4",
"eslint": "^8.19.0",
"eslint-plugin-bsky-internal": "link:./eslint",
"eslint-plugin-ft-flow": "^2.0.3",
@@ -266,7 +265,7 @@
"husky": "^8.0.3",
"is-ci": "^3.0.1",
"jest": "^29.7.0",
"jest-expo": "~53.0.7",
"jest-expo": "~54.0.5",
"jest-junit": "^16.0.0",
"lint-staged": "^13.2.3",
"lockfile-lint": "^4.14.0",
@@ -276,13 +275,13 @@
"react-refresh": "^0.14.0",
"svgo": "^3.3.2",
"ts-node": "^10.9.1",
"typescript": "~5.8.3",
"typescript": "~5.9.2",
"webpack-bundle-analyzer": "^4.10.1"
},
"resolutions": {
"@expo/image-utils": "0.6.3",
"@react-native/babel-preset": "0.79.3",
"@react-native/normalize-colors": "0.79.3",
"@react-native/babel-preset": "0.81.1",
"@react-native/normalize-colors": "0.81.1",
"@types/react": "^18",
"**/expo-constants": "17.0.3",
"**/expo-device": "7.1.4",
-19
View File
@@ -1,19 +0,0 @@
diff --git a/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt b/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
index f1255e8..a9b49e5 100644
--- a/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
+++ b/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
@@ -112,11 +112,9 @@ class MediaLibraryModule : Module() {
}
AsyncFunction("createAssetAsync") { localUri: String, albumId: String?, promise: Promise ->
- throwUnlessPermissionsGranted {
- withModuleScope(promise) {
- CreateAssetWithAlbumId(context, localUri, promise, true, albumId)
- .execute()
- }
+ withModuleScope(promise) {
+ CreateAssetWithAlbumId(context, localUri, promise, true, albumId)
+ .execute()
}
}
+13
View File
@@ -0,0 +1,13 @@
diff --git a/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt b/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
index 2dc1db2..ee844e8 100644
--- a/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
+++ b/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
@@ -105,7 +105,7 @@ class MediaLibraryModule : Module() {
}
AsyncFunction("createAssetAsync") Coroutine { localUri: String, albumId: String? ->
- requireSystemPermissions()
+ // requireSystemPermissions()
return@Coroutine createAssetWithAlbumId(context, localUri, true, albumId)
}
-136
View File
@@ -1,136 +0,0 @@
diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
index 914a249..0deac55 100644
--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
+++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
@@ -19,6 +19,8 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface RCTPullToRefreshViewComponentView : RCTViewComponentView <RCTCustomPullToRefreshViewProtocol>
+- (void)beginRefreshingProgrammatically;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
index d029337..0f63ea3 100644
--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
+++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
@@ -1003,6 +1003,11 @@ - (void)_adjustForMaintainVisibleContentPosition
}
}
++ (BOOL)shouldBeRecycled
+{
+ return NO;
+}
+
@end
Class<RCTComponentViewProtocol> RCTScrollViewCls(void)
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
index e9b330f..ec5f58c 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
@@ -15,5 +15,8 @@
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) RCTDirectEventBlock onRefresh;
@property (nonatomic, weak) UIScrollView *scrollView;
+@property (nonatomic, copy) UIColor *customTintColor;
+
+- (void)forwarderBeginRefreshing;
@end
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
index 53bfd04..ff1b1ed 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
@@ -23,6 +23,7 @@ @implementation RCTRefreshControl {
UIColor *_titleColor;
CGFloat _progressViewOffset;
BOOL _hasMovedToWindow;
+ UIColor *_customTintColor;
}
- (instancetype)init
@@ -58,6 +59,12 @@ - (void)layoutSubviews
_isInitialRender = false;
}
+- (void)didMoveToSuperview
+{
+ [super didMoveToSuperview];
+ [self setTintColor:_customTintColor];
+}
+
- (void)didMoveToWindow
{
[super didMoveToWindow];
@@ -221,4 +228,50 @@ - (void)refreshControlValueChanged
}
}
+// Fix for https://github.com/facebook/react-native/issues/43388
+// A bug in iOS 17.4 causes the haptic to not play when refreshing if the tintColor
+// is set before the refresh control gets added to the scrollview. We'll call this
+// function whenever the superview changes. We'll also call it if the value of customTintColor
+// changes.
+- (void)setTintColor:(UIColor *)tintColor
+{
+ if ([self.superview isKindOfClass:[UIScrollView class]] && self.tintColor != tintColor) {
+ [super setTintColor:tintColor];
+ }
+}
+
+// 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
+// function.
+- (void)forwarderBeginRefreshing
+{
+ _refreshingProgrammatically = NO;
+
+ [self sizeToFit];
+
+ if (!self.scrollView) {
+ return;
+ }
+
+ UIScrollView *scrollView = (UIScrollView *)self.scrollView;
+
+ [UIView animateWithDuration:0.3
+ delay:0
+ options:UIViewAnimationOptionBeginFromCurrentState
+ animations:^(void) {
+ // Whenever we call this method, the scrollview will always be at a position of
+ // -130 or less. Scrolling back to -65 simulates the default behavior of RCTRefreshControl
+ [scrollView setContentOffset:CGPointMake(0, -65)];
+ }
+ completion:^(__unused BOOL finished) {
+ [super beginRefreshing];
+ [self setCurrentRefreshingState:super.refreshing];
+
+ if (self->_onRefresh) {
+ self->_onRefresh(nil);
+ }
+ }
+ ];
+}
+
@end
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
index 40aaf9c..1c60164 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
@@ -22,11 +22,12 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL)
-RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, CGFloat)
+RCT_REMAP_VIEW_PROPERTY(tintColor, customTintColor, UIColor)
+
RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing)
{
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,17 @@
diff --git a/node_modules/react-native-date-picker/ios/RNDatePicker.h b/node_modules/react-native-date-picker/ios/RNDatePicker.h
index 480746e..470dc3a 100644
--- a/node_modules/react-native-date-picker/ios/RNDatePicker.h
+++ b/node_modules/react-native-date-picker/ios/RNDatePicker.h
@@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_END
#else
#import "DatePicker.h"
#import <UIKit/UIKit.h>
+#include <string>
@interface RNDatePicker : DatePicker
@@ -22,4 +23,3 @@ NS_ASSUME_NONNULL_END
@end
#endif
-
@@ -1,36 +0,0 @@
diff --git a/node_modules/react-native-gesture-handler/apple/RNGestureHandler.mm b/node_modules/react-native-gesture-handler/apple/RNGestureHandler.mm
index 43d11b4..5bf0d32 100644
--- a/node_modules/react-native-gesture-handler/apple/RNGestureHandler.mm
+++ b/node_modules/react-native-gesture-handler/apple/RNGestureHandler.mm
@@ -461,16 +461,23 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
- if ([_handlersToWaitFor count]) {
- RNGestureHandler *handler = [RNGestureHandler findGestureHandlerByRecognizer:otherGestureRecognizer];
- if (handler != nil) {
- for (NSNumber *handlerTag in _handlersToWaitFor) {
- if ([handler.tag isEqual:handlerTag]) {
- return YES;
- }
- }
+ RNGestureHandler *handler = [RNGestureHandler findGestureHandlerByRecognizer:otherGestureRecognizer];
+ if (handler == nil) {
+ return NO;
+ }
+
+ for (NSNumber *handlerTag in _handlersToWaitFor) {
+ if ([handler.tag isEqual:handlerTag]) {
+ return YES;
}
}
+
+ for (NSNumber *handlerTag in handler->_handlersThatShouldWait) {
+ if ([_tag isEqual:handlerTag]) {
+ return YES;
+ }
+ }
+
return NO;
}
@@ -1,44 +0,0 @@
diff --git a/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp b/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp
index eae3989..432745a 100644
--- a/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp
+++ b/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp
@@ -416,6 +416,10 @@ void NativeProxy::progressLayoutAnimation(
tag, newPropsJNI, isSharedTransition);
}
+void NativeProxy::endLayoutAnimation(int tag, bool shouldRemove) {
+ layoutAnimations_->cthis()->endLayoutAnimation(tag, shouldRemove);
+}
+
PlatformDepMethodsHolder NativeProxy::getPlatformDependentMethods() {
#ifdef RCT_NEW_ARCH_ENABLED
// nothing
@@ -455,14 +459,7 @@ PlatformDepMethodsHolder NativeProxy::getPlatformDependentMethods() {
auto progressLayoutAnimation =
bindThis(&NativeProxy::progressLayoutAnimation);
- auto endLayoutAnimation = [weakThis = weak_from_this()](
- int tag, bool removeView) {
- auto strongThis = weakThis.lock();
- if (!strongThis) {
- return;
- }
- strongThis->layoutAnimations_->cthis()->endLayoutAnimation(tag, removeView);
- };
+ auto endLayoutAnimation = bindThis(&NativeProxy::endLayoutAnimation);
auto maybeFlushUiUpdatesQueueFunction =
bindThis(&NativeProxy::maybeFlushUIUpdatesQueue);
diff --git a/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.h b/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.h
index 2ee2cc8..2edb5c9 100644
--- a/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.h
+++ b/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.h
@@ -234,6 +234,8 @@ class NativeProxy : public jni::HybridClass<NativeProxy>,
const jsi::Object &newProps,
bool isSharedTransition);
+ void endLayoutAnimation(int tag, bool shouldRemove);
+
/***
* Wraps a method of `NativeProxy` in a function object capturing `this`
* @tparam TReturn return type of passed method
+11 -19
View File
@@ -6,21 +6,17 @@ import {
useState,
} from 'react'
import {
type NativeSyntheticEvent,
Text as RNText,
type TextInputSelectionChangeEventData,
TextInput as RNTextInput,
type TextInputPasteEvent,
type TextInputSelectionChangeEvent,
View,
} from 'react-native'
import {AppBskyRichtextFacet, RichText} from '@atproto/api'
import PasteInput, {
type PastedFile,
type PasteInputRef, // @ts-expect-error no types when installing from github
} from '@mattermost/react-native-paste-input'
import {POST_IMG_MAX} from '#/lib/constants'
import {downloadAndResize} from '#/lib/media/manip'
import {isUriImage} from '#/lib/media/util'
import {cleanError} from '#/lib/strings/errors'
import {getMentionAt, insertMentionAt} from '#/lib/strings/mention-manip'
import {useTheme} from '#/lib/ThemeContext'
import {isAndroid, isNative} from '#/platform/detection'
@@ -46,11 +42,10 @@ export function TextInput({
setRichText,
onPhotoPasted,
onNewLink,
onError,
...props
}: TextInputProps) {
const {theme: t, fonts} = useAlf()
const textInput = useRef<PasteInputRef>(null)
const textInput = useRef<RNTextInput>(null)
const textInputSelection = useRef<Selection>({start: 0, end: 0})
const theme = useTheme()
const [autocompletePrefix, setAutocompletePrefix] = useState('')
@@ -127,23 +122,20 @@ export function TextInput({
)
const onPaste = useCallback(
async (err: string | undefined, files: PastedFile[]) => {
if (err) {
return onError(cleanError(err))
}
const uris = files.map(f => f.uri)
async (evt: TextInputPasteEvent) => {
const files = evt.nativeEvent.items
const uris = files.map(f => f.data)
const uri = uris.find(isUriImage)
if (uri) {
onPhotoPasted(uri)
}
},
[onError, onPhotoPasted],
[onPhotoPasted],
)
const onSelectionChange = useCallback(
(evt: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => {
(evt: TextInputSelectionChangeEvent) => {
// NOTE we track the input selection using a ref to avoid excessive renders -prf
textInputSelection.current = evt.nativeEvent.selection
},
@@ -215,7 +207,7 @@ export function TextInput({
return (
<View style={[a.flex_1, a.pl_md, hasRightPadding && a.pr_4xl]}>
<PasteInput
<RNTextInput
testID="composerTextInput"
ref={textInput}
onChangeText={onChangeText}
@@ -249,7 +241,7 @@ export function TextInput({
props.style,
]}>
{textDecorated}
</PasteInput>
</RNTextInput>
<Autocomplete
prefix={autocompletePrefix}
onSelect={onSelectAutocompleteItem}
+1134 -799
View File
File diff suppressed because it is too large Load Diff