From acf4cbde8d16bbed4291015fa100cf4db6fb30db Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Mon, 14 Mar 2022 16:21:45 -0300 Subject: [PATCH] [Keyboard] Keyboard tracking (#6050) * Pause/Resume tracking keyboard * fix keyboard tracking view on tablets * add EDIT_POST screen to pause keyboard tracking --- app/components/post_draft/post_draft.tsx | 51 +++++----- app/constants/events.ts | 2 + app/constants/post_draft.ts | 2 - app/constants/view.ts | 6 ++ app/screens/channel/channel.tsx | 20 +++- app/screens/home/tab_bar/index.tsx | 4 +- app/screens/navigation.ts | 2 +- app/screens/thread/thread.tsx | 5 +- index.ts | 12 ++- ...-native-keyboard-tracking-view+5.7.0.patch | 98 ++++++++++++++++--- .../react-native-keyboard-tracking-view.d.ts | 2 + 11 files changed, 148 insertions(+), 56 deletions(-) diff --git a/app/components/post_draft/post_draft.tsx b/app/components/post_draft/post_draft.tsx index 288ebd9ee3..6576e567ba 100644 --- a/app/components/post_draft/post_draft.tsx +++ b/app/components/post_draft/post_draft.tsx @@ -1,12 +1,12 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useCallback, useEffect, useRef, useState} from 'react'; -import {DeviceEventEmitter, Platform, View} from 'react-native'; +import React, {RefObject, useState} from 'react'; +import {Platform, useWindowDimensions, View} from 'react-native'; import {KeyboardTrackingView, KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view'; import Autocomplete from '@components/autocomplete'; -import {PostDraft as PostDraftConstants, View as ViewConstants} from '@constants'; +import {View as ViewConstants} from '@constants'; import {useIsTablet} from '@hooks/device'; import Archived from './archived'; @@ -26,9 +26,16 @@ type Props = { message?: string; rootId?: string; scrollViewNativeID?: string; + keyboardTracker: RefObject; } -export default function PostDraft({ +const { + KEYBOARD_TRACKING_OFFSET, + KEYBOARD_TRACKING_OFFSET_MODAL_LANDSCAPE, + KEYBOARD_TRACKING_OFFSET_MODAL_PORTRAIT, +} = ViewConstants; + +function PostDraft({ testID, accessoriesContainerID, canPost, @@ -41,35 +48,14 @@ export default function PostDraft({ message = '', rootId = '', scrollViewNativeID, + keyboardTracker, }: Props) { - const keyboardTracker = useRef(null); - const resetScrollViewAnimationFrame = useRef(); const [value, setValue] = useState(message); const [cursorPosition, setCursorPosition] = useState(message.length); const [postInputTop, setPostInputTop] = useState(0); const isTablet = useIsTablet(); - - const updateNativeScrollView = useCallback((scrollViewNativeIDToUpdate: string) => { - if (keyboardTracker?.current && scrollViewNativeID === scrollViewNativeIDToUpdate) { - resetScrollViewAnimationFrame.current = requestAnimationFrame(() => { - keyboardTracker.current?.resetScrollView(scrollViewNativeIDToUpdate); - if (resetScrollViewAnimationFrame.current != null) { - cancelAnimationFrame(resetScrollViewAnimationFrame.current); - } - resetScrollViewAnimationFrame.current = undefined; - }); - } - }, [scrollViewNativeID]); - - useEffect(() => { - const listener = DeviceEventEmitter.addListener(PostDraftConstants.UPDATE_NATIVE_SCROLLVIEW, updateNativeScrollView); - return () => { - listener.remove(); - if (resetScrollViewAnimationFrame.current) { - cancelAnimationFrame(resetScrollViewAnimationFrame.current); - } - }; - }, [updateNativeScrollView]); + const dimensions = useWindowDimensions(); + const isLandscape = dimensions.width > dimensions.height; if (channelIsArchived || deactivatedChannel) { const archivedTestID = `${testID}.archived`; @@ -128,13 +114,18 @@ export default function PostDraft({ ); } + let viewInitialOffsetY = isTablet ? KEYBOARD_TRACKING_OFFSET : 0; + if (isTablet && rootId) { + viewInitialOffsetY = isLandscape ? KEYBOARD_TRACKING_OFFSET_MODAL_LANDSCAPE : KEYBOARD_TRACKING_OFFSET_MODAL_PORTRAIT; + } + return ( <> {draftHandler} @@ -144,3 +135,5 @@ export default function PostDraft({ ); } + +export default PostDraft; diff --git a/app/constants/events.ts b/app/constants/events.ts index 8adca1fe87..cb6f5a64cf 100644 --- a/app/constants/events.ts +++ b/app/constants/events.ts @@ -14,8 +14,10 @@ export default keyMirror({ LEAVE_TEAM: null, LOADING_CHANNEL_POSTS: null, NOTIFICATION_ERROR: null, + PAUSE_KEYBOARD_TRACKING_VIEW: null, SERVER_LOGOUT: null, SERVER_VERSION_CHANGED: null, + TAB_BAR_VISIBLE: null, TEAM_LOAD_ERROR: null, USER_TYPING: null, USER_STOP_TYPING: null, diff --git a/app/constants/post_draft.ts b/app/constants/post_draft.ts index 1f4d0907b9..4c5f6e279b 100644 --- a/app/constants/post_draft.ts +++ b/app/constants/post_draft.ts @@ -4,7 +4,6 @@ export const MAX_MESSAGE_LENGTH_FALLBACK = 4000; export const DEFAULT_SERVER_MAX_FILE_SIZE = 50 * 1024 * 1024;// 50 Mb export const ICON_SIZE = 24; -export const UPDATE_NATIVE_SCROLLVIEW = 'onUpdateNativeScrollView'; export const TYPING_HEIGHT = 26; export const ACCESSORIES_CONTAINER_NATIVE_ID = 'channelAccessoriesContainer'; export const THREAD_ACCESSORIES_CONTAINER_NATIVE_ID = 'threadAccessoriesContainer'; @@ -18,5 +17,4 @@ export default { MAX_MESSAGE_LENGTH_FALLBACK, NOTIFY_ALL_MEMBERS, TYPING_HEIGHT, - UPDATE_NATIVE_SCROLLVIEW, }; diff --git a/app/constants/view.ts b/app/constants/view.ts index 47cc07217f..af96cef844 100644 --- a/app/constants/view.ts +++ b/app/constants/view.ts @@ -21,6 +21,9 @@ export const HEADER_WITH_SUBTITLE = 24; export const IOS_HEADER_SEARCH_INSET = 20; export const TABLET_HEADER_SEARCH_INSET = 28; export const ANDROID_HEADER_SEARCH_INSET = 11; +export const KEYBOARD_TRACKING_OFFSET = 72; +export const KEYBOARD_TRACKING_OFFSET_MODAL_LANDSCAPE = 44; +export const KEYBOARD_TRACKING_OFFSET_MODAL_PORTRAIT = 154; export const INDICATOR_BAR_HEIGHT = 38; @@ -44,5 +47,8 @@ export default { TABLET_HEADER_SEARCH_INSET, ANDROID_HEADER_SEARCH_INSET, INDICATOR_BAR_HEIGHT, + KEYBOARD_TRACKING_OFFSET, + KEYBOARD_TRACKING_OFFSET_MODAL_LANDSCAPE, + KEYBOARD_TRACKING_OFFSET_MODAL_PORTRAIT, }; diff --git a/app/screens/channel/channel.tsx b/app/screens/channel/channel.tsx index b5cec3114e..0f7dece442 100644 --- a/app/screens/channel/channel.tsx +++ b/app/screens/channel/channel.tsx @@ -1,16 +1,17 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useCallback, useMemo} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef} from 'react'; import {useIntl} from 'react-intl'; import {DeviceEventEmitter, Keyboard, Platform, StyleSheet, View} from 'react-native'; +import {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view'; import {Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'; import CompassIcon from '@components/compass_icon'; import FreezeScreen from '@components/freeze_screen'; import NavigationHeader from '@components/navigation_header'; import PostDraft from '@components/post_draft'; -import {Navigation} from '@constants'; +import {Events, Navigation} from '@constants'; import {ACCESSORIES_CONTAINER_NATIVE_ID} from '@constants/post_draft'; import {useTheme} from '@context/theme'; import {useAppState, useIsTablet} from '@hooks/device'; @@ -48,6 +49,7 @@ const Channel = ({channelId, componentId, displayName, isOwnDirectMessage, membe const insets = useSafeAreaInsets(); const theme = useTheme(); const defaultHeight = useDefaultHeaderHeight(); + const postDraftRef = useRef(null); const rightButtons: HeaderRightButton[] = useMemo(() => ([{ iconName: 'magnify', onPress: () => { @@ -88,6 +90,19 @@ const Channel = ({channelId, componentId, displayName, isOwnDirectMessage, membe console.log('Title Press go to Channel Info', displayName); }, [channelId]); + useEffect(() => { + const listener = DeviceEventEmitter.addListener(Events.PAUSE_KEYBOARD_TRACKING_VIEW, (pause: boolean) => { + if (pause) { + postDraftRef.current?.pauseTracking(channelId); + return; + } + + postDraftRef.current?.resumeTracking(channelId); + }); + + return () => listener.remove(); + }, []); + let title = displayName; if (isOwnDirectMessage) { title = formatMessage({id: 'channel_header.directchannel.you', defaultMessage: '{displayName} (you)'}, {displayName}); @@ -125,6 +140,7 @@ const Channel = ({channelId, componentId, displayName, isOwnDirectMessage, membe diff --git a/app/screens/home/tab_bar/index.tsx b/app/screens/home/tab_bar/index.tsx index b80389e01d..27fb01a15d 100644 --- a/app/screens/home/tab_bar/index.tsx +++ b/app/screens/home/tab_bar/index.tsx @@ -7,7 +7,7 @@ import {Shadow} from 'react-native-neomorph-shadows'; import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; -import {Navigation as NavigationConstants, Screens, View as ViewConstants} from '@constants'; +import {Events, Navigation as NavigationConstants, Screens, View as ViewConstants} from '@constants'; import EphemeralStore from '@store/ephemeral_store'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; @@ -66,7 +66,7 @@ function TabBar({state, descriptors, navigation, theme}: BottomTabBarProps & {th const safeareaInsets = useSafeAreaInsets(); useEffect(() => { - const event = DeviceEventEmitter.addListener('tabBarVisible', (show) => { + const event = DeviceEventEmitter.addListener(Events.TAB_BAR_VISIBLE, (show) => { setVisible(show); }); diff --git a/app/screens/navigation.ts b/app/screens/navigation.ts index df5c965ea1..47aa895782 100644 --- a/app/screens/navigation.ts +++ b/app/screens/navigation.ts @@ -307,7 +307,7 @@ export function goToScreen(name: string, title: string, passProps = {}, options const theme = getThemeFromState(); const isDark = tinyColor(theme.sidebarBg).isDark(); const componentId = EphemeralStore.getNavigationTopComponentId(); - DeviceEventEmitter.emit('tabBarVisible', false); + DeviceEventEmitter.emit(Events.TAB_BAR_VISIBLE, false); const defaultOptions: Options = { layout: { componentBackgroundColor: theme.centerChannelBg, diff --git a/app/screens/thread/thread.tsx b/app/screens/thread/thread.tsx index 6f8d31f37c..21b4aba79f 100644 --- a/app/screens/thread/thread.tsx +++ b/app/screens/thread/thread.tsx @@ -1,8 +1,9 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useCallback, useEffect} from 'react'; +import React, {useCallback, useEffect, useRef} from 'react'; import {BackHandler, StyleSheet, View} from 'react-native'; +import {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view'; import {Navigation} from 'react-native-navigation'; import {Edge, SafeAreaView} from 'react-native-safe-area-context'; @@ -32,6 +33,7 @@ const getStyleSheet = StyleSheet.create(() => ({ const Thread = ({closeButtonId, componentId, rootPost}: ThreadProps) => { const appState = useAppState(); const styles = getStyleSheet(); + const postDraftRef = useRef(null); const close = useCallback(() => { dismissModal({componentId}); @@ -83,6 +85,7 @@ const Thread = ({closeButtonId, componentId, rootPost}: ThreadProps) => { scrollViewNativeID={rootPost!.id} accessoriesContainerID={THREAD_ACCESSORIES_CONTAINER_NATIVE_ID} rootId={rootPost!.id} + keyboardTracker={postDraftRef} /> } diff --git a/index.ts b/index.ts index 737fb65a97..38b2668866 100644 --- a/index.ts +++ b/index.ts @@ -5,7 +5,7 @@ import {DeviceEventEmitter, Platform} from 'react-native'; import 'react-native-gesture-handler'; import {ComponentDidAppearEvent, ComponentDidDisappearEvent, Navigation} from 'react-native-navigation'; -import {Screens} from './app/constants'; +import {Events, Screens} from './app/constants'; import DatabaseManager from './app/database/manager'; import {getAllServerCredentials} from './app/init/credentials'; import GlobalEventHandler from './app/init/global_event_handler'; @@ -79,7 +79,9 @@ const registerNavigationListeners = () => { function componentWillAppear({componentId}: ComponentDidAppearEvent) { if (componentId === Screens.HOME) { - DeviceEventEmitter.emit('tabBarVisible', true); + DeviceEventEmitter.emit(Events.TAB_BAR_VISIBLE, true); + } else if ([Screens.EDIT_POST, Screens.THREAD].includes(componentId)) { + DeviceEventEmitter.emit(Events.PAUSE_KEYBOARD_TRACKING_VIEW, true); } } @@ -93,8 +95,12 @@ function componentDidDisappearListener({componentId}: ComponentDidDisappearEvent if (componentId !== Screens.HOME) { EphemeralStore.removeNavigationComponentId(componentId); + if ([Screens.EDIT_POST, Screens.THREAD].includes(componentId)) { + DeviceEventEmitter.emit(Events.PAUSE_KEYBOARD_TRACKING_VIEW, false); + } + if (EphemeralStore.getNavigationTopComponentId() === Screens.HOME) { - DeviceEventEmitter.emit('tabBarVisible', true); + DeviceEventEmitter.emit(Events.TAB_BAR_VISIBLE, true); } } } diff --git a/patches/react-native-keyboard-tracking-view+5.7.0.patch b/patches/react-native-keyboard-tracking-view+5.7.0.patch index ada195c1b9..ce761dbb1c 100644 --- a/patches/react-native-keyboard-tracking-view+5.7.0.patch +++ b/patches/react-native-keyboard-tracking-view+5.7.0.patch @@ -1,5 +1,5 @@ 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 1333a10..f0515fd 100644 +index 1333a10..9922be7 100644 --- a/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m +++ b/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m @@ -23,7 +23,7 @@ @@ -62,6 +62,15 @@ index 1333a10..f0515fd 100644 { subview = view; } +@@ -149,7 +164,7 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { + if(!_newClass) return; + + Method method = class_getInstanceMethod([UIResponder class], @selector(inputAccessoryView)); +- class_addMethod(_newClass, @selector(inputAccessoryView), imp_implementationWithBlock(^(id _self){return _observingInputAccessoryView;}), method_getTypeEncoding(method)); ++ class_addMethod(_newClass, @selector(inputAccessoryView), imp_implementationWithBlock(^(id _self){return self->_observingInputAccessoryView;}), method_getTypeEncoding(method)); + + objc_registerClassPair(_newClass); + } @@ -167,33 +182,32 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { - (void)initializeAccessoryViewsAndHandleInsets { @@ -120,7 +129,7 @@ index 1333a10..f0515fd 100644 { if(scrollView.scrollView == _scrollViewToManage) { -@@ -267,6 +281,21 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { +@@ -267,6 +281,36 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { [self addBottomViewIfNecessary]; } @@ -138,11 +147,26 @@ index 1333a10..f0515fd 100644 + [self scrollToStart]; + }); +} ++ ++-(void)pauseTracking:(NSString*) scrollViewNativeID { ++ if ([self.scrollViewNativeID isEqualToString:scrollViewNativeID]) { ++ _observingInputAccessoryView.delegate = nil; ++ self.scrollViewToManage = nil; ++ self.accessoriesContainer = nil; ++ } ++} ++ ++-(void)resumeTracking:(NSString*) scrollViewNativeID { ++ if ([self.scrollViewNativeID isEqualToString:scrollViewNativeID]) { ++ _observingInputAccessoryView.delegate = self; ++ [self deferedInitializeAccessoryViewsAndHandleInsets]; ++ } ++} + - (void)setupTextView:(UITextView*)textView { if (textView != nil) -@@ -343,7 +372,7 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { +@@ -343,7 +387,7 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { - (void)observingInputAccessoryViewKeyboardWillDisappear:(ObservingInputAccessoryView *)observingInputAccessoryView { @@ -151,7 +175,7 @@ index 1333a10..f0515fd 100644 [self updateBottomViewFrame]; } -@@ -388,32 +417,42 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { +@@ -388,32 +432,42 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { { if(self.scrollViewToManage != nil) { @@ -199,7 +223,7 @@ index 1333a10..f0515fd 100644 } } else if(self.scrollBehavior == KeyboardTrackingScrollBehaviorFixedOffset && !self.isDraggingScrollView) -@@ -422,16 +461,21 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { +@@ -422,16 +476,21 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { self.scrollViewToManage.contentOffset = CGPointMake(originalOffset.x, originalOffset.y + insetsDiff); } @@ -229,7 +253,7 @@ index 1333a10..f0515fd 100644 } } -@@ -448,7 +492,6 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { +@@ -448,7 +507,6 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { if (self.addBottomView && _bottomView == nil) { _bottomView = [UIView new]; @@ -237,7 +261,7 @@ index 1333a10..f0515fd 100644 [self addSubview:_bottomView]; [self updateBottomViewFrame]; } -@@ -467,6 +510,12 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { +@@ -467,6 +525,12 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { } } @@ -250,7 +274,7 @@ index 1333a10..f0515fd 100644 #pragma mark - safe area -(void)safeAreaInsetsDidChange -@@ -507,10 +556,10 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { +@@ -507,10 +571,10 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { -(void)updateTransformAndInsets { CGFloat bottomSafeArea = [self getBottomSafeArea]; @@ -263,7 +287,7 @@ index 1333a10..f0515fd 100644 } else if (_observingInputAccessoryView.keyboardState != KeyboardStateWillHide) { _bottomViewHeight = 0; } -@@ -582,6 +631,8 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { +@@ -582,6 +646,8 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { self.isDraggingScrollView = YES; @@ -272,7 +296,7 @@ index 1333a10..f0515fd 100644 } - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset -@@ -592,6 +643,15 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { +@@ -592,6 +658,15 @@ typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { self.isDraggingScrollView = NO; @@ -288,7 +312,7 @@ index 1333a10..f0515fd 100644 } - (CGFloat)getKeyboardHeight -@@ -634,6 +694,13 @@ RCT_REMAP_VIEW_PROPERTY(requiresSameParentToManageScrollView, requiresSameParent +@@ -634,6 +709,13 @@ RCT_REMAP_VIEW_PROPERTY(requiresSameParentToManageScrollView, requiresSameParent RCT_REMAP_VIEW_PROPERTY(addBottomView, addBottomView, BOOL) RCT_REMAP_VIEW_PROPERTY(scrollToFocusedInput, scrollToFocusedInput, BOOL) RCT_REMAP_VIEW_PROPERTY(allowHitsOutsideBounds, allowHitsOutsideBounds, BOOL) @@ -302,7 +326,7 @@ index 1333a10..f0515fd 100644 + (BOOL)requiresMainQueueSetup { -@@ -654,6 +721,20 @@ RCT_REMAP_VIEW_PROPERTY(allowHitsOutsideBounds, allowHitsOutsideBounds, BOOL) +@@ -654,6 +736,48 @@ RCT_REMAP_VIEW_PROPERTY(allowHitsOutsideBounds, allowHitsOutsideBounds, BOOL) return [[KeyboardTrackingView alloc] init]; } @@ -319,26 +343,56 @@ index 1333a10..f0515fd 100644 + [view resetScrollView:scrollViewNativeID]; + }]; +} ++ ++RCT_EXPORT_METHOD(pauseTracking:(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 pauseTracking:scrollViewNativeID]; ++ }]; ++} ++ ++RCT_EXPORT_METHOD(resumeTracking:(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 resumeTracking:scrollViewNativeID]; ++ }]; ++} + RCT_EXPORT_METHOD(getNativeProps:(nonnull NSNumber *)reactTag resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { [self.bridge.uiManager addUIBlock: 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 +index af15edf..20b6ab6 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 { +@@ -13,5 +13,8 @@ export default class KeyboardTrackingView extends PureComponent { async getNativeProps() { return {trackingViewHeight: 0, keyboardHeight: 0, contentTopInset: 0}; } + resetScrollView() {} ++ pauseTracking() {} ++ resumeTracking() {} 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..727017c 100644 +index 5e2c207..07c8257 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 { +@@ -25,6 +25,24 @@ export default class KeyboardTrackingView extends PureComponent { return {}; } @@ -347,6 +401,18 @@ index 5e2c207..727017c 100644 + KeyboardTrackingViewManager.resetScrollView(ReactNative.findNodeHandle(this.ref), scrollViewNativeID); + } + } ++ ++ pauseTracking(scrollViewNativeID) { ++ if (this.ref && KeyboardTrackingViewManager && KeyboardTrackingViewManager.pauseTracking) { ++ KeyboardTrackingViewManager.pauseTracking(ReactNative.findNodeHandle(this.ref), scrollViewNativeID); ++ } ++ } ++ ++ resumeTracking(scrollViewNativeID) { ++ if (this.ref && KeyboardTrackingViewManager && KeyboardTrackingViewManager.resumeTracking) { ++ KeyboardTrackingViewManager.resumeTracking(ReactNative.findNodeHandle(this.ref), scrollViewNativeID); ++ } ++ } + scrollToStart() { if (this.ref && KeyboardTrackingViewManager && KeyboardTrackingViewManager.scrollToStart) { diff --git a/types/modules/react-native-keyboard-tracking-view.d.ts b/types/modules/react-native-keyboard-tracking-view.d.ts index 316d164f70..a768a122aa 100644 --- a/types/modules/react-native-keyboard-tracking-view.d.ts +++ b/types/modules/react-native-keyboard-tracking-view.d.ts @@ -4,6 +4,8 @@ declare module 'react-native-keyboard-tracking-view' { import {ViewProps} from 'react-native'; export interface KeyboardTrackingViewRef { + pauseTracking: (id: string) => void; + resumeTracking: (id: string) => void; resetScrollView: (id: string) => void; setNativeProps(nativeProps: object): void; }