meses-messaging
Version:
Meses messaging SDK in JavaScript
242 lines (210 loc) • 8.51 kB
JSX
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