Skip to content

Instantly share code, notes, and snippets.

@iamkevingreen
Last active August 17, 2020 11:59
Show Gist options
  • Save iamkevingreen/0eedbacbf90fd7bfc049564f82ab9065 to your computer and use it in GitHub Desktop.
Save iamkevingreen/0eedbacbf90fd7bfc049564f82ab9065 to your computer and use it in GitHub Desktop.
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>
)
}
}
@mephraums
Copy link

Hi @iamkevingreen, did you happen to have the styles for this example that you could share?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment