Last active
June 18, 2019 22:31
-
-
Save dereknelson/2226951d7badf38c259a817b1d984950 to your computer and use it in GitHub Desktop.
sendbird mounting
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
var sb = null; | |
export default class Chat extends Component { | |
constructor(props) { | |
super(props); | |
sb = SendBird.getInstance(); | |
this.state = { | |
channel: props.channel, channelUrl: props.channelUrl, name: props.name, messageQuery: '', channel: '', name: '', messages: props.channel.messageList || [], | |
}; | |
} | |
componentDidMount() { | |
AppState.addEventListener('change', this.handleAppStateChange); | |
this.getChannel(); | |
if (this.state.messages == null && this.textInput) this.textInput.focus() | |
else if (this.state.messages.length < 5 && this.textInput) this.textInput.focus() | |
} | |
getChannel = () => { | |
if (sb == null) return setTimeout(() => { | |
this.getChannel() | |
}, 1000) | |
const channel = sb.GroupChannel.getChannel(this.state.channelUrl, (channel, error) => { | |
if (error) { | |
setTimeout(() => { | |
return this.getChannel() | |
}, 1000) | |
} else { | |
this.handleMounting(channel, error) | |
} | |
}) | |
} | |
handleMounting = (channel, error) => { | |
channel.markAsRead(); | |
var messageQuery = channel.createPreviousMessageListQuery() | |
messageQuery.load(20, true, (messageList, error) => { | |
channel.messageList = messageList | |
this.setState({ messages: messageList, channel, error, messageQuery, fetchedOld: true, loading: false, fetched: true, }) | |
}) | |
if (!this.state.hasRendered) { | |
this.setState({ hasRendered: true }) | |
this._getChannelMessage(false) | |
if (this.state.channel.channelType == 'group') { | |
this.state.channel.markAsRead(); | |
} | |
} | |
// channel handler | |
var ChannelHandler = new sb.ChannelHandler(); | |
ChannelHandler.onMessageReceived = (channel, message) => { | |
if (channel.url == this.state.channel.url) { | |
var messages = [message]; | |
this.setState({ | |
messages: messages.concat(this.state.messages) | |
}); | |
this.state.lastMessage = message; | |
if (this.state.channel.channelType == 'group') { | |
this.state.channel.markAsRead(); | |
} | |
} | |
} | |
sb.addChannelHandler('ChatView', ChannelHandler); | |
var ConnectionHandler = new sb.ConnectionHandler(); | |
ConnectionHandler.onReconnectSucceeded = function () { | |
this._getChannelMessage(true); | |
this.state.channel.refresh(); | |
} | |
} | |
render() { | |
return ( | |
<KeyboardAvoidingView style={styles.container} behavior="padding" > | |
<View style={[styles.chatContainer, { transform: [{ scaleY: -1 }] }]}> | |
<FlatList | |
enableEmptySections={true} | |
onEndReached={() => this._getChannelMessage(false)} | |
onEndReachedThreshold={.5} | |
ListFooterComponent={() => | |
this.state.messageQuery.isLoading ? | |
<ActivityIndicator size="large" animating={true} style={{ transform: [{ scaleY: -1 }] }} /> | |
: null | |
} | |
refreshing={this.state.messageQuery.isLoading} | |
data={this.state.messages} | |
removeClippedSubviews={true} | |
initialNumToRender={15} | |
ListEmptyComponent={this.loading} | |
keyExtractor={(item, index) => item.messageId} | |
renderItem={this.renderItem} | |
/> | |
</View> | |
<View style={styles.inputContainer} > | |
<this.image /> | |
<View style={{ flexDirection: 'row', }} > | |
<TouchableOpacity style={styles.photoButton} hitSlop={{ top: 5, bottom: 5, left: 10, right: 5 }} onPress={this._onPhoto}> | |
<Text style={{ fontSize: 20 }} > + </Text> | |
</TouchableOpacity> | |
<TextInput | |
style={styles.textInput} | |
placeholder={'Message'} | |
ref={ref => this.textInput = ref} | |
multiline={true} | |
onChangeText={this._onChangeText} | |
value={this.state.text} | |
blurOnSubmit={false} | |
/> | |
<TouchableOpacity style={styles.sendButton} onPress={this._onSend} disabled={this.state.disabled}> | |
<Text>Send</Text> | |
</TouchableOpacity> | |
</View> | |
</View> | |
</KeyboardAvoidingView> | |
) | |
} | |
renderItem = ({ item, index }) => { | |
/* * * * * | |
* * | |
* NOTE * | |
* * | |
/* * * * * | |
The entire flatlist has an inverse y-axis, effectively inverting the flatlist without also inverting refresh control, so some of the above/below comparisons have seemingly reversed logic */ | |
const { messages } = this.state | |
if (messages[index] == null) { | |
return | |
} | |
let aboveIndex = index + 1 | |
let belowIndex = index - 1 | |
if (belowIndex == -1) belowIndex = index | |
if (aboveIndex >= this.state.messages.length) aboveIndex = index | |
if (messages[index]._sender == null) messages[index]._sender = { userId: '' } | |
if (messages[aboveIndex]._sender == null) messages[aboveIndex]._sender = { userId: '' } | |
if (messages[belowIndex]._sender == null) messages[belowIndex]._sender = { userId: '' } | |
const isYou = item._sender.userId == this.props.user.info.id | |
let changesSidesAbove = messages[aboveIndex]._sender.userId != messages[index]._sender.userId | |
let changesSidesBelow = messages[belowIndex]._sender.userId != messages[index]._sender.userId | |
let thisTime = moment(messages[index].createdAt) | |
let aboveTime = moment(messages[aboveIndex].createdAt) | |
let aboveDifference = thisTime.diff(aboveTime, 'h') | |
let belowTime = moment(messages[belowIndex].createdAt) | |
let belowDifference = belowTime.diff(thisTime, 'h') | |
const difference = { aboveDifference, belowDifference, thisTime, } | |
let changed = false | |
if (aboveDifference > 1) { | |
changesSidesAbove = true | |
changed = true | |
} | |
const borderRadius = item.messageType == 'file' ? 15 : 25 | |
let borderRadii = { borderBottomLeftRadius: isYou ? borderRadius : 0, borderTopLeftRadius: isYou ? borderRadius : changesSidesAbove ? borderRadius - 5 : 0, borderBottomRightRadius: isYou ? 0 : borderRadius, borderTopRightRadius: isYou ? changesSidesAbove ? borderRadius - 5 : 0 : borderRadius } | |
if (changed) changesSidesAbove = false | |
let displayTime = (changesSidesBelow && aboveDifference < 1) || (index == 0 && aboveDifference < 1) || belowDifference > 1 | |
let displayImage = false | |
if (changesSidesBelow) displayImage = true | |
else if (aboveDifference > 1 && (changesSidesBelow || belowDifference > 1)) displayImage = true | |
else if (belowDifference > 1) displayImage = true | |
else if (index == 0) displayImage = true | |
return ( | |
<Message item={item} index={index} isYou={isYou} changesSidesAbove={changesSidesAbove} difference={difference} users={this.state.users} changesSidesBelow={changesSidesBelow} borderRadii={borderRadii} | |
displayTime={displayTime} displayImage={displayImage} navigation={this.props.navigation} | |
imageModalVisible={this.state.imageModalVisible} showImage={this.showImage} dismissImage={this.dismissImage} /> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment