Last active
August 17, 2020 11:59
-
-
Save iamkevingreen/0eedbacbf90fd7bfc049564f82ab9065 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import SendBird from 'sendbird' | |
const SiteStore = require('stores/SiteStore') | |
const Actions = require('actions/SiteActions') | |
export default class MemberMessaging extends Component { | |
constructor(props) { | |
super(props) | |
this.onChange = this.onChange.bind(this) | |
this.state = SiteStore.getState() | |
this.connect = this.connect.bind(this) | |
} | |
connect(userId, appId) { | |
const sb = new SendBird({appId: appId}) | |
let self = this | |
const user = Meteor.users.findOne() | |
let name = user.profile.name.first + ' ' + user.profile.name.last | |
sb.connect(userId.trim(), user.sendbird_token, (user, err) => { | |
if (err) { | |
console.error(err) | |
return | |
} | |
sb.updateCurrentUserInfo(name, '', (res, err) => { | |
if (err) { | |
console.error(err) | |
return | |
} | |
}) | |
Actions.updateSb(sb) | |
Actions.updateSbConnected(true) | |
}) | |
} | |
/* | |
Info | |
*/ | |
getNicknamesString(channel) { | |
let nicknameList = []; | |
let currentUserId = Meteor.userId(); | |
channel.members.forEach(function(member) { | |
if (member.userId != currentUserId) { | |
nicknameList.push(member.nickname); | |
} | |
}); | |
return nicknameList.toString(); | |
} | |
getMemberCount(channel) { | |
return (channel.memberCount > 9) ? MAX_COUNT : channel.memberCount.toString(); | |
} | |
getLastMessage(channel) { | |
if (channel.lastMessage) { | |
return channel.lastMessage.isUserMessage() ? channel.lastMessage.message : channel.lastMessage.name; | |
} | |
return ''; | |
} | |
getMessageTime(message) { | |
const months = [ | |
'JAN', 'FEB', 'MAR', 'APR', 'MAY', | |
'JUN', 'JUL', 'AUG', 'SEP', 'OCT', | |
'NOV', 'DEC' | |
]; | |
var _getDay = (val) => { | |
let day = parseInt(val); | |
if (day == 1) { | |
return day + 'st'; | |
} else if (day == 2) { | |
return day + 'en'; | |
} else if (day == 3) { | |
return day + 'rd'; | |
} else { | |
return day + 'th'; | |
} | |
}; | |
var _checkTime = (val) => { | |
return (+val < 10) ? '0' + val : val; | |
}; | |
if (message) { | |
const LAST_MESSAGE_YESTERDAY = 'YESTERDAY'; | |
var _nowDate = new Date(); | |
var _date = new Date(message.createdAt); | |
if (_nowDate.getDate() - _date.getDate() == 1) { | |
return LAST_MESSAGE_YESTERDAY; | |
} else if (_nowDate.getFullYear() == _date.getFullYear() | |
&& _nowDate.getMonth() == _date.getMonth() | |
&& _nowDate.getDate() == _date.getDate()) { | |
return _checkTime(_date.getHours()) + ':' + _checkTime(_date.getMinutes()); | |
} else { | |
return months[_date.getMonth()] + ' ' + _getDay(_date.getDate()); | |
} | |
} | |
return ''; | |
} | |
getMessageReadReceiptCount(channel, message) { | |
return channel.getReadReceipt(message); | |
} | |
getChannelUnreadCount(channel) { | |
return channel.unreadMessageCount; | |
} | |
componentWillUnmount() { | |
SiteStore.unlisten(this.onChange) | |
} | |
onChange(state) { | |
this.setState(state) | |
} | |
componentDidMount() { | |
SiteStore.listen(this.onChange) | |
const appId = Meteor.settings.public.sendbird.appId | |
const userId = Meteor.userId() | |
this.connect(userId, appId) | |
} | |
render() { | |
const { sbConnected, sb } = this.state | |
return ( | |
<div className="react-bird"> | |
{sbConnected ? | |
<div className="react-bird-container"> | |
<ChannelList | |
sb={sb} | |
getNicknamesString={this.getNicknamesString} | |
getLastMessage={this.getLastMessage} | |
getMemberCount={this.getMemberCount} | |
getMessageTime={this.getMessageTime} | |
getChannelUnreadCount={this.getChannelUnreadCount}/> | |
</div> | |
: <div className="react-bird-loading">Connecting</div> } | |
</div> | |
) | |
} | |
} | |
class ChannelList extends Component { | |
constructor(props) { | |
super(props) | |
this.onChange = this.onChange.bind(this) | |
this.renderChannels = this.renderChannels.bind(this) | |
this.createChat = this.createChat.bind(this) | |
this.state = SiteStore.getState() | |
} | |
componentDidMount() { | |
SiteStore.listen(this.onChange) | |
} | |
componentWillUnmount() { | |
SiteStore.unlisten(this.onChange) | |
} | |
onChange(state) { | |
this.setState(state) | |
} | |
componentWillMount() { | |
const { sb } = this.props | |
let channelListQuery = sb.GroupChannel.createMyGroupChannelListQuery() | |
channelListQuery.includeEmpty = true; | |
channelListQuery.limit = 20; | |
if (channelListQuery.hasNext && !channelListQuery.isLoading) { | |
channelListQuery.next((channelList, err) => { | |
if (err) { | |
console.error(err) | |
return | |
} | |
Actions.updateSbChannelListQuery(channelList) | |
}) | |
} | |
} | |
createChat(channel) { | |
let { sb, sbActiveChannels } = this.state | |
sb.GroupChannel.getChannel(channel.url, (channel, err) => { | |
if (err) { | |
console.log(err) | |
return | |
} | |
let activeChannels = sbActiveChannels | |
activeChannels.push(channel) | |
Actions.updateSbActiveChannels(activeChannels) | |
}) | |
} | |
renderChannels() { | |
let { sb } = this.state | |
let { getMessageTime, getNicknamesString, getChannelUnreadCount, getLastMessage } = this.props | |
return _.map(this.state.sbChannelListQuery, (channel, i) => { | |
const nickname = getNicknamesString(channel) | |
const unread = getChannelUnreadCount(channel) | |
const time = getMessageTime(channel.lastMessage) | |
const lastMessage = getLastMessage(channel) | |
return <ChannelListItem | |
key={i} | |
nickname={nickname} | |
createChat={this.createChat.bind(this, channel)} | |
time={time} | |
unread={unread} | |
lastMessage={lastMessage} /> | |
}) | |
} | |
renderChats() { | |
// Return the active chats | |
return _.map(this.state.sbActiveChannels, (channel, i) => { | |
return <ActiveMessaging | |
key={i} | |
sb={this.state.sb} | |
getMessageTime={this.props.getMessageTime} | |
channel={channel} | |
/> | |
}) | |
} | |
render() { | |
return ( | |
<div className="react-bird-channels"> | |
<div className="react-bird-channels-list"> | |
<div className="react-bird-channels-header f sb a-c"> | |
<div>Messages</div> | |
<div className={`react-bird-channels-toggle ${this.state.sbChatOpen}`}></div> | |
</div> | |
{this.renderChannels()} | |
</div> | |
<div className="react-bird-channels-active f sb jce"> | |
{this.renderChats()} | |
</div> | |
</div> | |
) | |
} | |
} | |
class ActiveMessaging extends Component { | |
constructor(props) { | |
super(props) | |
this.userPostMessage = this.userPostMessage.bind(this) | |
this.queryMessageList = this.queryMessageList.bind(this) | |
this.renderChannelMessages = this.renderChannelMessages.bind(this) | |
this.showTyping = this.showTyping.bind(this) | |
this.pushTyping = this.pushTyping.bind(this) | |
this.state = { | |
messages: [] | |
} | |
} | |
userPostMessage(e) { | |
e.preventDefault() | |
let message = this.refs.message.value | |
console.log(message) | |
} | |
showTyping() { | |
const { channel } = this.props | |
if (!channel.isTyping()) { | |
console.log('not typing') | |
} else new Promise(function(resolve, reject) { | |
console.log('typing') | |
}); | |
} | |
pushTyping() { | |
const { channel } = this.props | |
channel.startTyping() | |
} | |
queryMessageList() { | |
let self = this | |
let { channel } = this.props | |
let messagesListQuery = channel.createPreviousMessageListQuery() | |
messagesListQuery.load(50, true, (messageList, err) => { | |
if (err) { | |
console.error(err) | |
return | |
} | |
self.setState({ | |
messages: messageList | |
}) | |
console.log(messageList) | |
}) | |
} | |
componentDidMount() { | |
this.queryMessageList() | |
const { sb } = this.state | |
var ChannelHandler = new sb.ChannelHandler(); | |
ChannelHandler.onTypingStatusUpdated = function(channel){ | |
console.log(channel); | |
}; | |
sb.addChannelHandler('taco', ChannelHandler); | |
} | |
renderChannelMessages() { | |
console.log('bagel') | |
return _.map(this.state.messages, (message, i) => { | |
return ( | |
<div key={i}> | |
{this.props.getMessageTime(message)} | |
{message.message} | |
</div> | |
) | |
}) | |
} | |
render() { | |
const { channel } = this.props | |
return ( | |
<div className="react-bird-channels-chat"> | |
<div className="react-bird-channel-messages"> | |
{this.renderChannelMessages()} | |
{this.showTyping()} | |
</div> | |
<div className="react-bird-channels-msg-create"> | |
<form ref="msg_create" onSubmit={this.userPostMessage}> | |
<input ref="message" onChange={this.pushTyping} type="text" className="react-bird-channels-input" placeholder="message" onChange={this.userTyping} onSubmit={this.userPostMessage} /> | |
</form> | |
</div> | |
</div> | |
) | |
} | |
} | |
class ChannelListItem extends Component { | |
render() { | |
let { nickname, lastMessage, time, createChat } = this.props | |
return ( | |
<div className="react-bird-channels-item f sb a-c" onClick={createChat}> | |
<div className="react-bird-channels-item-message"> | |
<strong>{nickname}</strong><br /> | |
{lastMessage} | |
</div> | |
<div className="react-bird-channels-item-time"> | |
{time} | |
</div> | |
</div> | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @iamkevingreen, did you happen to have the styles for this example that you could share?