fix: reset iOS scrollView when switching channels (#5447)

* fix: reset iOS scrollView when switching channels

* cancel animation frame after resetting the scrollview

* add useResetNativeScrollView hook
This commit is contained in:
Elias Nahum 2021-06-11 18:22:38 -04:00 committed by GitHub
parent 6335932883
commit b2d233b5ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 17 deletions

View file

@ -51,7 +51,10 @@ export default class PostDraft extends PureComponent {
updateNativeScrollView = (scrollViewNativeID) => {
if (this.keyboardTracker?.current) {
this.keyboardTracker.current.resetScrollView(scrollViewNativeID);
const resetScrollView = requestAnimationFrame(() => {
this.keyboardTracker.current.resetScrollView(scrollViewNativeID);
cancelAnimationFrame(resetScrollView);
});
}
};

View file

@ -6,6 +6,7 @@ import {injectIntl, intlShape} from 'react-intl';
import {DeviceEventEmitter, FlatList, Platform, StyleSheet, ViewToken} from 'react-native';
import {DeepLinkTypes, NavigationTypes} from '@constants';
import {useResetNativeScrollView} from '@hooks';
import {Posts} from '@mm-redux/constants';
import EventEmitter from '@mm-redux/utils/event_emitter';
import {getDateForDateLine, isCombinedUserActivityPost, isDateLine, isStartOfNewMessages} from '@mm-redux/utils/post_list';
@ -228,6 +229,8 @@ const PostList = ({
});
}, []);
useResetNativeScrollView(scrollViewNativeID, postIds);
useEffect(() => {
const scrollToBottom = (screen: string) => {
if (screen === location) {

View file

@ -2,3 +2,6 @@
// See LICENSE.txt for license information.
export {default as useDidUpdate} from './did_update';
export {usePermanentSidebar, useSplitView} from './permanent_sidebar';
export {useResetNativeScrollView} from './reset_native_scrollview';
export {useShowMoreAnimatedStyle} from './show_more';

View file

@ -0,0 +1,24 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {useEffect, useRef} from 'react';
import {UPDATE_NATIVE_SCROLLVIEW} from '@constants/post_draft';
import EventEmitter from '@mm-redux/utils/event_emitter';
export const useResetNativeScrollView = (scrollViewNativeID: string | undefined, postIds: string[]) => {
const prevPostCount = useRef(postIds.length);
useEffect(() => {
if (scrollViewNativeID) {
EventEmitter.emit(UPDATE_NATIVE_SCROLLVIEW, scrollViewNativeID);
}
}, [scrollViewNativeID]);
useEffect(() => {
if (!prevPostCount.current && postIds.length) {
EventEmitter.emit(UPDATE_NATIVE_SCROLLVIEW, scrollViewNativeID);
}
prevPostCount.current = postIds.length;
}, [postIds]);
};

View file

@ -61,10 +61,7 @@ export default class ChannelIOS extends ChannelBase {
renderDraftArea = true;
component = (
<>
<ChannelPostList
updateNativeScrollView={this.updateNativeScrollView}
registerTypingAnimation={this.registerTypingAnimation}
/>
<ChannelPostList registerTypingAnimation={this.registerTypingAnimation}/>
</>
);
}

View file

@ -10,7 +10,7 @@ import {General} from '@mm-redux/constants';
import EventEmitter from '@mm-redux/utils/event_emitter';
import {showModal, showModalOverCurrentContext} from '@actions/navigation';
import {UPDATE_NATIVE_SCROLLVIEW, TYPING_VISIBLE} from '@constants/post_draft';
import {TYPING_VISIBLE} from '@constants/post_draft';
import CompassIcon from '@components/compass_icon';
import PushNotifications from '@init/push_notifications';
import EphemeralStore from '@store/ephemeral_store';
@ -127,7 +127,6 @@ export default class ChannelBase extends PureComponent {
requestAnimationFrame(() => {
this.props.actions.getChannelStats(this.props.currentChannelId);
this.updateNativeScrollView();
});
}
}
@ -297,10 +296,6 @@ export default class ChannelBase extends PureComponent {
});
};
updateNativeScrollView = () => {
EventEmitter.emit(UPDATE_NATIVE_SCROLLVIEW, this.props.currentChannelId);
};
render() {
// Overriden in channel.android.js and channel.ios.js
// but defined here for channel_base.test.js

View file

@ -34,7 +34,6 @@ export default class ChannelPostList extends PureComponent {
postIds: PropTypes.array,
refreshing: PropTypes.bool.isRequired,
theme: PropTypes.object.isRequired,
updateNativeScrollView: PropTypes.func,
registerTypingAnimation: PropTypes.func.isRequired,
};
@ -62,11 +61,6 @@ export default class ChannelPostList extends PureComponent {
if (this.props.channelId !== prevProps.channelId) {
this.isLoadingMoreTop = false;
}
if (!prevProps.postIds?.length && this.props.postIds?.length > 0 && this.props.updateNativeScrollView) {
// This is needed to re-bind the scrollview natively when getting the first posts
this.props.updateNativeScrollView();
}
}
componentWillUnmount() {