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); } };