From ce1aad22ce4619cc06ee73d391bc1d2db731d0ca Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Thu, 27 Feb 2020 17:06:04 -0300 Subject: [PATCH] MM-21276 & MM-22419 Fix PostList insets and Channel Intro (#3921) * MM-21276 & MM-22419 Fix PostList insets and Channel Intro * Update patches/react-native-keyboard-tracking-view+5.6.1.patch Co-Authored-By: Miguel Alatzar Co-authored-by: Miguel Alatzar --- app/components/channel_intro/channel_intro.js | 2 +- ios/Podfile.lock | 12 +- package-lock.json | 5 +- package.json | 2 +- ...-native-keyboard-tracking-view+5.6.1.patch | 433 ++++++++++++++++++ 5 files changed, 444 insertions(+), 10 deletions(-) create mode 100644 patches/react-native-keyboard-tracking-view+5.6.1.patch diff --git a/app/components/channel_intro/channel_intro.js b/app/components/channel_intro/channel_intro.js index 0e7c1e17a..cce432a04 100644 --- a/app/components/channel_intro/channel_intro.js +++ b/app/components/channel_intro/channel_intro.js @@ -351,7 +351,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { marginBottom: 12, }, container: { - marginTop: 60, + marginTop: 10, marginHorizontal: 12, marginBottom: 12, overflow: 'hidden', diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e64f26a20..37d679b4e 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -23,8 +23,6 @@ PODS: - glog (0.3.5) - jail-monkey (2.3.1): - React - - KeyboardTrackingView (5.5.0): - - React - libwebp (1.1.0): - libwebp/demux (= 1.1.0) - libwebp/mux (= 1.1.0) @@ -268,6 +266,8 @@ PODS: - ReactCommon/jscallinvoker (= 0.61.5) - ReactNativeExceptionHandler (2.10.8): - React + - ReactNativeKeyboardTrackingView (5.6.1): + - React - ReactNativeNavigation (3.2.0): - React - rn-fetch-blob (0.12.0): @@ -319,7 +319,6 @@ DEPENDENCIES: - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - jail-monkey (from `../node_modules/jail-monkey`) - - KeyboardTrackingView (from `../node_modules/react-native-keyboard-tracking-view`) - Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera.podspec`) - Permission-PhotoLibrary (from `../node_modules/react-native-permissions/ios/PhotoLibrary.podspec`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) @@ -358,6 +357,7 @@ DEPENDENCIES: - ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - ReactNativeExceptionHandler (from `../node_modules/react-native-exception-handler`) + - ReactNativeKeyboardTrackingView (from `../node_modules/react-native-keyboard-tracking-view`) - ReactNativeNavigation (from `../node_modules/react-native-navigation`) - rn-fetch-blob (from `../node_modules/rn-fetch-blob`) - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" @@ -401,8 +401,6 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" jail-monkey: :path: "../node_modules/jail-monkey" - KeyboardTrackingView: - :path: "../node_modules/react-native-keyboard-tracking-view" Permission-Camera: :path: "../node_modules/react-native-permissions/ios/Camera.podspec" Permission-PhotoLibrary: @@ -473,6 +471,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon" ReactNativeExceptionHandler: :path: "../node_modules/react-native-exception-handler" + ReactNativeKeyboardTrackingView: + :path: "../node_modules/react-native-keyboard-tracking-view" ReactNativeNavigation: :path: "../node_modules/react-native-navigation" rn-fetch-blob: @@ -511,7 +511,6 @@ SPEC CHECKSUMS: Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 jail-monkey: 8eb1b5d4ab5f2a55937dd123e6450cbbff0c8032 - KeyboardTrackingView: d4d7236123b401ed9b1e02869e7943117740c522 libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3 Permission-Camera: b0fec577b27488314a885f9c74433e02f3585b9b Permission-PhotoLibrary: 51718ddf8c0baf1cebf323c68cedcb2ff0cf304a @@ -548,6 +547,7 @@ SPEC CHECKSUMS: React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd ReactNativeExceptionHandler: 8025d98049c25f186835a3af732dd7c9974d6dce + ReactNativeKeyboardTrackingView: a240a6a0dba852bb107109a7ec7e98b884055977 ReactNativeNavigation: aad255980f20cc5d2001ed37972319f3789fea70 rn-fetch-blob: 17961aec08caae68bb8fc0e5b40f93b3acfa6932 RNCAsyncStorage: 8539fc80a0075fcc9c8e2dff84cd22dc5bf1dacf diff --git a/package-lock.json b/package-lock.json index dccb52cf0..293e70d55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12769,8 +12769,9 @@ } }, "react-native-keyboard-tracking-view": { - "version": "github:mattermost/react-native-keyboard-tracking-view#169676811a32f82cb674a52d7857a14043f7b8f7", - "from": "github:mattermost/react-native-keyboard-tracking-view#169676811a32f82cb674a52d7857a14043f7b8f7" + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/react-native-keyboard-tracking-view/-/react-native-keyboard-tracking-view-5.6.1.tgz", + "integrity": "sha512-uud94SDB2ffGWQHb2ehCIxNi1lmSOQneZ/ro3Zb6Nu6yEh4ljqr1fbRco+pU1RWzaM73uS32A3vPu3NuXjPceA==" }, "react-native-keychain": { "version": "4.0.5", diff --git a/package.json b/package.json index c39d85f9a..e3d607d6e 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "react-native-image-gallery": "github:mattermost/react-native-image-gallery#c1a9f7118e90cc87d47620bc0584c9cac4b0cf38", "react-native-image-picker": "2.0.0", "react-native-keyboard-aware-scroll-view": "0.9.1", - "react-native-keyboard-tracking-view": "github:mattermost/react-native-keyboard-tracking-view#169676811a32f82cb674a52d7857a14043f7b8f7", + "react-native-keyboard-tracking-view": "5.6.1", "react-native-keychain": "4.0.5", "react-native-linear-gradient": "2.5.6", "react-native-local-auth": "github:mattermost/react-native-local-auth#cc9ce2f468fbf7b431dfad3191a31aaa9227a6ab", diff --git a/patches/react-native-keyboard-tracking-view+5.6.1.patch b/patches/react-native-keyboard-tracking-view+5.6.1.patch new file mode 100644 index 000000000..13b08f684 --- /dev/null +++ b/patches/react-native-keyboard-tracking-view+5.6.1.patch @@ -0,0 +1,433 @@ +diff --git a/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.h b/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.h +index 0d9600e..03bd962 100644 +--- a/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.h ++++ b/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.h +@@ -11,4 +11,5 @@ + #import + + @interface KeyboardTrackingViewManager : RCTViewManager ++ + @end +diff --git a/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m b/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m +index 800bd35..c215a8d 100644 +--- a/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m ++++ b/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m +@@ -6,6 +6,8 @@ + // Copyright © 2016 Wix.com All rights reserved. + // + ++#import ++ + #import "KeyboardTrackingViewManager.h" + #import "ObservingInputAccessoryView.h" + #import "UIResponder+FirstResponder.h" +@@ -22,7 +24,7 @@ + NSUInteger const kInputViewKey = 101010; + NSUInteger const kMaxDeferedInitializeAccessoryViews = 15; + NSInteger const kTrackingViewNotFoundErrorCode = 1; +-NSInteger const kBottomViewHeight = 100; ++NSInteger const kBottomViewHeight = 34; + + typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { + KeyboardTrackingScrollBehaviorNone, +@@ -39,6 +41,7 @@ @interface KeyboardTrackingView : UIView + CGFloat _bottomViewHeight; + } + ++@property (nonatomic) NSMutableDictionary* rctScrollViewsArray; + @property (nonatomic, strong) UIScrollView *scrollViewToManage; + @property (nonatomic) BOOL scrollIsInverted; + @property (nonatomic) BOOL revealKeyboardInteractive; +@@ -51,6 +54,13 @@ @interface KeyboardTrackingView : UIView + @property (nonatomic) BOOL addBottomView; + @property (nonatomic) BOOL scrollToFocusedInput; + @property (nonatomic) BOOL allowHitsOutsideBounds; ++@property (nonatomic) BOOL normalList; ++@property (nonatomic) NSString* scrollViewNativeID; ++@property (nonatomic) CGFloat initialOffsetY; ++@property (nonatomic) BOOL initialOffsetIsSet; ++ ++@property (nonatomic, strong) UIView *accessoriesContainer; ++@property (nonatomic) NSString* accessoriesContainerID; + + @end + +@@ -69,12 +79,17 @@ -(instancetype)init + [self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL]; + _inputViewsMap = [NSMapTable weakToWeakObjectsMapTable]; + _deferedInitializeAccessoryViewsCount = 0; ++ _rctScrollViewsArray = [[NSMutableDictionary alloc] init]; + + _observingInputAccessoryView = [ObservingInputAccessoryView new]; + _observingInputAccessoryView.delegate = self; + ++ _initialOffsetY = 0; ++ _initialOffsetIsSet = NO; ++ + _manageScrollView = YES; + _allowHitsOutsideBounds = NO; ++ _requiresSameParentToManageScrollView = YES; + + _bottomViewHeight = kBottomViewHeight; + +@@ -128,12 +143,12 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { + return subview; + } + +--(void)_swizzleWebViewInputAccessory:(UIWebView*)webview ++-(void)_swizzleWebViewInputAccessory:(WKWebView*)webview + { + UIView* subview; + for (UIView* view in webview.scrollView.subviews) + { +- if([[view.class description] hasPrefix:@"UIWeb"]) ++ if([[view.class description] hasPrefix:@"WKWeb"]) + { + subview = view; + } +@@ -166,33 +181,32 @@ -(void)layoutSubviews + - (void)initializeAccessoryViewsAndHandleInsets + { + NSArray* allSubviews = [self getBreadthFirstSubviewsForView:[self getRootView]]; +- NSMutableArray* rctScrollViewsArray = [NSMutableArray array]; + + for (UIView* subview in allSubviews) + { ++ if(subview.nativeID) { ++ NSLog(@"self.accessoriesContainerID %@ %@", self.accessoriesContainerID, subview.nativeID); ++ } ++ ++ if (subview.nativeID && [subview.nativeID isEqualToString:self.accessoriesContainerID]) { ++ NSLog(@"SuperView ID: %@", subview.nativeID); ++ _accessoriesContainer = subview; ++ } ++ + if(_manageScrollView) + { + if(_scrollViewToManage == nil) + { +- if(_requiresSameParentToManageScrollView && [subview isKindOfClass:[RCTScrollView class]] && subview.superview == self.superview) ++ if([subview isKindOfClass:[RCTScrollView class]]) + { +- _scrollViewToManage = ((RCTScrollView*)subview).scrollView; +- } +- else if(!_requiresSameParentToManageScrollView && [subview isKindOfClass:[UIScrollView class]]) +- { +- _scrollViewToManage = (UIScrollView*)subview; +- } ++ RCTScrollView *scrollView = (RCTScrollView*)subview; + +- if(_scrollViewToManage != nil) +- { +- _scrollIsInverted = CGAffineTransformEqualToTransform(_scrollViewToManage.superview.transform, CGAffineTransformMakeScale(1, -1)); ++ if (subview.nativeID && [subview.nativeID isEqualToString:self.scrollViewNativeID]) { ++ [_rctScrollViewsArray setObject:scrollView forKey:subview.nativeID]; ++ _scrollViewToManage = scrollView.scrollView; ++ } + } + } +- +- if([subview isKindOfClass:[RCTScrollView class]]) +- { +- [rctScrollViewsArray addObject:(RCTScrollView*)subview]; +- } + } + + if ([subview isKindOfClass:NSClassFromString(@"RCTTextField")]) +@@ -235,13 +249,13 @@ - (void)initializeAccessoryViewsAndHandleInsets + { + [self setupTextView:(UITextView*)subview]; + } +- else if ([subview isKindOfClass:[UIWebView class]]) ++ else if ([subview isKindOfClass:[WKWebView class]]) + { +- [self _swizzleWebViewInputAccessory:(UIWebView*)subview]; ++ [self _swizzleWebViewInputAccessory:(WKWebView*)subview]; + } + } + +- for (RCTScrollView *scrollView in rctScrollViewsArray) ++ for (RCTScrollView *scrollView in [_rctScrollViewsArray allValues]) + { + if(scrollView.scrollView == _scrollViewToManage) + { +@@ -266,6 +280,21 @@ - (void)initializeAccessoryViewsAndHandleInsets + [self addBottomViewIfNecessary]; + } + ++- (void)resetScrollView:(NSString*) scrollViewNativeID { ++ for (RCTScrollView *scrollView in [_rctScrollViewsArray allValues]) ++ { ++ [scrollView removeScrollListener:self]; ++ } ++ [_rctScrollViewsArray removeAllObjects]; ++ _scrollViewToManage = nil; ++ _scrollViewNativeID = scrollViewNativeID; ++ ++ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ ++ [self deferedInitializeAccessoryViewsAndHandleInsets]; ++ [self scrollToStart]; ++ }); ++} ++ + - (void)setupTextView:(UITextView*)textView + { + if (textView != nil) +@@ -342,7 +371,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N + + - (void)observingInputAccessoryViewKeyboardWillDisappear:(ObservingInputAccessoryView *)observingInputAccessoryView + { +- _bottomViewHeight = kBottomViewHeight; ++ _bottomViewHeight = [self getBottomSafeArea]; + [self updateBottomViewFrame]; + } + +@@ -387,32 +416,43 @@ - (void)_updateScrollViewInsets + { + if(self.scrollViewToManage != nil) + { ++ if (!_initialOffsetIsSet) { ++ self.initialOffsetY = self.scrollViewToManage.contentOffset.y; ++ _initialOffsetIsSet = YES; ++ } ++ ++ if (_observingInputAccessoryView.keyboardState != KeyboardStateWillHide && _observingInputAccessoryView.keyboardState != KeyboardStateHidden) { ++ [self.scrollViewToManage setContentOffset:CGPointMake(self.scrollViewToManage.contentOffset.x, self.initialOffsetY) animated:NO]; ++ } ++ + UIEdgeInsets insets = self.scrollViewToManage.contentInset; + CGFloat bottomSafeArea = [self getBottomSafeArea]; + CGFloat bottomInset = MAX(self.bounds.size.height, _observingInputAccessoryView.keyboardHeight + _observingInputAccessoryView.height); + + CGFloat originalBottomInset = self.scrollIsInverted ? insets.top : insets.bottom; + CGPoint originalOffset = self.scrollViewToManage.contentOffset; ++ CGFloat keyboardHeight = _observingInputAccessoryView.keyboardHeight; + +- bottomInset += (_observingInputAccessoryView.keyboardHeight == 0 ? bottomSafeArea : 0); ++ bottomInset += (keyboardHeight == 0 ? bottomSafeArea : 0); + if(self.scrollIsInverted) + { + insets.top = bottomInset; + } + else + { +- insets.bottom = bottomInset; ++ insets.bottom = keyboardHeight; + } ++ + self.scrollViewToManage.contentInset = insets; + + if(self.scrollBehavior == KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly && _scrollIsInverted) + { +- BOOL fisrtTime = _observingInputAccessoryView.keyboardHeight == 0 && _observingInputAccessoryView.keyboardState == KeyboardStateHidden; ++ BOOL firstTime = _observingInputAccessoryView.keyboardHeight == 0 && _observingInputAccessoryView.keyboardState == KeyboardStateHidden; + BOOL willOpen = _observingInputAccessoryView.keyboardHeight != 0 && _observingInputAccessoryView.keyboardState == KeyboardStateHidden; + BOOL isOpen = _observingInputAccessoryView.keyboardHeight != 0 && _observingInputAccessoryView.keyboardState == KeyboardStateShown; +- if(fisrtTime || willOpen || (isOpen && !self.isDraggingScrollView)) ++ if(firstTime || willOpen || (isOpen && !self.isDraggingScrollView)) + { +- [self.scrollViewToManage setContentOffset:CGPointMake(self.scrollViewToManage.contentOffset.x, -self.scrollViewToManage.contentInset.top) animated:!fisrtTime]; ++ [self.scrollViewToManage setContentOffset:CGPointMake(self.scrollViewToManage.contentOffset.x, self.scrollViewToManage.contentOffset.y) animated:!firstTime]; + } + } + else if(self.scrollBehavior == KeyboardTrackingScrollBehaviorFixedOffset && !self.isDraggingScrollView) +@@ -421,16 +461,16 @@ - (void)_updateScrollViewInsets + self.scrollViewToManage.contentOffset = CGPointMake(originalOffset.x, originalOffset.y + insetsDiff); + } + +- insets = self.scrollViewToManage.contentInset; +- if(self.scrollIsInverted) +- { +- insets.top = bottomInset; +- } +- else +- { +- insets.bottom = bottomInset; ++ CGFloat positionY = self.normalList ? 0 : _observingInputAccessoryView.keyboardHeight; ++ CGRect frame = CGRectMake(self.scrollViewToManage.frame.origin.x, positionY, ++ self.scrollViewToManage.frame.size.width, self.scrollViewToManage.frame.size.height); ++ self.scrollViewToManage.frame = frame; ++ ++ if (self.accessoriesContainer) { ++ self.accessoriesContainer.bounds = CGRectMake(self.accessoriesContainer.bounds.origin.x, positionY, ++ self.accessoriesContainer.bounds.size.width, self.accessoriesContainer.bounds.size.height); + } +- self.scrollViewToManage.scrollIndicatorInsets = insets; ++ + } + } + +@@ -447,11 +487,9 @@ -(void)addBottomViewIfNecessary + if (self.addBottomView && _bottomView == nil) + { + _bottomView = [UIView new]; +- _bottomView.backgroundColor = [UIColor whiteColor]; + [self addSubview:_bottomView]; + [self updateBottomViewFrame]; +- } +- else if (!self.addBottomView && _bottomView != nil) ++ } else if (!self.addBottomView && _bottomView != nil) + { + [_bottomView removeFromSuperview]; + _bottomView = nil; +@@ -466,6 +504,12 @@ -(void)updateBottomViewFrame + } + } + ++-(void)setBottomViewBackgroundColor:(UIColor*) color { ++ if (_bottomView != nil) { ++ _bottomView.backgroundColor = color; ++ } ++} ++ + #pragma mark - safe area + + -(void)safeAreaInsetsDidChange +@@ -483,7 +527,7 @@ -(CGFloat)getBottomSafeArea + CGFloat bottomSafeArea = 0; + #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_10_3 + if (@available(iOS 11.0, *)) { +- bottomSafeArea = self.superview ? self.superview.safeAreaInsets.bottom : self.safeAreaInsets.bottom; ++ bottomSafeArea = self.superview ? self.superview.safeAreaInsets.bottom : self.safeAreaInsets.bottom; + } + #endif + return bottomSafeArea; +@@ -509,7 +553,7 @@ -(void)updateTransformAndInsets + CGFloat accessoryTranslation = MIN(-bottomSafeArea, -_observingInputAccessoryView.keyboardHeight); + + if (_observingInputAccessoryView.keyboardHeight <= bottomSafeArea) { +- _bottomViewHeight = kBottomViewHeight; ++ _bottomViewHeight = [self getBottomSafeArea]; + } else if (_observingInputAccessoryView.keyboardState != KeyboardStateWillHide) { + _bottomViewHeight = 0; + } +@@ -553,6 +597,14 @@ - (void) observingInputAccessoryViewKeyboardWillAppear:(ObservingInputAccessoryV + [self performScrollToFocusedInput]; + } + ++- (void)observingInputAccessoryViewKeyboardDidAppear:(ObservingInputAccessoryView *)observingInputAccessoryView { ++ if (observingInputAccessoryView.keyboardHeight == 0 && self.scrollViewToManage) { ++ CGRect frame = CGRectMake(self.scrollViewToManage.frame.origin.x, _observingInputAccessoryView.height, ++ self.scrollViewToManage.frame.size.width, self.scrollViewToManage.frame.size.height); ++ self.scrollViewToManage.frame = frame; ++ } ++} ++ + #pragma mark - UIScrollViewDelegate methods + + - (void)scrollViewDidScroll:(UIScrollView *)scrollView +@@ -581,6 +633,8 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView + - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView + { + self.isDraggingScrollView = YES; ++ _initialOffsetIsSet = NO; ++ self.initialOffsetY = scrollView.contentOffset.y; + } + + - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset +@@ -591,6 +645,15 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoi + - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate + { + self.isDraggingScrollView = NO; ++ self.initialOffsetY = scrollView.contentOffset.y; ++} ++ ++- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { ++ self.initialOffsetY = scrollView.contentOffset.y; ++} ++ ++- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { ++ self.initialOffsetY = scrollView.contentOffset.y; + } + + - (CGFloat)getKeyboardHeight +@@ -633,6 +696,12 @@ @implementation KeyboardTrackingViewManager + RCT_REMAP_VIEW_PROPERTY(addBottomView, addBottomView, BOOL) + RCT_REMAP_VIEW_PROPERTY(scrollToFocusedInput, scrollToFocusedInput, BOOL) + RCT_REMAP_VIEW_PROPERTY(allowHitsOutsideBounds, allowHitsOutsideBounds, BOOL) ++RCT_REMAP_VIEW_PROPERTY(normalList, normalList, BOOL) ++RCT_EXPORT_VIEW_PROPERTY(scrollViewNativeID, NSString) ++RCT_EXPORT_VIEW_PROPERTY(accessoriesContainerID, NSString) ++RCT_CUSTOM_VIEW_PROPERTY(backgroundColor, UIColor, KeyboardTrackingView) { ++ [view setBottomViewBackgroundColor:[RCTConvert UIColor:json]]; ++} + + + (BOOL)requiresMainQueueSetup + { +@@ -687,6 +756,20 @@ - (UIView *)view + }]; + } + ++RCT_EXPORT_METHOD(resetScrollView:(nonnull NSNumber *)reactTag scrollViewNativeID:(NSString*)scrollViewNativeID) { ++ [self.bridge.uiManager addUIBlock: ++ ^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { ++ ++ KeyboardTrackingView *view = viewRegistry[reactTag]; ++ if (!view || ![view isKindOfClass:[KeyboardTrackingView class]]) { ++ RCTLogError(@"Error: cannot find KeyboardTrackingView with tag #%@", reactTag); ++ return; ++ } ++ ++ [view resetScrollView:scrollViewNativeID]; ++ }]; ++} ++ + #pragma mark - helper methods + + -(void)rejectPromise:(RCTPromiseRejectBlock)reject withErrorMessage:(NSString*)errorMessage errorCode:(NSInteger)errorCode +diff --git a/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.h b/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.h +index 9b242e8..b500db1 100644 +--- a/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.h ++++ b/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.h +@@ -30,6 +30,7 @@ typedef NS_ENUM(NSUInteger, KeyboardState) { + + - (void)observingInputAccessoryViewKeyboardWillAppear:(ObservingInputAccessoryView*)observingInputAccessoryView keyboardDelta:(CGFloat)delta; + - (void)observingInputAccessoryViewKeyboardWillDisappear:(ObservingInputAccessoryView*)observingInputAccessoryView; ++- (void)observingInputAccessoryViewKeyboardDidAppear:(ObservingInputAccessoryView*)observingInputAccessoryView; + + @end + +diff --git a/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.m b/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.m +index e472679..1e62c61 100644 +--- a/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.m ++++ b/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.m +@@ -130,6 +130,11 @@ - (void)_keyboardDidShowNotification:(NSNotification*)notification + _keyboardState = KeyboardStateShown; + + [self invalidateIntrinsicContentSize]; ++ ++ if([_delegate respondsToSelector:@selector(observingInputAccessoryViewKeyboardDidAppear:)]) ++ { ++ [_delegate observingInputAccessoryViewKeyboardDidAppear:self]; ++ } + } + + - (void)_keyboardWillHideNotification:(NSNotification*)notification +diff --git a/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.android.js b/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.android.js +index af15edf..3ba0a3a 100644 +--- a/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.android.js ++++ b/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.android.js +@@ -13,5 +13,6 @@ export default class KeyboardTrackingView extends PureComponent { + async getNativeProps() { + return {trackingViewHeight: 0, keyboardHeight: 0, contentTopInset: 0}; + } ++ resetScrollView() {} + scrollToStart() {} + } +diff --git a/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.ios.js b/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.ios.js +index 5e2c207..e6099f3 100644 +--- a/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.ios.js ++++ b/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.ios.js +@@ -25,6 +25,12 @@ export default class KeyboardTrackingView extends PureComponent { + return {}; + } + ++ resetScrollView(scrollViewNativeID) { ++ if (this.ref && KeyboardTrackingViewManager && KeyboardTrackingViewManager.resetScrollView) { ++ KeyboardTrackingViewManager.resetScrollView(ReactNative.findNodeHandle(this.ref), scrollViewNativeID); ++ } ++ } ++ + scrollToStart() { + if (this.ref && KeyboardTrackingViewManager && KeyboardTrackingViewManager.scrollToStart) { + KeyboardTrackingViewManager.scrollToStart(ReactNative.findNodeHandle(this.ref));