UNPKG

meses-messaging

Version:

Meses messaging SDK in JavaScript

242 lines (210 loc) 8.51 kB
import React from 'react' import styles from './styles.css' import MessagingButton from './components/MessagingButton' import MessagingPopup from './components/MessagingPopup' import MesesMessagingApp from '../app' class MesesMessagingUI extends React.Component { constructor() { super() this.CLASS_TAG = '[MESES_MESSAGING_UI]' } componentWillMount() { this.setState({ buttonVisible: false, popupVisible: false, messageListVisible: false, conversationList: [], messageList: [], messageBuffer: [], hasMoreMessage: true, totalUnreadCount: 0, lastConversationScrollTop: 0 }) let { targetUri, applicationId, username } = this.props this._app = new MesesMessagingApp(targetUri, applicationId) this._handleConnect(username) } handleMessagingButtonOnClick() { let { popupVisible, conversationList } = this.state this.setState({ popupVisible: !popupVisible }) } handleConversationEntryOnClick(conversationName, scrollTop) { this._handlePrepareConversation(conversationName, scrollTop) } handleBackButtonOnClick() { this.setState({ messageList: [], messageBuffer: [], messageListVisible: false }) this._app.detachUpdateHandler(this.activeConversation.conversationName) this.activeConversation = null; } handleSendButtonOnClick(message) { message = message.trim() if (message.length > 0) this._handleSendMessageAction(message) } render() { let { buttonIcon, buttonClass, popupClass } = this.props let { buttonVisible, popupVisible, messageListVisible } = this.state let { hasMoreMessage, hasMoreConversation, lastConversationScrollTop } = this.state let { conversationList, messageList, messageBuffer } = this.state let { activeTitle, connectedUser, totalUnreadCount } = this.state let messagingPopup = popupVisible ? <MessagingPopup className={ popupClass } conversationList={ conversationList } messageList={ messageList } messageBuffer={ messageBuffer } messageListVisible={ messageListVisible } hasMoreConversation={ hasMoreConversation } hasMoreMessage={ hasMoreMessage } title={ activeTitle } connectedUser={ connectedUser } lastConversationScrollTop={ lastConversationScrollTop } conversationEntryOnClick={ this.handleConversationEntryOnClick.bind(this) } backButtonOnClick={ this.handleBackButtonOnClick.bind(this) } sendButtonOnClick={ this.handleSendButtonOnClick.bind(this) } loadMoreConversation={ this._handleLoadConversation.bind(this) } loadMoreMessage={ this._handleLoadMessage.bind(this) } /> : '' let messagingButton = buttonVisible ? <MessagingButton className={ buttonClass } buttonIcon={ buttonIcon } totalUnreadCount={ !popupVisible ? totalUnreadCount : 0 } onClick= { this.handleMessagingButtonOnClick.bind(this) } /> : '' return ( <div className={ styles.base }> { messagingPopup } { messagingButton } </div> ) } _handleConnect(username) { this._app.connect(username) .then(function(result) { this.prevConvListQuery = this._app.createPreviousConversationListQuery() this.setState({ connectedUser: result, buttonVisible: true }) this.activeConversation = null this._handleLoadConversation() this._handleConversationUpdate() }.bind(this)) .catch(err => console.error(this.CLASS_TAG, err)) } _handleLoadConversation() { let { fetchConversationSize } = this.props let { conversationList, totalUnreadCount } = this.state this.prevConvListQuery.load(fetchConversationSize ? fetchConversationSize : 10) .then(function(result) { let tmpCount = result.map(x => x.unreadCount).reduce((sum, value) => sum + value) this.setState({ conversationList: conversationList.concat(result), totalUnreadCount: totalUnreadCount + tmpCount, hasMoreConversation: this.prevConvListQuery.hasMore() }) }.bind(this)) .catch(err => console.error(this.CLASS_TAG, err)) } _handleLoadMessage() { let { fetchMessageSize } = this.props let { messageList } = this.state this.prevMsgListQuery.load(fetchMessageSize ? fetchMessageSize : 20) .then(function(result) { result.reverse() this.setState({ messageList: result.concat(messageList), messageListVisible: true, hasMoreMessage: this.prevMsgListQuery.hasMore() }) }.bind(this)) .catch(err => console.error(this.CLASS_TAG, err)) } _handlePrepareConversation(conversationName, scrollTop) { this._app.getConversation(conversationName) .then(function(conversation) { this.activeConversation = conversation this.prevMsgListQuery = conversation.createPreviousMessageListQuery() this.setState({ messageListVisible: true, activeTitle: conversation.title ? conversation.title : conversation.conversationName, lastConversationScrollTop: scrollTop }) this._handleMessageUpdate() this._handleMarkAsRead(conversationName) this._handleLoadMessage() }.bind(this)) .catch(err => console.error(this.CLASS_TAG, err)) } _handleMarkAsRead(conversationName) { let { conversationList, totalUnreadCount } = this.state let conversation = conversationList.find(c => c.conversationName === conversationName) const count = conversation.unreadCount; conversation.unreadCount = 0; this.setState({ conversationList: conversationList, totalUnreadCount: totalUnreadCount - count }) this.activeConversation.markAsRead() } _handleSendMessageAction(message) { let { connectedUser, messageBuffer } = this.state this.activeConversation.sendMessage(message, { displayName: connectedUser.displayName }) .then(function(message) { messageBuffer.push(message) this.setState({ messageBuffer: messageBuffer }) this.activeConversation.markAsRead() }.bind(this)) .catch(err => console.error(this.CLASS_TAG, err)) } _handleConversationUpdate() { let { refreshRate } = this.props if (refreshRate) { let handler = this._app.createConversationUpdateHandler( 'conv-update-handler', this._conversationUpdateCallback.bind(this), refreshRate ) this._app.attachUpdateHandler(handler) } } _handleMessageUpdate() { let { refreshRate } = this.props if (refreshRate) { let handler = this.activeConversation.createNewMessageUpdateHandler( this.activeConversation.conversationName, this._newMessageUpdateCallback.bind(this), refreshRate ) this._app.attachUpdateHandler(handler) } } _conversationUpdateCallback(err, result) { let { conversationList, totalUnreadCount } = this.state let tmpUnreadCount = 0 if (err) console.error(this.CLASS_TAG, err) else if (result.updatedConversationPayloads.length > 0) { result.updatedConversationPayloads.map(x => { let found = conversationList.find(c => c.conversationName === x.conversationName) if (found) { tmpUnreadCount -= found.unreadCount found.lastMessageText = x.lastMessageText found.lastMessageTime = x.lastMessageTime if (this.activeConversation == null || this.activeConversation.conversationName != x.conversationName) found.unreadCount = x.unreadCount } else { conversationList.push(x) } tmpUnreadCount += x.unreadCount }) conversationList.sort((a, b) => b.lastMessageTime - a.lastMessageTime) this.setState({ conversationList: conversationList, totalUnreadCount: totalUnreadCount + tmpUnreadCount }) } } _newMessageUpdateCallback(err, result) { let { messageList, messageBuffer } = this.state if (err) console.error(this.CLASS_TAG, err) else if (result.messages.length > 0) { result.messages.reverse() result.messages.map(x => { let idx = messageBuffer.findIndex(message => message.messageId === x.messageId) if (idx != -1) messageBuffer.splice(idx, 1) messageList.push(x) }) this.setState({ messageList: messageList, messageBuffer: messageBuffer }) } } } export default MesesMessagingUI