Created
March 12, 2018 09:22
-
-
Save poberwong/061c5ddb39f8fea4838ed17dfa1e16ca 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
| /** | |
| * Created by dowin on 2017/8/3. | |
| */ | |
| import React from 'react' | |
| import PropTypes from 'prop-types' | |
| import { | |
| Clipboard, | |
| StyleSheet, | |
| Image, | |
| View, | |
| Dimensions, | |
| NativeAppEventEmitter, | |
| NativeModules, | |
| Animated | |
| } from 'react-native' | |
| import {inject, observer} from 'mobx-react' | |
| import LGNavigationBar from '../components/LGNavigationBar' | |
| // import Toast from 'react-native-simple-toast' | |
| import {NimFriend, NimSession} from 'react-native-netease-im' | |
| import ImagePicker from 'react-native-image-crop-picker' | |
| import {MessageList, ChatInput} from 'react-native-imui' | |
| const ContainerHeightMax = 800 | |
| // const ContainerHeightMin = 800 | |
| const ChatInputHeightMax = 300 | |
| const ChatInputHeightMin = 56 | |
| const ChatInputHeightBg = '#ffffff' | |
| const AuroraIMUIModule = NativeModules.AuroraIMUIModule | |
| const AnimatedImplementation = require('react-native/Libraries/Animated/src/AnimatedImplementation') | |
| const MessageListView = AnimatedImplementation.createAnimatedComponent(MessageList) | |
| const InputView = AnimatedImplementation.createAnimatedComponent(ChatInput) | |
| @inject('auth')@observer | |
| export default class Chat extends React.Component { | |
| static navigatorStyle = { | |
| tabBarHidden: true, | |
| navBarBackgroundColor: '#444', | |
| navBarButtonColor: '#fff', | |
| navBarTextColor: '#fff' | |
| } | |
| static propTypes = { | |
| navigation: PropTypes.object, | |
| auth: PropTypes.object | |
| } | |
| constructor (props) { | |
| super(props) | |
| this.state = { | |
| isInitialized: false, // initialization will calculate maxHeight before rendering the chat | |
| canLoadMoreContent: true, | |
| currentMetering: 0, | |
| messages: [], | |
| lastMessage: undefined, | |
| showMenuBar: false, | |
| menuBarOrigin: {}, | |
| menuItems: [], | |
| isPacketModalOpen: false, | |
| packetData: {}, | |
| sendUser: {}, | |
| selectMessage: {}, | |
| menuContainerHeight: ContainerHeightMax, | |
| chatInputStyle: { | |
| backgroundColor: ChatInputHeightBg, | |
| width: width | |
| }, | |
| chatInputheight: new Animated.Value(48), | |
| level: '', | |
| time: '', | |
| status: '', | |
| isDismissMenuContainer: false, | |
| initList: [] | |
| } | |
| this._loadMoreContentAsync = this._loadMoreContentAsync.bind(this) | |
| this.onSend = this.onSend.bind(this) | |
| // if (props.session && props.session.sessionType === '1') { | |
| // this.props.navigator.setButtons({ | |
| // rightButtons: [ | |
| // { | |
| // id: 'setting_team', | |
| // icon: require('../images/session_team.png') | |
| // } | |
| // ] | |
| // }) | |
| // } else { | |
| // this.props.navigator.setButtons({ | |
| // rightButtons: [ | |
| // { | |
| // id: 'setting_user', | |
| // icon: require('../images/session_user.png') | |
| // } | |
| // ] | |
| // }) | |
| // } | |
| // this.props.navigator.setOnNavigatorEvent(this._onNavigatorEvent.bind(this)) | |
| } | |
| // _onNavigatorEvent (event) { | |
| // const {session, navigator} = this.props | |
| // let self = this | |
| // if (event.type == 'NavBarButtonPress') { // this is the event type for button presses | |
| // if (event.id == 'setting_team') { // this is the same id field from the static navigatorButtons definition | |
| // navigator.push({ | |
| // screen: 'ImDemo.SessionTeamDetail', | |
| // title: '聊天信息', | |
| // backButtonTitle: '返回', | |
| // passProps: { | |
| // session: session, | |
| // onResult: function() { | |
| // AuroraIMUIModule.clearMessage() | |
| // } | |
| // } | |
| // }) | |
| // } | |
| // if (event.id === 'setting_user') { | |
| // navigator.push({ | |
| // screen: 'ImDemo.SessionUserDetail', | |
| // title: '聊天详情', | |
| // passProps: { | |
| // session: session, | |
| // onResult: function () { | |
| // AuroraIMUIModule.clearMessage() | |
| // } | |
| // } | |
| // }) | |
| // } | |
| // } | |
| // } | |
| componentDidMount () { | |
| const {auth: { nimInfo, doctorInfo }} = this.props | |
| NimSession.login(nimInfo.accid, nimInfo.token).then(res => { | |
| this.loadSession(doctorInfo.accid) | |
| }) | |
| } | |
| loadSession = (friendId) => { | |
| NimFriend.addFriendWithType(friendId, '1', '直接加好友') // 每次都默认强行加一次好友(其实可以先看看是不是好友) | |
| NimSession.startSession(friendId, '0') | |
| this.sessionListener = NativeAppEventEmitter.addListener('observeReceiveMessage', (data) => { | |
| console.info('新消息通知', data) | |
| if (data && data.length > 0) { | |
| AuroraIMUIModule.appendMessages(data) | |
| AuroraIMUIModule.scrollToBottom() | |
| } | |
| }) | |
| this.msgStatusListener = NativeAppEventEmitter.addListener('observeMsgStatus', (data) => { | |
| console.info('消息', data) | |
| if (data.length > 0) { | |
| if (data[0].status === 'send_sending') { | |
| AuroraIMUIModule.appendMessages(data) | |
| } else { | |
| for (var i in data) { | |
| AuroraIMUIModule.updateMessage(data[i]) | |
| } | |
| } | |
| AuroraIMUIModule.scrollToBottom() | |
| } | |
| }) | |
| this.deleteMessageListener = NativeAppEventEmitter.addListener('observeDeleteMessage', (data) => { | |
| if (data.length > 0) { | |
| for (var i in data) { | |
| AuroraIMUIModule.deleteMessage(data[i]) | |
| } | |
| } | |
| }) | |
| NimSession.queryMessageListEx('', 20).then((data) => { | |
| console.info('首次加载', data) | |
| if (data.length > 0) { | |
| this._lastMessage = data[0] | |
| this.setState({initList: data}) | |
| AuroraIMUIModule.scrollToBottom() | |
| } | |
| }, (err) => { | |
| console.log(err) | |
| }) | |
| } | |
| componentWillUnmount () { | |
| NimSession.stopSession() | |
| this.sessionListener && this.sessionListener.remove() | |
| this.msgStatusListener && this.msgStatusListener.remove() | |
| this.deleteMessageListener && this.deleteMessageListener.remove() | |
| } | |
| sendLocationImage (longitude, latitude, address) { | |
| NimSession.sendLocationMessage(longitude, latitude, address) | |
| } | |
| onSend (text, ids) { | |
| if (!text || !text.trim()) { | |
| console.log('请输入聊天内容') | |
| return | |
| } | |
| text = text.trim() | |
| NimSession.sendTextMessage(text, ids) | |
| this.forceUpdate() | |
| } | |
| handleImagePicker () { | |
| if (!this.state.action) { | |
| return | |
| } | |
| ImagePicker.openPicker({mediaType: 'photo', loadingLabelText: '请稍候...'}).then(image => { | |
| NimSession.sendImageMessages(image.path, 'myName') | |
| }) | |
| } | |
| handleCameraPicker () { | |
| if (!this.state.action) { | |
| return | |
| } | |
| ImagePicker.openCamera({mediaType: 'photo', loadingLabelText: '请稍候...'}).then(image => { | |
| NimSession.sendImageMessages(image.path, 'myName') | |
| }) | |
| } | |
| onLocation (coordinate) { | |
| this.sendLocationImage(coordinate.longitude, coordinate.latitude, coordinate.address) | |
| } | |
| handleLocationClick () { | |
| // if (!this.state.action) { | |
| // return | |
| // } | |
| // this.props.navigator.showModal({ | |
| // screen: 'ImDemo.LocationPicker', | |
| // title: '位置信息', | |
| // backButtonTitle: '返回', | |
| // passProps: { | |
| // onLocation: this.onLocation.bind(this) | |
| // } | |
| // }) | |
| } | |
| handleTransferClick () { | |
| // if (!this.state.action) { | |
| // return | |
| // } | |
| // const {navigator, session} = this.props | |
| console.log('向好友转账') | |
| } | |
| handlePacketClick () { | |
| if (!this.state.action) { | |
| return | |
| } | |
| console.log('发红包') | |
| } | |
| onOpenURL = (url) => { | |
| console.log('打开链接') | |
| } | |
| onMessagePress = (message) => { | |
| // const { navigator } = this.props | |
| // if (message.msgType === 'location') { | |
| // navigator.push({ | |
| // screen: 'ImDemo.LocationView', | |
| // title: '查看位置', | |
| // passProps: { | |
| // region: message.extend | |
| // } | |
| // }) | |
| // } | |
| if (message.msgType === 'redpacket' && message.extend) { | |
| console.log('红包详情') | |
| } | |
| if (message.msgType === 'transfer' && message.extend) { | |
| console.log('转账详情') | |
| } | |
| if (message.msgType === 'redpacketOpen' && message.extend) { | |
| this.onPacketPress(message) | |
| } | |
| } | |
| onTouchMsgList = () => { | |
| Animated.timing(this.state.chatInputheight, { | |
| toValue: 48, | |
| duration: 200 | |
| }).start() | |
| this.setState({ | |
| isDismissMenuContainer: true, | |
| chatInputStyle: { | |
| backgroundColor: ChatInputHeightBg, | |
| width: width | |
| } | |
| }) | |
| } | |
| onPacketPress (message) { | |
| console.log('红包详情') | |
| } | |
| onAvatarPress = (v) => { | |
| // if (v && v.fromUser) { | |
| // NimFriend.getUserInfo(v.fromUser._id).then((data) => { | |
| // this.props.navigator.push({ | |
| // screen: 'ImDemo.FriendDetail', | |
| // title: '详细资料', | |
| // backButtonTitle: '返回', | |
| // passProps: { | |
| // friendData: data | |
| // } | |
| // }) | |
| // }) | |
| // } | |
| } | |
| _loadMoreContentAsync = async () => { | |
| if (!this._lastMessage) { | |
| return | |
| } | |
| return NimSession.queryMessageListEx(this._lastMessage.msgId, 20) | |
| .then((data) => { | |
| if (data.length > 0) { | |
| this._lastMessage = data[0] | |
| AuroraIMUIModule.insertMessagesToTop(data) | |
| } | |
| }, () => { | |
| this.setState({canLoadMoreContent: false}) | |
| }) | |
| } | |
| onSendText = (text) => { | |
| this.onSend(text, []) | |
| } | |
| onSendRecordMessage = (path, duration) => { | |
| NimSession.sendAudioMessage(path, duration) | |
| } | |
| onFeatureView = (inputHeight, showType) => { | |
| console.log('showType: ', showType) | |
| if (showType > 0) { | |
| Animated.timing(this.state.chatInputheight, { | |
| toValue: 323, | |
| duration: 200 | |
| }).start() | |
| } else { | |
| Animated.timing(this.state.chatInputheight, { | |
| toValue: 48, | |
| duration: 260 | |
| }).start() | |
| } | |
| this.setState({ | |
| action: showType === 2, | |
| isDismissMenuContainer: false, | |
| chatInputStyle: { | |
| backgroundColor: ChatInputHeightBg, | |
| width: width | |
| // height: showType === 0 ? ChatInputHeightMin : ChatInputHeightMax | |
| }, | |
| menuContainerHeight: ContainerHeightMax // showType === 0 ? ContainerHeightMin : ContainerHeightMax + showType, | |
| }) | |
| setTimeout(() => { | |
| AuroraIMUIModule.scrollToBottom() | |
| }, 500) | |
| } | |
| onShowKeyboard = (inputHeight, showType) => { | |
| console.info('onShowKeyboard', inputHeight, showType) | |
| setTimeout(() => { | |
| AuroraIMUIModule.scrollToBottom() | |
| }, 200) | |
| } | |
| onEditTextChange = (text) => { | |
| console.log('用于做@提醒:', text) | |
| } | |
| onStatusViewClick = (message, opt) => { | |
| console.info('onStatusViewClick', message + '--' + opt) | |
| if (opt === 'copy') { | |
| Clipboard.setString(message.text) | |
| } else if (opt === 'delete') { | |
| NimSession.deleteMessage(message.msgId) | |
| AuroraIMUIModule.deleteMessage([message]) | |
| } else if (opt === 'revoke') { | |
| NimSession.revokeMessage(message.msgId).then((data) => { | |
| AuroraIMUIModule.deleteMessage([message]) | |
| }) | |
| } | |
| } | |
| renderChatInput () { | |
| return ( | |
| <InputView style={[this.state.chatInputStyle, {height: this.state.chatInputheight}]} | |
| menuContainerHeight={this.state.menuContainerHeight} | |
| isDismissMenuContainer={this.state.isDismissMenuContainer} | |
| onSendText={this.onSendText} | |
| onSendVoice={this.onSendRecordMessage} | |
| onShowKeyboard={this.onShowKeyboard} | |
| onFeatureView={this.onFeatureView} | |
| onEditTextChange={this.onEditTextChange}> | |
| <View style={styles.search}> | |
| {/* {this.renderActionBar()} */} | |
| </View> | |
| </InputView> | |
| ) | |
| } | |
| renderMessages () { | |
| return ( | |
| <MessageListView style={{flex: 1}} | |
| onMsgClick={this.onMessagePress} | |
| onLinkClick={this.onOpenURL} | |
| onAvatarClick={this.onAvatarPress} | |
| onStatusViewClick={this.onStatusViewClick} | |
| onTouchMsgList={this.onTouchMsgList} | |
| onClickChangeAutoScroll={this.onClickChangeAutoScroll} | |
| onPullToRefresh={this._loadMoreContentAsync} | |
| sendBubble={{imageName: 'send_msg', padding: 10}} | |
| receiveBubbleTextColor={'#ffffff'} | |
| sendBubbleTextSize={14} | |
| receiveBubbleTextSize={14} | |
| sendBubblePressedColor={'#dddddd'} | |
| eventMsgTxtColor={'#ffffff'} | |
| eventMsgTxtSize={12} | |
| initList={this.state.initList} /> | |
| ) | |
| } | |
| goBack = () => this.props.navigation.goBack() | |
| render () { | |
| return ( | |
| <View style={{ flex: 1, backgroundColor: '#f7f7f7' }}> | |
| {this.renderMessages()} | |
| {this.renderChatInput()} | |
| </View> | |
| ) | |
| } | |
| } | |
| const {width} = Dimensions.get('window') | |
| const sWidth = width - 55 * 4 | |
| const styles = StyleSheet.create({ | |
| container: { | |
| flex: 1, | |
| justifyContent: 'center', | |
| alignItems: 'center', | |
| backgroundColor: '#F5FCFF' | |
| }, | |
| messageList: { | |
| // backgroundColor: 'red', | |
| flex: 1, | |
| marginTop: 0, | |
| width: window.width, | |
| margin: 0 | |
| }, | |
| inputView: { | |
| backgroundColor: 'green', | |
| width: window.width, | |
| height: 100 | |
| }, | |
| btnStyle: { | |
| marginTop: 10, | |
| borderWidth: 1, | |
| borderColor: '#3e83d7', | |
| borderRadius: 8, | |
| backgroundColor: '#3e83d7' | |
| }, | |
| iconRow: { | |
| flexDirection: 'row', | |
| paddingHorizontal: sWidth / 5 - 1, | |
| flexWrap: 'wrap', | |
| paddingVertical: 30, | |
| flex: 1 | |
| }, | |
| actionCol: { | |
| alignItems: 'center', | |
| marginRight: sWidth / 5, | |
| height: 95 | |
| }, | |
| iconTouch: { | |
| justifyContent: 'center', | |
| alignItems: 'center' | |
| }, | |
| search: { | |
| flex: 1, | |
| flexDirection: 'column', | |
| backgroundColor: '#fff' | |
| } | |
| }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment