Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ PODS:
- React-Core
- RNReactNativeHapticFeedback (1.14.0):
- React-Core
- RNReanimated (3.0.0-rc.10):
- RNReanimated (3.1.0):
- DoubleConversion
- FBLazyVector
- FBReactNativeSpec
Expand Down Expand Up @@ -1118,7 +1118,7 @@ SPEC CHECKSUMS:
RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81
RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c
RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c
RNReanimated: fbc356493970e3acddc15586b1bccb5eab3ff1ec
RNReanimated: b1220a0e5168745283ff5d53bfc7d2144b2cee1b
RNScreens: 0df01424e9e0ed7827200d6ed1087ddd06c493f9
RNSVG: 38ca962c970dbce1ca38991a5aebf26d163f9efb
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
Expand Down
1 change: 1 addition & 0 deletions jest/setup.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'setimmediate';
import 'react-native-gesture-handler/jestSetup';
import * as reanimatedJestUtils from 'react-native-reanimated/src/reanimated2/jestUtils';
import setupMockImages from './setupMockImages';
Expand Down
57 changes: 34 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
"react-native-picker-select": "git+https://github.com/Expensify/react-native-picker-select.git#107b3786ae6bc155dec05c7fc5ee525d3421dc21",
"react-native-plaid-link-sdk": "^10.0.0",
"react-native-quick-sqlite": "^8.0.0-beta.2",
"react-native-reanimated": "3.0.0-rc.10",
"react-native-reanimated": "3.1.0",
"react-native-render-html": "6.3.1",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "3.17.0",
Expand Down Expand Up @@ -196,14 +196,15 @@
"metro-react-native-babel-preset": "^0.73.3",
"mock-fs": "^4.13.0",
"onchange": "^7.1.0",
"prettier": "^2.8.8",
"portfinder": "^1.0.28",
"prettier": "^2.8.8",
"pusher-js-mock": "^0.3.3",
"react-native-clean-project": "^4.0.0-alpha4.0",
"react-native-flipper": "https://gitpkg.now.sh/facebook/flipper/react-native/react-native-flipper?9cacc9b59402550eae866e0e81e5f0c2f8203e6b",
"react-native-performance-flipper-reporter": "^2.0.0",
"react-native-svg-transformer": "^1.0.0",
"react-test-renderer": "18.1.0",
"setimmediate": "^1.0.5",
"shellcheck": "^1.1.0",
"style-loader": "^2.0.0",
"time-analytics-webpack-plugin": "^0.1.17",
Expand Down
177 changes: 177 additions & 0 deletions patches/react-native-reanimated+3.1.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
diff --git a/node_modules/react-native-reanimated/ios/REANodesManager.mm b/node_modules/react-native-reanimated/ios/REANodesManager.mm
index 26bb253..4108293 100644
--- a/node_modules/react-native-reanimated/ios/REANodesManager.mm
+++ b/node_modules/react-native-reanimated/ios/REANodesManager.mm
@@ -85,19 +85,77 @@ - (void)runSyncUIUpdatesWithObserver:(id<RCTUIManagerObserver>)observer

@end

-@interface REANodesManager () <RCTUIManagerObserver>
+#ifndef RCT_NEW_ARCH_ENABLED

+@interface REASyncUpdateObserver : NSObject <RCTUIManagerObserver>
@end

+@implementation REASyncUpdateObserver {
+ volatile void (^_mounting)(void);
+ volatile BOOL _waitTimedOut;
+ dispatch_semaphore_t _semaphore;
+}
+
+- (instancetype)init
+{
+ self = [super init];
+ if (self) {
+ _mounting = nil;
+ _waitTimedOut = NO;
+ _semaphore = dispatch_semaphore_create(0);
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ RCTAssert(_mounting == nil, @"Mouting block was set but never executed. This may lead to UI inconsistencies");
+}
+
+- (void)unblockUIThread
+{
+ RCTAssertUIManagerQueue();
+ dispatch_semaphore_signal(_semaphore);
+}
+
+- (void)waitAndMountWithTimeout:(NSTimeInterval)timeout
+{
+ RCTAssertMainQueue();
+ long result = dispatch_semaphore_wait(_semaphore, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC));
+ if (result != 0) {
+ @synchronized(self) {
+ _waitTimedOut = YES;
+ }
+ }
+ if (_mounting) {
+ _mounting();
+ _mounting = nil;
+ }
+}
+
+- (BOOL)uiManager:(RCTUIManager *)manager performMountingWithBlock:(RCTUIManagerMountingBlock)block
+{
+ RCTAssertUIManagerQueue();
+ @synchronized(self) {
+ if (_waitTimedOut) {
+ return NO;
+ } else {
+ _mounting = block;
+ return YES;
+ }
+ }
+}
+
+@end
+
+#endif
+
@implementation REANodesManager {
CADisplayLink *_displayLink;
BOOL _wantRunUpdates;
NSMutableArray<REAOnAnimationCallback> *_onAnimationCallbacks;
BOOL _tryRunBatchUpdatesSynchronously;
REAEventHandler _eventHandler;
- volatile void (^_mounting)(void);
- NSObject *_syncLayoutUpdatesWaitLock;
- volatile BOOL _syncLayoutUpdatesWaitTimedOut;
NSMutableDictionary<NSNumber *, ComponentUpdate *> *_componentUpdateBuffer;
NSMutableDictionary<NSNumber *, UIView *> *_viewRegistry;
#ifdef RCT_NEW_ARCH_ENABLED
@@ -125,7 +183,6 @@ - (nonnull instancetype)initWithModule:(REAModule *)reanimatedModule
_operationsInBatch = [NSMutableDictionary new];
_componentUpdateBuffer = [NSMutableDictionary new];
_viewRegistry = [_uiManager valueForKey:@"_viewRegistry"];
- _syncLayoutUpdatesWaitLock = [NSObject new];
}

_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onAnimationFrame:)];
@@ -241,19 +298,6 @@ - (void)onAnimationFrame:(CADisplayLink *)displayLink
}
}

-- (BOOL)uiManager:(RCTUIManager *)manager performMountingWithBlock:(RCTUIManagerMountingBlock)block
-{
- RCTAssert(_mounting == nil, @"Mouting block is expected to not be set");
- @synchronized(_syncLayoutUpdatesWaitLock) {
- if (_syncLayoutUpdatesWaitTimedOut) {
- return NO;
- } else {
- _mounting = block;
- return YES;
- }
- }
-}
-
- (void)performOperations
{
#ifdef RCT_NEW_ARCH_ENABLED
@@ -268,8 +312,7 @@ - (void)performOperations
_tryRunBatchUpdatesSynchronously = NO;

__weak __typeof__(self) weakSelf = self;
- dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
- _syncLayoutUpdatesWaitTimedOut = NO;
+ REASyncUpdateObserver *syncUpdateObserver = [REASyncUpdateObserver new];
RCTExecuteOnUIManagerQueue(^{
__typeof__(self) strongSelf = weakSelf;
if (strongSelf == nil) {
@@ -278,7 +321,7 @@ - (void)performOperations
BOOL canUpdateSynchronously = trySynchronously && ![strongSelf.uiManager hasEnqueuedUICommands];

if (!canUpdateSynchronously) {
- dispatch_semaphore_signal(semaphore);
+ [syncUpdateObserver unblockUIThread];
}

for (int i = 0; i < copiedOperationsQueue.count; i++) {
@@ -286,8 +329,8 @@ - (void)performOperations
}

if (canUpdateSynchronously) {
- [strongSelf.uiManager runSyncUIUpdatesWithObserver:strongSelf];
- dispatch_semaphore_signal(semaphore);
+ [strongSelf.uiManager runSyncUIUpdatesWithObserver:syncUpdateObserver];
+ [syncUpdateObserver unblockUIThread];
}
// In case canUpdateSynchronously=true we still have to send uiManagerWillPerformMounting event
// to observers because some components (e.g. TextInput) update their UIViews only on that event.
@@ -298,17 +341,7 @@ - (void)performOperations
// from CADisplayLink but it is easier to hardcode it for the time being.
// The reason why we use frame duration here is that if takes longer than one frame to complete layout tasks
// there is no point of synchronizing layout with the UI interaction as we get that one frame delay anyways.
- long result = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 16 * NSEC_PER_MSEC));
- if (result != 0) {
- @synchronized(_syncLayoutUpdatesWaitLock) {
- _syncLayoutUpdatesWaitTimedOut = YES;
- }
- }
- }
-
- if (_mounting) {
- _mounting();
- _mounting = nil;
+ [syncUpdateObserver waitAndMountWithTimeout:0.016];
}
}
_wantRunUpdates = NO;
diff --git a/node_modules/react-native-reanimated/mock.js b/node_modules/react-native-reanimated/mock.js
index 68b20d2..b088001 100644
--- a/node_modules/react-native-reanimated/mock.js
+++ b/node_modules/react-native-reanimated/mock.js
@@ -41,6 +41,9 @@ const Reanimated = {
createAnimatedComponent: (Component) => Component,
addWhitelistedUIProps: NOOP,
addWhitelistedNativeProps: NOOP,
+
+ // used by react-navigation fork
+ isConfigured: () => true,
};

