UNPKG

sfm-uikit-react-native

Version:

It is a react native component for SmartFloMeet users.

254 lines (241 loc) 8.9 kB
import React, { PureComponent,createRef } from "react"; import { View, Text, FlatList, TextInput, TouchableOpacity, Dimensions, Keyboard, KeyboardAvoidingView, Platform, TouchableWithoutFeedback, Image} from "react-native"; import { format } from 'date-fns'; import { LinkPreview } from '@flyerhq/react-native-link-preview' import { styles } from "../style/EnxChatScreenStyle"; import { EnxSetting } from ".."; class EnxChatScreen extends PureComponent { constructor(props) { super(props); this.state={ selfClientId: this.props.selfClientId,//this.props.selfClientId, participantClientId:this.props.participantClientId, chatType:this.props.chatType, newMessage: '', keyboardOffset: 0, screenWidth: Dimensions.get('window').width, // Current screen width screenHeight: Dimensions.get('window').height, shouldScrollToBottom: true, // Flag to indicate if we should scroll } this.flatListRef = createRef(); //this.isKeyboardVisible = false; // Track if the keyboard is visible } componentDidMount() { // Add keyboard listeners to adjust the view when the keyboard is opened or closed this.keyboardDidShowListener = Keyboard.addListener("keyboardDidShow", this._keyboardDidShow); this.keyboardDidHideListener = Keyboard.addListener("keyboardDidHide", this._keyboardDidHide); // Listen to orientation changes this.dimensionsListener = Dimensions.addEventListener("change", this.handleOrientationChange); //Add listener for notification EnxSetting.addEventListener('ChatPageBack', this.handleBackEvent); } componentWillUnmount() { // Remove listeners when the component is unmounted this.keyboardDidShowListener.remove(); this.keyboardDidHideListener.remove(); this.dimensionsListener.remove(); EnxSetting.removeEventListener('ChatPageBack', this.handleBackEvent); } //Handle notification lisner from EnxSetting class handleBackEvent = (data) => { this.props.onBack(); }; // Handle orientation change handleOrientationChange = ({ window: { width, height } }) => { this.setState({ screenWidth: width, screenHeight: height, }); }; // Scroll to the bottom of the list when the keyboard is opened _keyboardDidShow = (event) => { const keyboardHeight = event.endCoordinates.height; this.setState({ keyboardOffset: keyboardHeight }, () => { // Only scroll if shouldScrollToBottom is true if (this.state.shouldScrollToBottom) { this.scrollToBottom(); } }); }; // Reset the offset when the keyboard is closed // _keyboardDidHide = () => { // this.setState({ keyboardOffset: 0 }, () => { // this.isKeyboardVisible = false; // Reset keyboard visible flag // }); // }; _keyboardDidHide = () => { this.setState({ keyboardOffset: 0 }); }; // Scroll the FlatList to the most recent message (bottom) scrollToBottom = () => { if (this.flatListRef.current) { this.flatListRef.current.scrollToEnd({ animated: true }); } }; shareFile = () => { var option = { type: this.state.chatType, clientId: this.state.participantClientId, } this.props.shareFile(option) } //Send message sendMessage = () => { if(this.state.newMessage != "") { var option = { msg:this.state.newMessage, type:this.state.chatType, clientId: this.state.participantClientId, } this.props.sendMessageInGroup(option) this.setState({ newMessage:'' },()=>{ this.scrollToBottom(); // Scroll to bottom if keyboard is visible }) } } onScrollBeginDrag = () => { // User has started scrolling manually, so disable auto-scroll console.log('keybard getting drag'); this.setState({ shouldScrollToBottom: false }); }; onScrollEndDrag = () => { console.log('keybard drag end'); // User has finished scrolling this.setState({ shouldScrollToBottom: true }); }; render() { const { screenWidth, screenHeight, newMessage, keyboardOffset } = this.state; return ( <KeyboardAvoidingView style={[styles.container, { width: screenWidth, height: screenHeight }]} behavior={Platform.OS === 'ios' ? 'padding' : 'height'} > <TouchableWithoutFeedback onPress={Keyboard.dismiss}> <View style={[styles.container, { width: screenWidth }]}> <View style={{ flex: 1 }}> {this.props.data.length > 0 ? ( <FlatList ref={this.flatListRef} data={this.props.data} renderItem={this.renderItem} keyExtractor={(item) => item.id} onTouchStart={this.onScrollBeginDrag} onTouchEnd={this.onScrollEndDrag} contentContainerStyle={{ paddingBottom: this.state.keyboardOffset }} showsVerticalScrollIndicator={false} />) : ( <View style={styles.placeholder}> <Text>No messages available.</Text> </View> )} </View> <View style={styles.inputContainer}> <TextInput style={styles.input} placeholder="Type your message..." value={newMessage} onChangeText={(text) => this.setState({ newMessage: text })} onFocus={this.scrollToBottom} // Optional: Scroll when input is focused /> <TouchableOpacity style={{padding:5}} onPress={this.shareFile}> <Image source={require("../image_asset/file_chooser.png")} style={{width: 27,height: 27,alignSelf: 'center'}} /> </TouchableOpacity> <TouchableOpacity style={styles.sendButton} onPress={this.sendMessage}> <Image source={require("../image_asset/send.png")} style={styles.itemImage} /> </TouchableOpacity> </View> </View> </TouchableWithoutFeedback> </KeyboardAvoidingView> ); } renderItem = ({ item,index }) => { console.log("Item43",item); // Function to render text with link preview const renderTextWithLinkPreview = (text) => { const urlRegex = /(https?:\/\/[^\s]+)/g; const parts = text.split(urlRegex); return parts.map((part, i) => { if (part.match(urlRegex)) { return ( <LinkPreview key={i} text={part} renderText={(previewText) => <Text style={styles.linkText} key={i}>{previewText}</Text>} containerStyle={styles.linkPreviewContainer} textContainerStyle={styles.linkPreviewTextContainer} /> ); } return <Text style={styles.normalText} key={i}>{part}</Text>; }); }; const isSender = item.isReceived; const firstLetter = item.sender.charAt(0).toUpperCase(); return ( <View style={[ styles.messageContainer, isSender ? styles.senderContainer : styles.receiverContainer, ]} > {/* First Row: First letter, Name, Date */} <View style={[ styles.firstRow, isSender ? styles.senderFirstRow : styles.receiverFirstRow, ]} > <View style={[ styles.firstLetterContainer, isSender ? styles.senderFirstLetter : styles.receiverFirstLetter, ]} > <Text style={styles.firstLetterText}>{firstLetter}</Text> </View> {isSender ? <View style={styles.nameDateContainer}> <Text style={styles.dateText}>{format(new Date(item.timestamp), 'hh:mm:ss a')}</Text> <Text style={styles.nameText}>{item.senderName}</Text> </View> : <View style={styles.nameDateContainer}> <Text style={styles.nameText}>{item.senderName}</Text> <Text style={styles.dateText}>{format(new Date(item.timestamp), 'hh:mm:ss a')}</Text> </View> } </View> {/* Second Row: Message */} <View style={[styles.secondRow, isSender ? styles.senderSecondRow : null]}> <View style={[ styles.messageBubble, isSender ? styles.senderBubble : styles.receiverBubble, ]} > <Text style={styles.messageText}>{renderTextWithLinkPreview(item.message)}</Text> {item.jsondata!=null && item.jsondata!=''? <TouchableOpacity onPress={() => { this.props.downloadFile(index)}} > <Text style={{color: 'blue'}}>[Download]</Text> </TouchableOpacity> :null } </View> </View> </View> ); }; } export default EnxChatScreen;