import { useState, useRef, useEffect, useGlobal, getGlobal } from 'reactn' import { Pressable, TextInput, View, Image, Text, Keyboard, FlatList } from 'react-native' import { responsiveHeight } from '../actions/responsiveSizes.js' import { useDataFromRef } from 'react-native-minuit/src/hooks' import { useKeyboard } from '@react-native-community/hooks' import moment from 'moment' import { Fonts, gutters, Palette } from '../styles' import Style, { bubbleStyle } from '../styles/Style' import firebase, { chatsRef } from '../config/firebase' import { formatNameForConfidentiality } from '../helpers/index.js' import useLayoutType from '../hooks/useLayoutType.js' import TypingLoader from './TypingLoader' import Avatar from './Avatar' import RenderChatFile from './RenderChatFile.js' import HyperlinkContainer from './HyperlinkContainer.js' export default ({ chatID = null, layout = 'default', // default | taskSideBar containerStyle = {}, messageListContainerStyle = {}, }) => { const [currentUID] = useGlobal('currentUID') const [currentProjectData] = useGlobal('currentProjectData') const [isTyping] = useState(false) const flatListRef = useRef() const { isNative } = useLayoutType() const { keyboardShown = false } = useKeyboard() const { data: messageList } = useDataFromRef({ ref: chatID ? chatsRef.doc(chatID).collection('messages').orderBy('createdAt', 'desc').limit(50) : null, simpleRef: false, listener: true, condition: chatID, refreshArray: [chatID], documentID: 'messageID', }) let conversation = [ isTyping ? { senderID: 'minuit.ai', userTyping: true } : null, ...(messageList || []), ].filter((item) => item) if (layout === 'default') { conversation = conversation.reverse() } useEffect(() => { if (flatListRef?.current && isNative && keyboardShown) { flatListRef?.current?.scrollToEnd?.({ animated: true }) } }, [keyboardShown, isNative]) return ( item?.messageID ? `${item?.messageID?.toString()}-${index}` : `no-messageID-${index}` } renderItem={({ item: { createdAt = null, senderID, senderName = '', senderProfilePicture = null, text = '', userTyping = false, files = [], }, index, }) => { const isCurrentUser = senderID === currentUID const isChatbot = senderID === 'minuit.ai' const senderData = currentProjectData?.teamMembers?.[senderID] || {} const isDayChange = moment(createdAt?.toDate()).format('DD/MM/YYYY') !== moment(conversation[index - 1]?.createdAt?.toDate() || new Date()).format( 'DD/MM/YYYY' ) || !conversation[index - 1] return ( <> {isDayChange && ( {moment(createdAt?.toDate()).format('[Le] DD/MM/YYYY [à] HH:mm')} )} {!isCurrentUser && ( )} {files?.map((props, index) => ( 0 || userTyping ? gutters / 2 : 0, }} /> )) || null} {(text?.length > 0 || userTyping) && ( 0 ? gutters / 2 : 0, }, }), }} > {userTyping ? ( ) : ( {text} )} )} ) }} /> ) } export const onSendMessage = async ({ chatID = null, projectID = null, message = '', setMessage = () => {}, setIsTyping = () => {}, customPayload = {}, }) => { try { const currentUID = getGlobal()?.currentUID || null const { name = '', profilePictureURL = null } = getGlobal()?.currentUserData || {} if (message.length > 0 || customPayload?.files?.length > 0) { Keyboard.dismiss() setMessage('') const messageData = { projectID, createdAt: firebase.firestore.FieldValue.serverTimestamp(), senderID: currentUID, senderName: formatNameForConfidentiality({ name }), senderProfilePicture: profilePictureURL || null, text: message, ...customPayload, } await chatsRef.doc(chatID).collection('messages').add(messageData) } } catch (error) { console.log(error) } finally { setIsTyping(false) } }