module.exports = {
17 changes: 12 additions & 5 deletions src/components/AvatarCropModal/ImageCropView.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,23 @@ const defaultProps = {
const ImageCropView = (props) => {
const containerStyle = StyleUtils.getWidthAndHeightStyle(props.containerSize, props.containerSize);

const originalImageHeight = props.originalImageHeight;
Comment thread
roryabraham marked this conversation as resolved.
const originalImageWidth = props.originalImageWidth;
const rotation = props.rotation;
const translateX = props.translateX;
const translateY = props.translateY;
const scale = props.scale;

// A reanimated memoized style, which updates when the image's size or scale changes.
const imageStyle = useAnimatedStyle(() => {
const height = props.originalImageHeight.value;
const width = props.originalImageWidth.value;
const height = originalImageHeight.value;
const width = originalImageWidth.value;
const aspectRatio = height > width ? height / width : width / height;
const rotate = interpolate(props.rotation.value, [0, 360], [0, 360]);
const rotate = interpolate(rotation.value, [0, 360], [0, 360]);
return {
transform: [{translateX: props.translateX.value}, {translateY: props.translateY.value}, {scale: props.scale.value * aspectRatio}, {rotate: `${rotate}deg`}],
transform: [{translateX: translateX.value}, {translateY: translateY.value}, {scale: scale.value * aspectRatio}, {rotate: `${rotate}deg`}],
};
Comment thread
roryabraham marked this conversation as resolved.
}, [props.originalImageHeight, props.originalImageWidth]);
}, [originalImageHeight, originalImageWidth, rotation, translateX, translateY, scale]);

// We're preventing text selection with ControlSelection.blockElement to prevent safari
// default behaviour of cursor - I-beam cursor on drag. See https://github.com/Expensify/App/issues/13688
Expand Down
3 changes: 2 additions & 1 deletion src/components/AvatarCropModal/Slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ const defaultProps = {

// This component can't be written using class since reanimated API uses hooks.
const Slider = (props) => {
const sliderValue = props.sliderValue;
Comment thread
roryabraham marked this conversation as resolved.
const [tooltipIsVisible, setTooltipIsVisible] = useState(true);

// A reanimated memoized style, which tracks
// a translateX shared value and updates the slider position.
const rSliderStyle = useAnimatedStyle(() => ({
transform: [{translateX: props.sliderValue.value}],
transform: [{translateX: sliderValue.value}],
}));

// We're preventing text selection with ControlSelection.blockElement to prevent safari
Expand Down
Loading