Use react-native-tab-view in ReactionsList

This commit is contained in:
Danish 2022-08-18 19:53:11 +05:30
parent 359171ed03
commit f1658c146a
1 changed files with 38 additions and 19 deletions

View File

@ -1,7 +1,7 @@
import React from 'react'; import React, { useState } from 'react';
import { StyleSheet, Text, Pressable, View, ScrollView } from 'react-native'; import { StyleSheet, Text, Pressable, View, ScrollView } from 'react-native';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import { FlatList } from 'react-native-gesture-handler'; import { FlatList } from 'react-native-gesture-handler';
import { TabView, SceneRendererProps, NavigationState } from 'react-native-tab-view';
import Emoji from './message/Emoji'; import Emoji from './message/Emoji';
import { useTheme } from '../theme'; import { useTheme } from '../theme';
@ -30,6 +30,12 @@ const styles = StyleSheet.create({
customEmojiStyle: { width: 25, height: 25 } customEmojiStyle: { width: 25, height: 25 }
}); });
type Route = {
key: string;
reaction: IReaction;
};
type State = NavigationState<Route>;
interface IReactionsListBase { interface IReactionsListBase {
baseUrl: string; baseUrl: string;
getCustomEmoji: TGetCustomEmoji; getCustomEmoji: TGetCustomEmoji;
@ -41,24 +47,23 @@ interface IReactionsListProps extends IReactionsListBase {
} }
interface ITabBarItem extends IReactionsListBase { interface ITabBarItem extends IReactionsListBase {
tab: IReaction; tab: { key: string; reaction: IReaction };
index: number; jumpTo?: (key: string) => void;
goToPage?: (index: number) => void;
} }
interface IReactionsTabBar extends IReactionsListBase { interface IReactionsTabBar extends IReactionsListBase {
activeTab?: number; activeTab?: number;
tabs?: IReaction[]; tabs?: { key: string; reaction: IReaction }[];
goToPage?: (index: number) => void; jumpTo?: (key: string) => void;
width: number; width: number;
} }
const TabBarItem = ({ tab, index, goToPage, baseUrl, getCustomEmoji }: ITabBarItem) => { const TabBarItem = ({ tab, jumpTo, baseUrl, getCustomEmoji }: ITabBarItem) => {
const { colors } = useTheme(); const { colors } = useTheme();
return ( return (
<Pressable <Pressable
key={tab.emoji} key={tab.key}
onPress={() => { onPress={() => {
goToPage?.(index); jumpTo?.(tab.key);
}} }}
style={({ pressed }: { pressed: boolean }) => ({ style={({ pressed }: { pressed: boolean }) => ({
opacity: pressed ? 0.7 : 1 opacity: pressed ? 0.7 : 1
@ -66,19 +71,19 @@ const TabBarItem = ({ tab, index, goToPage, baseUrl, getCustomEmoji }: ITabBarIt
> >
<View style={styles.tabBarItem}> <View style={styles.tabBarItem}>
<Emoji <Emoji
content={tab.emoji} content={tab.key}
standardEmojiStyle={styles.standardEmojiStyle} standardEmojiStyle={styles.standardEmojiStyle}
customEmojiStyle={styles.customEmojiStyle} customEmojiStyle={styles.customEmojiStyle}
baseUrl={baseUrl} baseUrl={baseUrl}
getCustomEmoji={getCustomEmoji} getCustomEmoji={getCustomEmoji}
/> />
<Text style={[styles.reactionCount, { color: colors.auxiliaryTintColor }]}>{tab.usernames.length}</Text> <Text style={[styles.reactionCount, { color: colors.auxiliaryTintColor }]}>{tab.reaction.usernames.length}</Text>
</View> </View>
</Pressable> </Pressable>
); );
}; };
const ReactionsTabBar = ({ tabs, activeTab, goToPage, baseUrl, getCustomEmoji, width }: IReactionsTabBar) => { const ReactionsTabBar = ({ tabs, activeTab, jumpTo, baseUrl, getCustomEmoji, width }: IReactionsTabBar) => {
const tabWidth = tabs && Math.max(width / tabs.length, MIN_TAB_WIDTH); const tabWidth = tabs && Math.max(width / tabs.length, MIN_TAB_WIDTH);
const { colors } = useTheme(); const { colors } = useTheme();
return ( return (
@ -94,7 +99,7 @@ const ReactionsTabBar = ({ tabs, activeTab, goToPage, baseUrl, getCustomEmoji, w
borderColor: isActiveTab ? colors.tintActive : colors.separatorColor borderColor: isActiveTab ? colors.tintActive : colors.separatorColor
}} }}
> >
<TabBarItem tab={tab} index={index} goToPage={goToPage} baseUrl={baseUrl} getCustomEmoji={getCustomEmoji} /> <TabBarItem tab={tab} jumpTo={jumpTo} baseUrl={baseUrl} getCustomEmoji={getCustomEmoji} />
</View> </View>
); );
})} })}
@ -128,16 +133,30 @@ const UsersList = ({ tabLabel }: { tabLabel: IReaction }) => {
}; };
const ReactionsList = ({ reactions, baseUrl, getCustomEmoji, width }: IReactionsListProps): React.ReactElement => { const ReactionsList = ({ reactions, baseUrl, getCustomEmoji, width }: IReactionsListProps): React.ReactElement => {
const [index, setIndex] = useState(0);
// sorting reactions in descending order on the basic of number of users reacted // sorting reactions in descending order on the basic of number of users reacted
const sortedReactions = reactions?.sort((reaction1, reaction2) => reaction2.usernames.length - reaction1.usernames.length); const sortedReactions = reactions?.sort((reaction1, reaction2) => reaction2.usernames.length - reaction1.usernames.length);
const routes = sortedReactions ? sortedReactions?.map(reaction => ({ key: reaction.emoji, reaction })) : [];
return ( return (
<View style={styles.reactionsListContainer}> <View style={styles.reactionsListContainer}>
<ScrollableTabView renderTabBar={() => <ReactionsTabBar baseUrl={baseUrl} getCustomEmoji={getCustomEmoji} width={width} />}> <TabView
{sortedReactions?.map(reaction => ( lazy
<UsersList tabLabel={reaction} key={reaction.emoji} /> navigationState={{ index, routes }}
))} renderScene={({ route }) => <UsersList tabLabel={route.reaction} />}
</ScrollableTabView> onIndexChange={setIndex}
renderTabBar={(props: SceneRendererProps & { navigationState: State }) => (
<ReactionsTabBar
tabs={routes}
jumpTo={props.jumpTo}
width={width}
baseUrl={baseUrl}
getCustomEmoji={getCustomEmoji}
activeTab={index}
/>
)}
/>
</View> </View>
); );
}; };