I am using syncmanager for handling messages. The issue is MessageCollection only works on refreshing. I am not getting the updated states when I send or receive a message but I get the message handler when I send a message and refresh the page.
onSucceededMessageEvent
works on refreshing the page but doesn’t works after sending the message.
I am following the sample code from github for react native and web-basic-sample-syncmanager.
Does anyone have an idea about what I am missing here.
following is the code for the reference:
import React, { useState, useEffect } from 'react';
import { useStoreState, useStoreActions } from 'easy-peasy';
import Loader from 'components/Loader';
import SendBird from 'sendbird';
import SendBirdSyncManager from 'sendbird-syncmanager';
import MessageList from '../MessageList/MessageList';
import {
Button,
TextField
} from 'widget';
const ChatMessages = props => {
// local states
const [loading, setLoading] = useState(true);
const [typedText, setTypedText] = useState('');
const [channelUrl, setChannelUrl] = useState('');
const [channel, setChannel] = useState('');
const [currentMessages, setCurrentMessages] = useState([]);
// store states
const {
latestChannel, messages,
} = useStoreState(state => state.chatMessages);
const { addMessages, updateMessages, removeMessages, clearMessages } = useStoreActions(actions => actions.chatMessages);
// global variables
let collection = null;
const sb = SendBird.getInstance();
const _messageEventHandler = (messages, action, reason) => {
console.log('inside msg event handler');
switch (action) {
case 'insert': {
addMessages(messages);
break;
}
case 'update': {
if (reason === SendBirdSyncManager.MessageCollection.FailedMessageEventActionReason.UPDATE_RESEND_FAILED) {
updateMessages(messages, true);
} else {
updateMessages(messages);
}
break;
}
case 'remove': {
removeMessages(messages);
break;
}
case 'clear': {
clearMessages();
break;
}
}
}
// send message handler
const sendMessage = () => {
if (typedText) {
const pendingMessage = channel.sendUserMessage(typedText, (message, err) => {
// To preserve order of pending messages being processed before same failed ones.
setTimeout(() => {
if (collection) {
collection.handleSendMessageResponse(err, message);
}
}, 100);
});
if (collection) {
collection.appendMessage(pendingMessage);
setTypedText('');
}
}
}
// latest channel url got changed so change channel
useEffect(() => {
if (!latestChannel)
return;
const latestchannelUrl = latestChannel ? latestChannel : '';
setChannelUrl(latestchannelUrl);
sb.getChannel(latestchannelUrl, false).then(channel => {
setChannel(channel)
});
}, [latestChannel])
//channel got changed
useEffect(() => {
if (!channel)
return;
// message collection handler
if (collection) {
collection = null;
}
collection = new SendBirdSyncManager.MessageCollection(channel);
collection.limit = 50;
const collectionHandler = new SendBirdSyncManager.MessageCollection.CollectionHandler();
collectionHandler.onSucceededMessageEvent = (messages, action, reason) => {
_messageEventHandler(messages, action, reason);
};
collectionHandler.onFailedMessageEvent = (messages, action, reason) => {
_messageEventHandler(messages, action, reason);
};
collectionHandler.onPendingMessageEvent = (messages, action, reason) => {
_messageEventHandler(messages, action, reason);
};
collection.setCollectionHandler(collectionHandler);
collection.fetchSucceededMessages('prev', err => {
collection.fetchSucceededMessages('next', err => {
collection.fetchFailedMessages(err => { });
});
});
}, [channel])
useEffect(() => {
messages ? setLoading(false) : setLoading(true);
}, []);
useEffect(() => {
messages ? setCurrentMessages(messages) : setCurrentMessages([]);
}, [messages])
return (
<>
{
!loading ? (
<div>
<div>
msg will be disaplayed here
<MessageList messages={messages} />
</div>
<div>
type text msg here
<TextField
type="text"
name="msg"
value={typedText}
onChange={e => setTypedText(e.target.value)}
label="type your text message here"
/>
<Button
variant="contained"
color="primary"
onClick={() => {
sendMessage();
setTypedText('');
}}>
Send
</Button>
</div>
</div>
) : <Loader />
}
</>
);
};