Migrate NavBottomFAB to reanimated 3

This commit is contained in:
Diego Mello 2023-07-06 10:45:32 -03:00
parent 1d99145d93
commit 28d55a581e
3 changed files with 67 additions and 51 deletions

View File

@ -1,13 +1,12 @@
import PropTypes from 'prop-types';
import React from 'react';
import React, { useState } from 'react';
import { FlatListProps, StyleSheet } from 'react-native';
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 scrollPersistTaps from '../../../lib/methods/helpers/scrollPersistTaps';
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
import NavBottomFAB, { SCROLL_LIMIT } from './NavBottomFAB';
const styles = StyleSheet.create({
list: {
@ -22,24 +21,45 @@ export type TListRef = React.RefObject<FlatList & { getNode: () => FlatList }>;
export interface IListProps extends FlatListProps<any> {
listRef: TListRef;
jumpToBottom: () => void;
isThread: boolean;
}
const List = ({ listRef, ...props }: IListProps) => (
<AnimatedFlatList
testID='room-view-messages'
ref={listRef}
keyExtractor={(item: any) => item.id}
contentContainerStyle={styles.contentContainer}
style={styles.list}
removeClippedSubviews={isIOS}
initialNumToRender={7}
onEndReachedThreshold={0.5}
maxToRenderPerBatch={5}
windowSize={10}
{...props}
{...scrollPersistTaps}
/>
);
const List = ({ listRef, jumpToBottom, isThread, ...props }: IListProps) => {
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'
ref={listRef}
keyExtractor={(item: any) => item.id}
contentContainerStyle={styles.contentContainer}
style={styles.list}
removeClippedSubviews={isIOS}
initialNumToRender={7}
onEndReachedThreshold={0.5}
maxToRenderPerBatch={5}
windowSize={10}
scrollEventThrottle={16}
onScroll={scrollHandler}
{...props}
{...scrollPersistTaps}
/>
<NavBottomFAB visible={visible} onPress={jumpToBottom} isThread={isThread} />
</>
);
};
List.propTypes = {
listRef: PropTypes.object

View File

@ -1,15 +1,12 @@
import React, { useState } from 'react';
import { StyleSheet, View } from 'react-native';
import Animated, { call, cond, greaterOrEq, useCode } from 'react-native-reanimated';
import React from 'react';
import { StyleSheet, View, Platform } from 'react-native';
import { themes } from '../../../lib/constants';
import { CustomIcon } from '../../../containers/CustomIcon';
import { useTheme } from '../../../theme';
import Touch from '../../../containers/Touch';
import { hasNotch } from '../../../lib/methods/helpers';
const SCROLL_LIMIT = 200;
const SEND_TO_CHANNEL_HEIGHT = 40;
export const SCROLL_LIMIT = 200;
const styles = StyleSheet.create({
container: {
@ -30,45 +27,45 @@ const styles = StyleSheet.create({
});
const NavBottomFAB = ({
y,
visible,
onPress,
isThread
}: {
y: Animated.Value<number>;
visible: boolean;
onPress: Function;
isThread: boolean;
}): React.ReactElement | null => {
const { theme } = useTheme();
const [show, setShow] = useState(false);
const handleOnPress = () => onPress();
const toggle = (v: boolean) => setShow(v);
useCode(
() =>
cond(
greaterOrEq(y, SCROLL_LIMIT),
call([y], () => toggle(true)),
call([y], () => toggle(false))
),
[y]
);
if (!show) {
if (!visible) {
return null;
}
let bottom = hasNotch ? 100 : 60;
if (isThread) {
bottom += SEND_TO_CHANNEL_HEIGHT;
}
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 }]}>
<View style={[styles.content, { borderColor: themes[theme].borderColor }]}>
<CustomIcon name='chevron-down' color={themes[theme].auxiliaryTintColor} size={36} />
</View>
</Touch>
</Animated.View>
</View>
);
};

View File

@ -354,7 +354,7 @@ class ListContainer extends React.Component<IListContainerProps, IListContainerS
console.count(`${this.constructor.name}.render calls`);
const {
rid,
// tmid,
tmid,
listRef
} = this.props;
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} />
<RefreshControl refreshing={refreshing} onRefresh={this.onRefresh}>
<List
// onScroll={this.onScroll}
scrollEventThrottle={16}
listRef={listRef}
data={messages}
renderItem={this.renderItem}
@ -373,9 +371,10 @@ class ListContainer extends React.Component<IListContainerProps, IListContainerS
onScrollToIndexFailed={this.handleScrollToIndexFailed}
onViewableItemsChanged={this.onViewableItemsChanged}
viewabilityConfig={this.viewabilityConfig}
jumpToBottom={this.jumpToBottom}
isThread={!!tmid}
/>
</RefreshControl>
{/* <NavBottomFAB y={this.y} onPress={this.jumpToBottom} isThread={!!tmid} /> */}
</>
);
}