import React , { useState } from 'react' ; import { Platform , RefreshControl , SafeAreaView , VirtualizedList , } from 'react-native' ; import { useNavigation } from '@react-navigation/native' ; import { CustomHeader , FooterLoadingIndicator , LoadingOrError , } from '../../components' ; import { FloatingButton } from '../../core-ui' ; import { Message_privateMessage_topicList_topics as MessageType } from '../../generated/server/Message' ; import { errorHandler , getParticipants , useStorage } from '../../helpers' ; import { useMessageList } from '../../hooks' ; import { makeStyles , useTheme } from '../../theme' ; import { MessageParticipants , StackNavProp } from '../../types' ; import { MessageCard } from './Components' ; type MessageRenderItem = { item : MessageType ; index : number ; } ; export default function Messages ( ) { const styles = useStyles ( ) ; const { colors } = useTheme ( ) ; const { navigate } = useNavigation < StackNavProp < 'Profile' > > ( ) ; const storage = useStorage ( ) ; const username = storage . getItem ( 'user' ) ?. username || '' ; const [ messages , setMessages ] = useState < Array < MessageType > > ( [ ] ) ; const [ participants , setParticipants ] = useState < Array < MessageParticipants > > ( [ ] ) ; const [ loading , setLoading ] = useState ( true ) ; const [ page , setPage ] = useState ( 0 ) ; const [ hasOlderMessages , setHasOlderMessages ] = useState ( false ) ; const ios = Platform . OS === 'ios' ; const onPressNewMessage = ( ) => { navigate ( 'NewMessage' , { users : [ ] , listOfUser : [ ] } ) ; } ; const { error , refetch , fetchMore } = useMessageList ( { variables : { username , page } , onCompleted : ( data ) => { const allMessages = data . privateMessage . topicList . topics ?? [ ] ; const allUsers = data . privateMessage . users ?? [ ] ; const tempMessages = allMessages . map ( ( item ) => ( { ... item , unseen : item . highestPostNumber - ( item . lastReadPostNumber ?? 0 ) > 0 || item . unseen , } ) ) ; const tempParticipants = allMessages . map ( ( { participants , lastPosterUsername } ) => { let userIds = participants ?. map ( ( { userId } , idx ) => userId ?? idx ) || [ ] ; return getParticipants ( userIds , allUsers , username , lastPosterUsername ?? '' ) ; } ) ; const currentMessageIds = messages . map ( ( topic ) => topic . id ) ; const incomingMessageIds = tempMessages . map ( ( topic ) => topic . id ) ; if ( JSON . stringify ( currentMessageIds ) === JSON . stringify ( incomingMessageIds ) ) { setHasOlderMessages ( false ) ; } else { setHasOlderMessages ( true ) ; } setMessages ( tempMessages ) ; setParticipants ( tempParticipants ) ; setLoading ( false ) ; } , fetchPolicy : 'network-only' , } , 'HIDE_ALERT' ) ; const onRefresh = ( ) => { setLoading ( true ) ; refetch ( ) . then ( ( ) => setLoading ( false ) ) ; } ; const onEndReached = ( ) => { if ( ! hasOlderMessages || loading ) { return ; } setLoading ( true ) ; const nextPage = page + 1 ; setPage ( nextPage ) ; fetchMore ( { variables : { username , page : nextPage } } ) . then ( ( ) => setLoading ( false ) ) ; } ; const getItem = ( messages , index ) => messages [ index ] ; const getItemCount = ( messages ) => messages . length ; const getItemLayout = ( data , index ) => ( { length : 85 , offset : 85 * index , index , } ) ; const keyExtractor = ( { id } ) => `message-${ id }` ; const renderItem = ( { item , index } ) => ( < MessageCard id = { item . id } message = { item . title } messageParticipants = { participants [ index ] } allowedUserCount = { item . allowedUserCount } postPointer = { item . lastReadPostNumber || 1 } date = { item . lastPostedAt || '' } seen = { ! item . unseen } />); let content ; if ( error ) { content = < LoadingOrError message = { errorHandler ( error , true ) } />; } else if ( loading && messages . length < 1 ) { content = < LoadingOrError loading / > ; } else if ( ! loading && messages . length < 1 ) { content = < LoadingOrError message = { t ( 'You have no messages' ) } />; } else { content = ( < VirtualizedList data = { messages } refreshControl = { < RefreshControl refreshing = { loading } onRefresh = { onRefresh } tintColor = { colors . primary } / > } getItem = { getItem } getItemCount = { getItemCount } renderItem = { renderItem } keyExtractor = { keyExtractor } getItemLayout = { getItemLayout } onEndReachedThreshold = { 0.1 } onEndReached = { onEndReached } ListFooterComponent = { < FooterLoadingIndicator isHidden = { ! hasOlderMessages } />} style={styles.messageContainer}/ > ) ; } return ( < SafeAreaView style = { styles . container } > { ios && ( < CustomHeader title = { t ( 'Messages' ) } rightIcon = "Add" onPressRight = { onPressNewMessage } / > ) } { content } { ! ios && ( < FloatingButton onPress = { onPressNewMessage } style = { styles . fab } / > ) } < /SafeAreaView>); } const useStyles = makeStyles ( ( { colors , spacing } ) => ( { container : { flex : 1 , justifyContent : 'flex-start' , alignItems : 'center' , backgroundColor : colors . background , } , messageContainer : { flex : 1 , width : '100%' , } , fab : { position : 'absolute' , marginRight : spacing . xxl , marginBottom : spacing . xxl , right : 0 , bottom : 0 , } , } ) ) ;