|
| 1 | +import React from 'react'; |
| 2 | +import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; |
| 3 | +import { useNavigation } from '@react-navigation/native'; |
| 4 | +import { randParagraph, randUuid } from '@ngneat/falso'; |
| 5 | +import { BlurView } from '@react-native-community/blur'; |
| 6 | +import { useSafeAreaInsets } from 'react-native-safe-area-context'; |
| 7 | +import { StatusBar } from 'expo-status-bar'; |
| 8 | +import { |
| 9 | + Header, |
| 10 | + ScrollHeaderProps, |
| 11 | + FlatListWithHeaders, |
| 12 | + SurfaceComponentProps, |
| 13 | +} from '@codeherence/react-native-header'; |
| 14 | +import { Avatar, BackButton } from '../../components'; |
| 15 | +import { RANDOM_IMAGE_NUM } from '../../constants'; |
| 16 | +import { range } from '../../utils'; |
| 17 | +import type { InvertedUsageScreenNavigationProps } from '../../navigation'; |
| 18 | + |
| 19 | +const HeaderSurface: React.FC<SurfaceComponentProps> = () => { |
| 20 | + return <BlurView style={StyleSheet.absoluteFill} blurType="chromeMaterialDark" />; |
| 21 | +}; |
| 22 | + |
| 23 | +const HeaderComponent: React.FC<ScrollHeaderProps> = ({ showNavBar }) => { |
| 24 | + const navigation = useNavigation(); |
| 25 | + const onPressProfile = () => navigation.navigate('Profile'); |
| 26 | + |
| 27 | + return ( |
| 28 | + <Header |
| 29 | + showNavBar={showNavBar} |
| 30 | + noBottomBorder |
| 31 | + headerCenterFadesIn={false} |
| 32 | + headerCenter={ |
| 33 | + <Text style={styles.navBarTitle} numberOfLines={1}> |
| 34 | + Elon Musk |
| 35 | + </Text> |
| 36 | + } |
| 37 | + headerRight={ |
| 38 | + <TouchableOpacity onPress={onPressProfile}> |
| 39 | + <Avatar size="sm" source={{ uri: `https://i.pravatar.cc/128?img=${RANDOM_IMAGE_NUM}` }} /> |
| 40 | + </TouchableOpacity> |
| 41 | + } |
| 42 | + headerLeft={<BackButton color="white" />} |
| 43 | + SurfaceComponent={HeaderSurface} |
| 44 | + /> |
| 45 | + ); |
| 46 | +}; |
| 47 | + |
| 48 | +interface ChatMessage { |
| 49 | + id: string; |
| 50 | + message: string; |
| 51 | + type: 'sent' | 'received'; |
| 52 | +} |
| 53 | + |
| 54 | +const data: ChatMessage[] = range({ end: 100 }).map((i) => { |
| 55 | + const id = randUuid(); |
| 56 | + const message = randParagraph(); |
| 57 | + const type = i % 2 === 0 ? 'sent' : 'received'; |
| 58 | + |
| 59 | + return { id, message, type }; |
| 60 | +}); |
| 61 | + |
| 62 | +const ChatMessage: React.FC<ChatMessage> = ({ message, type }) => { |
| 63 | + return ( |
| 64 | + <View style={type === 'sent' ? styles.sentMessageContainer : styles.receivedMessageContainer}> |
| 65 | + <Text style={styles.messageText}>{message}</Text> |
| 66 | + </View> |
| 67 | + ); |
| 68 | +}; |
| 69 | + |
| 70 | +const Inverted: React.FC<InvertedUsageScreenNavigationProps> = () => { |
| 71 | + const { bottom } = useSafeAreaInsets(); |
| 72 | + |
| 73 | + return ( |
| 74 | + <> |
| 75 | + <StatusBar style="light" /> |
| 76 | + <FlatListWithHeaders |
| 77 | + data={data} |
| 78 | + renderItem={({ item }) => <ChatMessage {...item} />} |
| 79 | + HeaderComponent={HeaderComponent} |
| 80 | + keyExtractor={(item) => item.id} |
| 81 | + inverted |
| 82 | + absoluteHeader |
| 83 | + containerStyle={styles.container} |
| 84 | + contentContainerStyle={[styles.contentContainer, { paddingTop: bottom }]} |
| 85 | + showsVerticalScrollIndicator |
| 86 | + indicatorStyle={'white'} |
| 87 | + /> |
| 88 | + </> |
| 89 | + ); |
| 90 | +}; |
| 91 | + |
| 92 | +export default Inverted; |
| 93 | + |
| 94 | +const styles = StyleSheet.create({ |
| 95 | + container: { |
| 96 | + backgroundColor: 'black', |
| 97 | + }, |
| 98 | + contentContainer: { |
| 99 | + backgroundColor: 'black', |
| 100 | + paddingHorizontal: 12, |
| 101 | + }, |
| 102 | + navBarTitle: { fontSize: 16, fontWeight: 'bold', color: 'white' }, |
| 103 | + messageText: { |
| 104 | + color: 'white', |
| 105 | + }, |
| 106 | + sentMessageContainer: { |
| 107 | + backgroundColor: '#186BE7', |
| 108 | + alignSelf: 'flex-start', |
| 109 | + borderRadius: 12, |
| 110 | + maxWidth: '75%', |
| 111 | + padding: 12, |
| 112 | + marginVertical: 12, |
| 113 | + }, |
| 114 | + receivedMessageContainer: { |
| 115 | + backgroundColor: '#1F2329', |
| 116 | + alignItems: 'flex-end', |
| 117 | + justifyContent: 'flex-end', |
| 118 | + alignSelf: 'flex-end', |
| 119 | + borderRadius: 12, |
| 120 | + maxWidth: '75%', |
| 121 | + padding: 12, |
| 122 | + marginVertical: 12, |
| 123 | + }, |
| 124 | + separator: { |
| 125 | + height: 24, |
| 126 | + }, |
| 127 | +}); |
0 commit comments