forked from Ivasoft/mattermost-mobile
[Keyboard] Keyboard tracking (#6050)
* Pause/Resume tracking keyboard * fix keyboard tracking view on tablets * add EDIT_POST screen to pause keyboard tracking
This commit is contained in:
@@ -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<KeyboardTrackingViewRef>;
|
||||
}
|
||||
|
||||
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<KeyboardTrackingViewRef>(null);
|
||||
const resetScrollViewAnimationFrame = useRef<number>();
|
||||
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 (
|
||||
<>
|
||||
<KeyboardTrackingView
|
||||
accessoriesContainerID={accessoriesContainerID}
|
||||
ref={keyboardTracker}
|
||||
scrollViewNativeID={scrollViewNativeID}
|
||||
viewInitialOffsetY={isTablet ? ViewConstants.BOTTOM_TAB_HEIGHT : 0}
|
||||
viewInitialOffsetY={viewInitialOffsetY}
|
||||
>
|
||||
{draftHandler}
|
||||
</KeyboardTrackingView>
|
||||
@@ -144,3 +135,5 @@ export default function PostDraft({
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default PostDraft;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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<KeyboardTrackingViewRef>(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
|
||||
</View>
|
||||
<PostDraft
|
||||
channelId={channelId}
|
||||
keyboardTracker={postDraftRef}
|
||||
scrollViewNativeID={channelId}
|
||||
accessoriesContainerID={ACCESSORIES_CONTAINER_NATIVE_ID}
|
||||
/>
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<KeyboardTrackingViewRef>(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}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
12
index.ts
12
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<NSNumber *, KeyboardTrackingView *> *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<NSNumber *, KeyboardTrackingView *> *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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user