Migrate NavBottomFAB to reanimated 3
This commit is contained in:
parent
1d99145d93
commit
28d55a581e
|
@ -1,13 +1,12 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { FlatListProps, StyleSheet } from 'react-native';
|
import { FlatListProps, StyleSheet } from 'react-native';
|
||||||
import { FlatList } from 'react-native-gesture-handler';
|
import { FlatList } from 'react-native-gesture-handler';
|
||||||
import Animated from 'react-native-reanimated';
|
import Animated, { runOnJS, useAnimatedScrollHandler } from 'react-native-reanimated';
|
||||||
|
|
||||||
import { isIOS } from '../../../lib/methods/helpers';
|
import { isIOS } from '../../../lib/methods/helpers';
|
||||||
import scrollPersistTaps from '../../../lib/methods/helpers/scrollPersistTaps';
|
import scrollPersistTaps from '../../../lib/methods/helpers/scrollPersistTaps';
|
||||||
|
import NavBottomFAB, { SCROLL_LIMIT } from './NavBottomFAB';
|
||||||
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
list: {
|
list: {
|
||||||
|
@ -22,10 +21,26 @@ export type TListRef = React.RefObject<FlatList & { getNode: () => FlatList }>;
|
||||||
|
|
||||||
export interface IListProps extends FlatListProps<any> {
|
export interface IListProps extends FlatListProps<any> {
|
||||||
listRef: TListRef;
|
listRef: TListRef;
|
||||||
|
jumpToBottom: () => void;
|
||||||
|
isThread: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const List = ({ listRef, ...props }: IListProps) => (
|
const List = ({ listRef, jumpToBottom, isThread, ...props }: IListProps) => {
|
||||||
<AnimatedFlatList
|
const [visible, setVisible] = useState(false);
|
||||||
|
|
||||||
|
const scrollHandler = useAnimatedScrollHandler({
|
||||||
|
onScroll: event => {
|
||||||
|
if (event.contentOffset.y > SCROLL_LIMIT) {
|
||||||
|
runOnJS(setVisible)(true);
|
||||||
|
} else {
|
||||||
|
runOnJS(setVisible)(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Animated.FlatList
|
||||||
testID='room-view-messages'
|
testID='room-view-messages'
|
||||||
ref={listRef}
|
ref={listRef}
|
||||||
keyExtractor={(item: any) => item.id}
|
keyExtractor={(item: any) => item.id}
|
||||||
|
@ -36,10 +51,15 @@ const List = ({ listRef, ...props }: IListProps) => (
|
||||||
onEndReachedThreshold={0.5}
|
onEndReachedThreshold={0.5}
|
||||||
maxToRenderPerBatch={5}
|
maxToRenderPerBatch={5}
|
||||||
windowSize={10}
|
windowSize={10}
|
||||||
|
scrollEventThrottle={16}
|
||||||
|
onScroll={scrollHandler}
|
||||||
{...props}
|
{...props}
|
||||||
{...scrollPersistTaps}
|
{...scrollPersistTaps}
|
||||||
/>
|
/>
|
||||||
|
<NavBottomFAB visible={visible} onPress={jumpToBottom} isThread={isThread} />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
List.propTypes = {
|
List.propTypes = {
|
||||||
listRef: PropTypes.object
|
listRef: PropTypes.object
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { StyleSheet, View } from 'react-native';
|
import { StyleSheet, View, Platform } from 'react-native';
|
||||||
import Animated, { call, cond, greaterOrEq, useCode } from 'react-native-reanimated';
|
|
||||||
|
|
||||||
import { themes } from '../../../lib/constants';
|
import { themes } from '../../../lib/constants';
|
||||||
import { CustomIcon } from '../../../containers/CustomIcon';
|
import { CustomIcon } from '../../../containers/CustomIcon';
|
||||||
import { useTheme } from '../../../theme';
|
import { useTheme } from '../../../theme';
|
||||||
import Touch from '../../../containers/Touch';
|
import Touch from '../../../containers/Touch';
|
||||||
import { hasNotch } from '../../../lib/methods/helpers';
|
|
||||||
|
|
||||||
const SCROLL_LIMIT = 200;
|
export const SCROLL_LIMIT = 200;
|
||||||
const SEND_TO_CHANNEL_HEIGHT = 40;
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
|
@ -30,45 +27,45 @@ const styles = StyleSheet.create({
|
||||||
});
|
});
|
||||||
|
|
||||||
const NavBottomFAB = ({
|
const NavBottomFAB = ({
|
||||||
y,
|
visible,
|
||||||
onPress,
|
onPress,
|
||||||
isThread
|
isThread
|
||||||
}: {
|
}: {
|
||||||
y: Animated.Value<number>;
|
visible: boolean;
|
||||||
onPress: Function;
|
onPress: Function;
|
||||||
isThread: boolean;
|
isThread: boolean;
|
||||||
}): React.ReactElement | null => {
|
}): React.ReactElement | null => {
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const [show, setShow] = useState(false);
|
|
||||||
const handleOnPress = () => onPress();
|
const handleOnPress = () => onPress();
|
||||||
const toggle = (v: boolean) => setShow(v);
|
|
||||||
|
|
||||||
useCode(
|
if (!visible) {
|
||||||
() =>
|
|
||||||
cond(
|
|
||||||
greaterOrEq(y, SCROLL_LIMIT),
|
|
||||||
call([y], () => toggle(true)),
|
|
||||||
call([y], () => toggle(false))
|
|
||||||
),
|
|
||||||
[y]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!show) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bottom = hasNotch ? 100 : 60;
|
|
||||||
if (isThread) {
|
|
||||||
bottom += SEND_TO_CHANNEL_HEIGHT;
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<Animated.View style={[styles.container, { bottom }]} testID='nav-jump-to-bottom'>
|
<View
|
||||||
|
style={[
|
||||||
|
styles.container,
|
||||||
|
{
|
||||||
|
...Platform.select({
|
||||||
|
ios: {
|
||||||
|
bottom: 100 + (isThread ? 40 : 0)
|
||||||
|
},
|
||||||
|
android: {
|
||||||
|
top: 15,
|
||||||
|
scaleY: -1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
testID='nav-jump-to-bottom'
|
||||||
|
>
|
||||||
<Touch onPress={handleOnPress} style={[styles.button, { backgroundColor: themes[theme].backgroundColor }]}>
|
<Touch onPress={handleOnPress} style={[styles.button, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||||
<View style={[styles.content, { borderColor: themes[theme].borderColor }]}>
|
<View style={[styles.content, { borderColor: themes[theme].borderColor }]}>
|
||||||
<CustomIcon name='chevron-down' color={themes[theme].auxiliaryTintColor} size={36} />
|
<CustomIcon name='chevron-down' color={themes[theme].auxiliaryTintColor} size={36} />
|
||||||
</View>
|
</View>
|
||||||
</Touch>
|
</Touch>
|
||||||
</Animated.View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -354,7 +354,7 @@ class ListContainer extends React.Component<IListContainerProps, IListContainerS
|
||||||
console.count(`${this.constructor.name}.render calls`);
|
console.count(`${this.constructor.name}.render calls`);
|
||||||
const {
|
const {
|
||||||
rid,
|
rid,
|
||||||
// tmid,
|
tmid,
|
||||||
listRef
|
listRef
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { messages, refreshing } = this.state;
|
const { messages, refreshing } = this.state;
|
||||||
|
@ -363,8 +363,6 @@ class ListContainer extends React.Component<IListContainerProps, IListContainerS
|
||||||
<EmptyRoom rid={rid} length={messages.length} mounted={this.mounted} />
|
<EmptyRoom rid={rid} length={messages.length} mounted={this.mounted} />
|
||||||
<RefreshControl refreshing={refreshing} onRefresh={this.onRefresh}>
|
<RefreshControl refreshing={refreshing} onRefresh={this.onRefresh}>
|
||||||
<List
|
<List
|
||||||
// onScroll={this.onScroll}
|
|
||||||
scrollEventThrottle={16}
|
|
||||||
listRef={listRef}
|
listRef={listRef}
|
||||||
data={messages}
|
data={messages}
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
|
@ -373,9 +371,10 @@ class ListContainer extends React.Component<IListContainerProps, IListContainerS
|
||||||
onScrollToIndexFailed={this.handleScrollToIndexFailed}
|
onScrollToIndexFailed={this.handleScrollToIndexFailed}
|
||||||
onViewableItemsChanged={this.onViewableItemsChanged}
|
onViewableItemsChanged={this.onViewableItemsChanged}
|
||||||
viewabilityConfig={this.viewabilityConfig}
|
viewabilityConfig={this.viewabilityConfig}
|
||||||
|
jumpToBottom={this.jumpToBottom}
|
||||||
|
isThread={!!tmid}
|
||||||
/>
|
/>
|
||||||
</RefreshControl>
|
</RefreshControl>
|
||||||
{/* <NavBottomFAB y={this.y} onPress={this.jumpToBottom} isThread={!!tmid} /> */}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue