UNPKG

softchatjs-react-native

Version:

React native UI SDK for softchatjs-core. Create a free account at: https://www.softchatjs.com

1,043 lines (1,019 loc) 33.8 kB
// src/components/Conversations/index.tsx import React11, { useMemo as useMemo3 } from "react"; import { ActivityIndicator, FlatList as FlatList3, Text as Text8, TouchableOpacity as TouchableOpacity5, View as View8 } from "react-native"; import { forwardRef, useCallback as useCallback2, useEffect as useEffect3, useImperativeHandle, useRef as useRef3, useState as useState3 } from "react"; // src/components/Conversations/Conversation.tsx import { TouchableOpacity as TouchableOpacity2, View as View4, StyleSheet as StyleSheet3, Text as Text4 } from "react-native"; import React6, { useCallback, useMemo as useMemo2 } from "react"; // src/utils/index.ts import moment from "moment"; import { MessageStates } from "softchatjs-core"; var getUserInfoWithId = (userId, participantList) => { let presentUser = participantList.find((participant) => participant.participantId === userId); let otherParticipants = participantList.filter((participant) => participant.participantId !== userId); return { presentUser: presentUser?.participantDetails, receivingUser: otherParticipants[0]?.participantDetails }; }; var truncate = (str, len) => { return str.length > len ? str.substring(0, len) + "..." : str; }; var getConversationTitle = (userId, converstaion) => { if (converstaion.conversationType !== "group-chat") { const userInfos = getUserInfoWithId(userId, converstaion.participantList); const firstname = userInfos.receivingUser?.firstname; const username = userInfos.receivingUser?.username; return firstname ? firstname : username; } return converstaion.groupMeta?.groupName || "no-groupname"; }; function formatConversationTime(time) { const now = moment(); const then = moment(time); const duration = moment.duration(now.diff(then)); const years = Math.floor(duration.asYears()); if (years > 0) return years + "yr"; const months = Math.floor(duration.asMonths()); if (months > 0) return months + "mo"; const weeks = Math.floor(duration.asWeeks()); if (weeks > 0) return weeks + "w"; const days = Math.floor(duration.asDays()); if (days > 0) return days + "d"; const hours = Math.floor(duration.asHours()); if (hours > 0) return hours + "h"; const minutes = Math.floor(duration.asMinutes()); if (minutes > 0) return minutes + "m"; return "Just now"; } var getUnreadMessageIds = (conversation, userId) => { var ids = []; conversation.messages.map((m) => { if (m.messageState === MessageStates.SENT && m.from !== userId) { ids.push(m.messageId); } }); return ids; }; var getParticipant = (uid, participantList) => { return participantList.find((p) => p.participantDetails.uid === uid); }; // src/components/Conversations/ConversationAvatar.tsx import { View as View2, StyleSheet as StyleSheet2, Text as Text2 } from "react-native"; import React4, { useMemo } from "react"; // src/constants/Colors.ts var Colors = { greyLighter: "#F0F0F0" }; // src/components/Conversations/ConversationAvatar.tsx import { Image } from "expo-image"; // src/contexts/ChatProvider.tsx import React3, { createContext as createContext3, useContext as useContext3 } from "react"; // src/contexts/ModalProvider.tsx import React, { createContext, useContext, useState } from "react"; import { Modal, View } from "react-native"; var initial = { displayModal: () => { }, resetModal: () => { }, modalProps: { dismissable: true, justifyContent: "center", children: null, animation: "slide", containerWidth: "100%" } }; var ModalProviderContext = createContext(initial); var useModalProvider = () => useContext(ModalProviderContext); // src/theme/colors.ts var teal = { 50: "#DCF2F0", 100: "#A9DFD8", 200: "#73CABE", 300: "#3AB4A4", 400: "#00A391", 500: "#00927E", 600: "#008572", 700: "#007662", 800: "#006654", 900: "#004A38" }; var green = { 50: "#E6F5E4", 100: "#C2E6BD", 200: "#9AD693", 300: "#6FC666", 400: "#4ABA42", 500: "#17AE13", 600: "#029F04", 700: "#008D00", 800: "#007C00", 900: "#005E00" }; var grey = { 50: "#F6F6FF", 100: "#F2F1FF", 200: "#EBEBF9", 300: "#CAC9D7", 400: "#ACACB9", 500: "#82818F", 600: "#6D6D7A", 700: "#4D4D59", 800: "#2B2B36", 900: "#21222D", A100: "#1D1E26" }; var stone = { 50: "#F8F8F8", 100: "#EFEFEF", 200: "#E8E8E8", 300: "#D9D9D9", 400: "#D2D2D2", 500: "#A0A0A0", 600: "#87888C", 700: "#2C2D33", 800: "#1D1E26", 900: "#171821" }; // src/theme/index.ts var theme = { background: { primary: stone[900], secondary: grey[900], disabled: grey[800] }, text: { primary: "black", secondary: stone[200], disabled: stone[500] }, action: { primary: teal[50], secondary: stone[300] }, chatBubble: { left: { bgColor: grey[900], messageColor: stone[200], messageTimeColor: "grey", replyBorderColor: stone[200] }, right: { bgColor: "#474952", messageColor: "white", messageTimeColor: "grey", replyBorderColor: green[900] } }, icon: "white", divider: stone[700] }; var theme_default = theme; // src/contexts/MessageStateContext.tsx import React2, { createContext as createContext2, useState as useState2, useContext as useContext2 } from "react"; import { Audio } from "expo-av"; // src/constants/defaultUser.ts var defaultUser_default = { id: "", uid: "", username: "", firstname: "", lastname: "", profileUrl: "", color: "", custom: {} }; // src/contexts/MessageStateContext.tsx var initialMessageStateContext = { globalTextMessage: "", setGlobalTextMessage: () => { }, stickers: [], setStickers: () => { }, pendingMessages: [], addNewPendingMessages: (message) => { }, removePendingMessage: (messageId) => { }, updatePendingMessage: (messageId, message) => { }, playVoiceMessage: (media) => { }, pauseVoiceMessage: () => { }, resumeVoiceMessage: () => { }, audioState: null, unload: () => { }, sound: null, activeVoiceMessage: null, avPlayBackStatus: null, userMeta: defaultUser_default, setUserMeta: () => { }, conversationList: [], setConversationList: () => { } }; var MessageStateContext = createContext2( initialMessageStateContext ); var useMessageState = () => useContext2(MessageStateContext); // src/contexts/ChatProvider.tsx var ConfigContext = createContext3({ theme: theme_default, client: null, fontFamily: void 0, fontScale: 1 }); function useConfig() { return useContext3(ConfigContext); } // src/components/Conversations/ConversationAvatar.tsx var avatarSize = 50; var ConversationAvatar = ({ type, chatUserId, participantList, groupMeta, conversationTitle }) => { const { fontFamily, fontScale } = useConfig(); const userInfo = useMemo(() => { if (type === "private-chat") { return getUserInfoWithId(chatUserId, participantList); } return null; }, [chatUserId, participantList, type]); const imageUri = type === "private-chat" ? userInfo?.receivingUser?.profileUrl : groupMeta?.groupIcon; const initials = conversationTitle ? conversationTitle.substring(0, 1) : ""; return imageUri ? /* @__PURE__ */ React4.createElement(Image, { source: { uri: imageUri }, style: styles.avatar, cachePolicy: "disk" }) : /* @__PURE__ */ React4.createElement(View2, { style: styles.avatar }, /* @__PURE__ */ React4.createElement(Text2, { style: { ...styles.avatarInitials, fontSize: 30 * fontScale, fontFamily } }, initials)); }; var styles = StyleSheet2.create({ main: { height: "100%", width: "100%" }, conversationTitle: { color: "black", fontSize: 20, textTransform: "capitalize" }, messageText: { color: "black", fontSize: 17 }, messageTime: {}, avatar: { height: avatarSize, width: avatarSize, borderRadius: avatarSize, backgroundColor: Colors.greyLighter, alignItems: "center", justifyContent: "center", marginEnd: 10 }, avatarInitials: { fontSize: 30, textTransform: "capitalize", color: "white" }, listItem: { height: 80, width: "100%", paddingHorizontal: 10, flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }); // src/components/Badge.tsx import React5 from "react"; import { View as View3, Text as Text3 } from "react-native"; var UnreadMessagesBadge = (props) => { const { label } = props; return /* @__PURE__ */ React5.createElement(View3, { style: { height: 25, width: 25, borderRadius: 25, backgroundColor: "lightblue", alignItems: "center", justifyContent: "center" } }, /* @__PURE__ */ React5.createElement(Text3, { style: { color: "white", fontWeight: "bold" } }, label)); }; // src/components/Conversations/Conversation.tsx var ConversationItem = (props) => { const { theme: theme2, fontFamily, fontScale } = useConfig(); const { conversation, chatUserId, isLastItem, onPress, lastMessage, unread } = props; let conversationTitle = useMemo2(() => { return getConversationTitle(chatUserId, conversation); }, [chatUserId, conversation]); let getUnreadMessages = useMemo2(() => { return getUnreadMessageIds(conversation, chatUserId); }, [conversation]); const renderLastMessage = useCallback(() => { if (!lastMessage) { return null; } if (lastMessage.reactions.length > 0 && chatUserId !== lastMessage?.reactions[lastMessage.reactions.length - 1].uid) { return /* @__PURE__ */ React6.createElement(Text4, { style: { fontSize: 15.5 * fontScale, color: theme2?.text.secondary, fontFamily } }, /* @__PURE__ */ React6.createElement(Text4, { style: { fontStyle: "italic" } }, "@", getParticipant( lastMessage.reactions[lastMessage.reactions.length - 1]?.uid, conversation.participantList )?.participantDetails.username), " ", 'reacted "', lastMessage.reactions[0]?.emoji, '" to your message.'); } if (lastMessage.message) { return /* @__PURE__ */ React6.createElement(Text4, { style: { fontSize: 15.5 * fontScale, color: theme2?.text.secondary, fontFamily } }, lastMessage.from === chatUserId ? "You: " : "", truncate(lastMessage.message, 35)); } else { return /* @__PURE__ */ React6.createElement(View4, { style: { flexDirection: "row", alignItems: "center" } }, /* @__PURE__ */ React6.createElement(Text4, { style: { fontSize: 15.5 * fontScale, color: theme2?.text.secondary, fontFamily } }, lastMessage.from === chatUserId ? "You: " : ""), /* @__PURE__ */ React6.createElement(View4, { style: { padding: 3, borderWidth: 1, borderColor: theme2?.divider, borderRadius: 3 } }, /* @__PURE__ */ React6.createElement( Text4, { style: { fontFamily, fontSize: 10 * fontScale, color: theme2?.text.secondary } }, lastMessage.attachmentType || "media" ))); } }, [lastMessage]); return ( // <Draggeble actionContainer={ // <View style={{ flex: 1, backgroundColor: 'red', width: '100%', height: '100%' }}> // <Text>hello</Text> // </View> // }> /* @__PURE__ */ React6.createElement( TouchableOpacity2, { style: styles2.listItemContainer, onPress: () => onPress() }, /* @__PURE__ */ React6.createElement( ConversationAvatar, { chatUserId, participantList: conversation.participantList, type: conversation.conversationType, groupMeta: conversation.groupMeta, conversationTitle } ), /* @__PURE__ */ React6.createElement( View4, { style: [ { ...styles2.listItem }, !isLastItem && { borderBottomWidth: 0.5, borderBottomColor: theme2?.divider } ] }, /* @__PURE__ */ React6.createElement( View4, { style: { flexDirection: "row", flex: 1, alignItems: "center" } }, /* @__PURE__ */ React6.createElement(View4, { style: { flex: 1 } }, /* @__PURE__ */ React6.createElement( Text4, { style: { textTransform: "capitalize", fontSize: 20 * fontScale, color: theme2?.text.secondary, fontFamily } }, conversationTitle ), /* @__PURE__ */ React6.createElement(React6.Fragment, null, renderLastMessage())) ), /* @__PURE__ */ React6.createElement(View4, { style: { alignItems: "flex-end" } }, unread.length > 0 && /* @__PURE__ */ React6.createElement(UnreadMessagesBadge, { label: unread.length }), lastMessage && /* @__PURE__ */ React6.createElement( Text4, { style: { fontSize: 15.5 * fontScale, color: theme2?.text.secondary, fontFamily } }, formatConversationTime(lastMessage?.createdAt) )) ) ) ); }; var styles2 = StyleSheet3.create({ main: { height: "100%", width: "100%" }, conversationTitle: { fontSize: 20, textTransform: "capitalize" }, messageText: { fontSize: 15.5 }, messageTime: {}, avatarInitials: { fontSize: 30, textTransform: "capitalize", color: "white" }, listItemContainer: { flexDirection: "row", height: 80, flex: 1, alignItems: "center" }, listItem: { width: "100%", height: "100%", flexDirection: "row", alignItems: "center", flex: 1, justifyContent: "space-between" }, typing: { fontStyle: "italic", color: "green" } }); // src/components/Conversations/index.tsx import { GestureHandlerRootView } from "react-native-gesture-handler"; import { Events } from "softchatjs-core"; // src/assets/icons.tsx import React7 from "react"; import { View as View5 } from "react-native"; import { Svg, Path, G, Defs, ClipPath, Rect } from "react-native-svg"; function XIcon(props) { const { size = 25, color = "black" } = props; return /* @__PURE__ */ React7.createElement(Svg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React7.createElement( Path, { d: "M6 18L17.94 6M18 18L6.06 6", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" } )); } var ChatIcon = (props) => { const { size = 25, color = "black" } = props; return /* @__PURE__ */ React7.createElement(Svg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React7.createElement( Path, { d: "M12 2C17.523 2 22 6.477 22 12C22 17.523 17.523 22 12 22H4C3.46957 22 2.96086 21.7893 2.58579 21.4142C2.21071 21.0391 2 20.5304 2 20V12C2 6.477 6.477 2 12 2ZM12 14H9C8.73478 14 8.48043 14.1054 8.29289 14.2929C8.10536 14.4804 8 14.7348 8 15C8 15.2652 8.10536 15.5196 8.29289 15.7071C8.48043 15.8946 8.73478 16 9 16H12C12.2652 16 12.5196 15.8946 12.7071 15.7071C12.8946 15.5196 13 15.2652 13 15C13 14.7348 12.8946 14.4804 12.7071 14.2929C12.5196 14.1054 12.2652 14 12 14ZM15 10H9C8.74512 10.0003 8.49997 10.0979 8.31463 10.2728C8.1293 10.4478 8.01776 10.687 8.00283 10.9414C7.98789 11.1958 8.07067 11.4464 8.23426 11.6418C8.39785 11.8373 8.6299 11.9629 8.883 11.993L9 12H15C15.2549 11.9997 15.5 11.9021 15.6854 11.7272C15.8707 11.5522 15.9822 11.313 15.9972 11.0586C16.0121 10.8042 15.9293 10.5536 15.7657 10.3582C15.6021 10.1627 15.3701 10.0371 15.117 10.007L15 10Z", fill: color } )); }; var ChatIconPlus = (props) => { const { size = 25, color = "black" } = props; return /* @__PURE__ */ React7.createElement(Svg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React7.createElement( Path, { d: "M19 8V2", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" } ), /* @__PURE__ */ React7.createElement( Path, { fillRule: "evenodd", clipRule: "evenodd", d: "M20.7299 9.80407C21.064 11.1317 21.0907 12.5181 20.8082 13.8576C20.5256 15.1972 19.9412 16.4546 19.0994 17.5342C18.2575 18.6138 17.1805 19.4872 15.9503 20.0878C14.72 20.6884 13.369 21.0004 11.9999 21.0001H7.49993C6.10193 21.0001 5.40293 21.0001 4.85193 20.7721C4.48784 20.6213 4.15702 20.4003 3.87837 20.1216C3.59972 19.843 3.3787 19.5122 3.22793 19.1481C2.99993 18.5971 2.99993 17.8981 2.99993 16.5001V12.0001C2.99962 10.631 3.31164 9.27999 3.91223 8.04974C4.51282 6.81949 5.38616 5.74246 6.46578 4.90064C7.54539 4.05882 8.80283 3.47439 10.1424 3.19183C11.4819 2.90927 12.8683 2.93603 14.1959 3.27007C13.8569 3.62372 13.6293 4.06918 13.5413 4.5511C13.4533 5.03303 13.5089 5.53018 13.7011 5.9808C13.8933 6.43142 14.2136 6.81565 14.6223 7.08575C15.031 7.35585 15.51 7.49992 15.9999 7.50007H16.4999V8.00007C16.5001 8.48996 16.6441 8.96901 16.9143 9.37771C17.1844 9.78641 17.5686 10.1067 18.0192 10.2989C18.4698 10.4911 18.967 10.5467 19.4489 10.4587C19.9308 10.3707 20.3763 10.1431 20.7299 9.80407ZM14.9999 10.0001C15.2651 10.0001 15.5195 10.1054 15.707 10.293C15.8946 10.4805 15.9999 10.7349 15.9999 11.0001C15.9999 11.2653 15.8946 11.5196 15.707 11.7072C15.5195 11.8947 15.2651 12.0001 14.9999 12.0001H8.99993C8.73471 12.0001 8.48036 11.8947 8.29282 11.7072C8.10529 11.5196 7.99993 11.2653 7.99993 11.0001C7.99993 10.7349 8.10529 10.4805 8.29282 10.293C8.48036 10.1054 8.73471 10.0001 8.99993 10.0001H14.9999ZM11.9999 14.0001C12.2651 14.0001 12.5195 14.1054 12.707 14.293C12.8946 14.4805 12.9999 14.7349 12.9999 15.0001C12.9999 15.2653 12.8946 15.5196 12.707 15.7072C12.5195 15.8947 12.2651 16.0001 11.9999 16.0001H8.99993C8.73471 16.0001 8.48036 15.8947 8.29282 15.7072C8.10529 15.5196 7.99993 15.2653 7.99993 15.0001C7.99993 14.7349 8.10529 14.4805 8.29282 14.293C8.48036 14.1054 8.73471 14.0001 8.99993 14.0001H11.9999Z", fill: color } ), /* @__PURE__ */ React7.createElement( Path, { d: "M22 5H16", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" } )); }; // src/components/Search.tsx import { View as View6, TextInput } from "react-native"; import React8 from "react"; function Search(props) { const { theme: theme2, fontFamily } = useConfig(); const { value, setValue, placeholder, containerStyle } = props; return /* @__PURE__ */ React8.createElement( View6, { style: { paddingHorizontal: 10, marginVertical: 10, width: "100%", ...containerStyle } }, /* @__PURE__ */ React8.createElement( TextInput, { style: { height: 45, width: "100%", borderWidth: 1, borderColor: theme2?.divider, borderRadius: 10, paddingStart: 10, color: theme2?.text.secondary, fontFamily }, placeholder, placeholderTextColor: "grey", value, onChangeText: (val) => setValue(val) } ) ); } // src/components/Conversations/index.tsx import { StatusBar } from "expo-status-bar"; // src/components/Modals/UserList.tsx import { View as View7, Text as Text7, StyleSheet as StyleSheet4, FlatList as FlatList2, TouchableOpacity as TouchableOpacity4, Platform } from "react-native"; import React10 from "react"; // src/components/Chat/MessageAvatar.tsx import React9 from "react"; import { TouchableOpacity as TouchableOpacity3, Text as Text6 } from "react-native"; import { Image as Image3 } from "expo-image"; function MessageAvatar(props) { const { imgUrl, initials, size = 40, style } = props; const { fontFamily } = useConfig(); return /* @__PURE__ */ React9.createElement( TouchableOpacity3, { style: { height: size, width: size, borderRadius: size, backgroundColor: "black", alignItems: "center", justifyContent: "center", ...style } }, imgUrl ? /* @__PURE__ */ React9.createElement( Image3, { source: { uri: imgUrl }, cachePolicy: "disk", style: { height: size, width: size, borderRadius: size, backgroundColor: Colors.greyLighter } } ) : /* @__PURE__ */ React9.createElement( Text6, { style: { fontSize: size / 2, textTransform: "uppercase", color: "white", fontFamily } }, initials ) ); } // src/components/Modals/UserList.tsx function UserList(props) { const { data, goToChat, title = "Start conversation" } = props; const { theme: theme2, client, fontFamily } = useConfig(); const { resetModal } = useModalProvider(); const startChat = (data2) => { if (client) { const msClient = client.newConversation({ ...data2 }, null); const res = msClient.create("Hey\u{1F44B}"); resetModal(); setTimeout(() => { goToChat(); }, 500); } }; return /* @__PURE__ */ React10.createElement(View7, { style: { ...styles3.container, backgroundColor: theme2?.background.primary } }, /* @__PURE__ */ React10.createElement(View7, { style: { ...styles3.header } }, /* @__PURE__ */ React10.createElement(Text7, { style: { color: theme2?.text.secondary, fontFamily, fontSize: 25 } }, title), /* @__PURE__ */ React10.createElement(TouchableOpacity4, { onPress: () => resetModal() }, /* @__PURE__ */ React10.createElement(XIcon, { size: 25, color: theme2?.icon }))), /* @__PURE__ */ React10.createElement( FlatList2, { data, style: { marginTop: 20 }, renderItem: ({ item, index }) => /* @__PURE__ */ React10.createElement( TouchableOpacity4, { onPress: () => startChat(item), style: styles3.userItem }, /* @__PURE__ */ React10.createElement( MessageAvatar, { size: 50, initials: item.username.substring(0, 1), imgUrl: item.profileUrl, style: { marginEnd: 15 } } ), /* @__PURE__ */ React10.createElement(View7, { style: { flex: 1 } }, /* @__PURE__ */ React10.createElement(Text7, { style: { color: theme2?.text.secondary, fontSize: 18, fontFamily } }, item.firstname, " ", item.lastname), /* @__PURE__ */ React10.createElement(Text7, { style: { color: theme2?.text.secondary, fontFamily, fontSize: 12 } }, item.username)) ) } )); } var styles3 = StyleSheet4.create({ container: { flex: 1, height: "100%", width: "100%", padding: 20 }, header: { // height: 50, width: "100%", flexDirection: "row", alignItems: "center", paddingTop: Platform.OS === "ios" ? 30 : 10, justifyContent: "space-between" }, userItem: { height: 70, width: "100%", flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }); // src/components/Conversations/index.tsx var retrieveFromCache = (store) => { try { const values = Object.values(store).flat(); values.sort( (a, b) => new Date(b.lastMessage?.createdAt).getTime() - new Date(a.lastMessage?.createdAt).getTime() ); return values; } catch (error) { return []; } }; var Conversations = forwardRef((props, ref) => { const { onOpen, renderItem, renderHeader, user, renderPlaceHolder, users = [], store = {} } = props; const { client, theme: theme2, fontFamily } = useConfig(); const { activeVoiceMessage, unload, setUserMeta } = useMessageState(); const [searchVal, setSearchVal] = useState3(""); const { displayModal } = useModalProvider(); const flatListRef = useRef3(null); const [conversationList, setConversationList] = useState3([...retrieveFromCache(store)]); const [connectionStatus, setConnectionStatus] = useState3({ isConnected: false, fetchingConversations: false, connecting: false }); const reconnect = () => { if (client) { client.initializeUser(user, { connectionConfig: { reset: true } }); } }; useImperativeHandle(ref, () => ({ retryConnection: () => { } })); const handleConnectionChanged = (event) => { setConnectionStatus(event); }; var sortConversations = (data) => { const values = Object.values(data).flat(); try { values.sort( (a, b) => new Date(b.lastMessage?.createdAt).getTime() - new Date(a.lastMessage?.createdAt).getTime() ); return values; } catch (error) { return values; } }; const handleConversationListChanged = (event) => { try { setConversationList(sortConversations(event.conversationListMeta)); } catch (error) { } }; useEffect3(() => { if (client) { setUserMeta(user); } }, [user, client]); const getMemoizedConversations = () => { const res = client.getConversations(); setConversationList(sortConversations(res)); }; const getConnectionStatus = () => { const connStatus = client.getConnectionStatus(); setConnectionStatus(connStatus); }; useEffect3(() => { if (client) { getMemoizedConversations(); getConnectionStatus(); client.subscribe(Events.CONNECTION_CHANGED, handleConnectionChanged); client.subscribe( Events.CONVERSATION_LIST_META_CHANGED, handleConversationListChanged ); return () => { client.unsubscribe(Events.CONNECTION_CHANGED, handleConnectionChanged); client.unsubscribe( Events.CONVERSATION_LIST_META_CHANGED, handleConversationListChanged ); }; } }, [client]); const renderConversations = useCallback2( ({ item, index }) => { if (renderItem) { let conversationTitle = getConversationTitle( user.uid, item.conversation ); const userInfo = getUserInfoWithId( user.uid, item.conversation.participantList ); const imageUrl = item.conversation.conversationType === "private-chat" ? userInfo?.receivingUser?.profileUrl : item.conversation.groupMeta?.groupIcon; return /* @__PURE__ */ React11.createElement( TouchableOpacity5, { onPress: () => onOpen({ activeConversation: item }) }, /* @__PURE__ */ React11.createElement(React11.Fragment, null, renderItem({ conversationDetails: { title: conversationTitle, recipient: userInfo.presentUser, lastMessage: item.lastMessage, imageUrl } })) ); } return /* @__PURE__ */ React11.createElement( ConversationItem, { onPress: () => onOpen({ activeConversation: item }), chatUserId: user.uid, key: index, conversation: { ...item.conversation }, lastMessage: item.lastMessage, unread: item.unread, isLastItem: conversationList.length === index + 1 } ); }, [renderItem, conversationList] ); const filteredConversations = useMemo3(() => { try { const userId = user.uid; const data = conversationList.filter((c) => { const participantMatch = c.conversation.participantList.some((participant) => { const username = participant.participantDetails.username.toLowerCase(); const firstname = participant.participantDetails?.firstname?.toLowerCase() || ""; const lastname = participant.participantDetails?.lastname?.toLowerCase() || ""; const uid = participant.participantDetails?.uid; return uid !== userId && // Exclude participants with this specific userId (username.includes(searchVal.toLowerCase()) || firstname.includes(searchVal.toLowerCase()) || lastname.includes(searchVal.toLowerCase())); }); return participantMatch; }); return data; } catch (error) { return conversationList; } }, [conversationList, searchVal]); return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(GestureHandlerRootView, { style: { flex: 1 } }, /* @__PURE__ */ React11.createElement(StatusBar, { style: "auto" }), /* @__PURE__ */ React11.createElement( View8, { style: { flex: 1, height: "100%", width: "100%", backgroundColor: theme2?.background.primary, paddingHorizontal: 20 } }, renderHeader ? /* @__PURE__ */ React11.createElement(React11.Fragment, null, renderHeader({ isConnected: connectionStatus.isConnected, isConnecting: connectionStatus.connecting })) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement( View8, { style: { width: "100%", height: 40, flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }, /* @__PURE__ */ React11.createElement(View8, null, connectionStatus.connecting ? /* @__PURE__ */ React11.createElement( View8, { style: { flexDirection: "row", alignItems: "center" } }, /* @__PURE__ */ React11.createElement(ActivityIndicator, null), /* @__PURE__ */ React11.createElement( Text8, { style: { fontFamily, marginStart: 5, color: theme2?.text.secondary } }, "Connecting..." ) ) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, connectionStatus.isConnected ? /* @__PURE__ */ React11.createElement( View8, { style: { flexDirection: "row", alignItems: "center" } }, /* @__PURE__ */ React11.createElement( Text8, { style: { fontFamily, marginStart: 5, color: theme2?.text.secondary } }, "Active" ), /* @__PURE__ */ React11.createElement( View8, { style: { height: 5, width: 5, backgroundColor: "green", marginStart: 5 } } ) ) : /* @__PURE__ */ React11.createElement( View8, { style: { flexDirection: "row", alignItems: "center" } }, /* @__PURE__ */ React11.createElement( Text8, { style: { marginStart: 5, fontFamily, color: theme2?.text.secondary } }, "Offline" ), /* @__PURE__ */ React11.createElement( View8, { style: { height: 5, width: 5, backgroundColor: "lightgrey", marginStart: 5 } } ) ))), !connectionStatus.isConnected && /* @__PURE__ */ React11.createElement( TouchableOpacity5, { style: { padding: 5, paddingHorizontal: 10, display: connectionStatus.connecting ? "none" : "flex", backgroundColor: theme2?.action.primary, alignItems: "center", justifyContent: "center", borderRadius: 5 }, onPress: () => reconnect() }, /* @__PURE__ */ React11.createElement(Text8, { style: { color: "white", fontFamily } }, "Connect") ) )), /* @__PURE__ */ React11.createElement( FlatList3, { ref: flatListRef, data: filteredConversations, renderItem: renderConversations, showsVerticalScrollIndicator: false, ListHeaderComponent: /* @__PURE__ */ React11.createElement(View8, null, /* @__PURE__ */ React11.createElement( Text8, { style: { fontFamily, fontSize: 25, color: theme2?.text.secondary } }, "Chats" ), /* @__PURE__ */ React11.createElement( Search, { value: searchVal, setValue: setSearchVal, placeholder: "Search chats", containerStyle: { paddingHorizontal: 0 } } )), ListEmptyComponent: renderPlaceHolder ? /* @__PURE__ */ React11.createElement(React11.Fragment, null, renderPlaceHolder({ loading: connectionStatus.fetchingConversations })) : /* @__PURE__ */ React11.createElement(View8, { style: { alignItems: "center", marginTop: 50 } }, /* @__PURE__ */ React11.createElement(ChatIcon, { size: 100, color: theme2?.action.primary }), /* @__PURE__ */ React11.createElement( Text8, { style: { marginStart: 5, color: theme2?.text.disabled, marginTop: 20, fontFamily } }, "Your conversations will appear here" )) } ) ), /* @__PURE__ */ React11.createElement( TouchableOpacity5, { style: { display: users.length > 0 ? "flex" : "none", position: "absolute", bottom: 70, right: 20 }, onPress: () => displayModal({ children: /* @__PURE__ */ React11.createElement(UserList, { data: users, goToChat: () => { } }) }) }, /* @__PURE__ */ React11.createElement(ChatIconPlus, { size: 70, color: theme2?.action.primary }) ))); }); var Conversations_default = Conversations; export { Conversations_default as default }; //# sourceMappingURL=index.mjs.map