/**
* Desc: 聊天输入框
*
* Created by WangGanxin on 2018/1/29
* Email: mail@wangganxin.me
*/
import React, {Component,PureComponent} from 'react';
import {
StyleSheet,
Text,
View,
Image,
TextInput,
TouchableWithoutFeedback,
Platform,
KeyboardAvoidingView,
Keyboard,
Modal,
} from 'react-native';
import PropTypes from 'prop-types';
import EmotionsView from './EmotionsView';
import ModalBox from 'react-native-modalbox';
import Line from './Line';
import {EMOTIONS_ZHCN,invertKeyValues} from './DataSource';
let emojiReg = new RegExp('\\[[^\\]]+\\]','g'); //表情符号正则表达式
export default class ChatInputBar extends PureComponent {
constructor(props){
super(props);
this.state = {
isEmotionsVisible:false, //表情框是否可见
modalVisible:false,
inputValue:'',
cursorIndex:0,
autoFocus:true,
tempSendTxtArray:[],
};
}
openInputBar(){
if (Platform.OS === 'android'){
this.refs.modal.open();
}
else {
this.setState({
modalVisible:!this.state.modalVisible,
});
}
}
closeInputBar(){
if (Platform.OS === 'android'){
this.refs.modal.close();
}
else {
this.setState({
modalVisible:false,
});
}
}
_matchContentString(textContent){
// 匹配得到index并放入数组中
let currentTextLength = textContent.length;
let emojiIndex = textContent.search(emojiReg);
let checkIndexArray = [];
// 若匹配不到,则直接返回一个全文本
if (emojiIndex === -1) {
this.state.tempSendTxtArray.push(textContent.substring(0,currentTextLength));
} else {
if (emojiIndex !== -1) {
checkIndexArray.push(emojiIndex);
}
// 取index最小者
let minIndex = Math.min(...checkIndexArray);
// 将0-index部分返回文本
this.state.tempSendTxtArray.push(textContent.substring(0, minIndex));
// 将index部分作分别处理
this._matchEmojiString(textContent.substring(minIndex));
}
}
_matchEmojiString(emojiStr) {
let castStr = emojiStr.match(emojiReg);
let emojiLength = castStr[0].length;
let emotoins_code = invertKeyValues(EMOTIONS_ZHCN);
this.state.tempSendTxtArray.push(emotoins_code[castStr]);
this._matchContentString(emojiStr.substring(emojiLength));
}
_toogleShowEmojiView(){
if (!this.state.isEmotionsVisible){
Keyboard.dismiss();
}
this.setState({
isEmotionsVisible:!this.state.isEmotionsVisible,
});
}
_onModalBoxClosed(){
this.setState({
isEmotionsVisible:false,
});
}
_onEmojiSelected(code){
if (code === '' ){
return;
}
let lastText = '';
let currentTextLength = this.state.inputValue.length;
if (code === '/{del'){ //删除键
if (currentTextLength === 0){
return;
}
if (this.state.cursorIndex < currentTextLength){ //光标在字符串中间
let emojiReg = new RegExp('\\[[^\\]]+\\]'); //表情符号正则表达式
let emojiIndex = this.state.inputValue.search(emojiReg); //匹配到的第一个表情符位置
if (emojiIndex === -1){ //没有匹配到表情符
let preStr = this.state.inputValue.substring(0,this.state.cursorIndex);
let nextStr = this.state.inputValue.substring(this.state.cursorIndex);
lastText = preStr.substring(0,preStr.length - 1) + nextStr;
this.setState({
cursorIndex:preStr.length - 1,
});
}
else {
let preStr = this.state.inputValue.substring(0,this.state.cursorIndex);
let nextStr = this.state.inputValue.substring(this.state.cursorIndex);
let lastChar = preStr.charAt(preStr.length - 1);
if (lastChar === ']'){
let castArray = preStr.match(emojiReg);
if(!castArray){
let cast = castArray[castArray.length - 1];
lastText = preStr.substring(0,preStr.length - cast.length) + nextStr;
this.setState({
cursorIndex:preStr.length - cast.length,
});
}
else{
lastText = preStr.substring(0,preStr.length - 1) + nextStr;
this.setState({
cursorIndex:preStr.length - 1,
});
}
} else {
lastText = preStr.substring(0,preStr.length - 1) + nextStr;
this.setState({
cursorIndex:preStr.length - 1,
});
}
}
}
else { //光标在字符串最后
let lastChar = this.state.inputValue.charAt(currentTextLength - 1);
if (lastChar === ']'){
let castArray = this.state.inputValue.match(emojiReg);
if(castArray){
let cast = castArray[castArray.length - 1];
lastText = this.state.inputValue.substring(0,this.state.inputValue.length - cast.length);
this.setState({
cursorIndex:this.state.inputValue.length - cast.length,
});
}
else{
lastText = this.state.inputValue.substring(0,this.state.inputValue.length - 1);
this.setState({
cursorIndex:this.state.inputValue.length - 1,
});
}
}
else {
lastText = this.state.inputValue.substring(0,currentTextLength - 1);
this.setState({
cursorIndex:currentTextLength - 1,
});
}
}
}
else {
if (this.state.cursorIndex >= currentTextLength) {
lastText = this.state.inputValue + EMOTIONS_ZHCN[code];
this.setState({
cursorIndex:lastText.length
});
}
else {
let preTemp = this.state.inputValue.substring(0,this.state.cursorIndex);
let nextTemp = this.state.inputValue.substring(this.state.cursorIndex,currentTextLength);
lastText = preTemp + EMOTIONS_ZHCN[code] + nextTemp;
this.setState({
cursorIndex:this.state.cursorIndex + EMOTIONS_ZHCN[code].length
});
}
}
this.setState({
inputValue:lastText,
});
this._onInputChangeText(lastText);
}
_onSelectionChange(event){
this.setState({
cursorIndex:event.nativeEvent.selection.start,
});
}
_onInputChangeText(text){
//设值
this.setState({
inputValue:text,
});
//改变按钮颜色
if (text !== '' && text.length > 0){
this.refs.sendBtnWrapper.setNativeProps({
style:{
backgroundColor:'#56b2f0'
},
});
this.refs.sendBtnText.setNativeProps({
style:{
color:'#1d1d1d'
},
});
}
else {
this.refs.sendBtnWrapper.setNativeProps({
style:{
backgroundColor:'#f5f5f5'
}
});
this.refs.sendBtnText.setNativeProps({
style:{
color:'#bbbbbb',
}
});
}
}
_onFocus(){
this.setState({
isEmotionsVisible:false,
});
}
_onSendMsg(){
this.setState({
tempSendTxtArray:[],
});
let finalMsg = '';
if (this.state.inputValue !== '' && this.state.inputValue.length > 0) {
this._matchContentString(this.state.inputValue);
for (let i = 0; i < this.state.tempSendTxtArray.length; i++){
finalMsg += this.state.tempSendTxtArray[i];
}
this._onInputChangeText('');
this.props.onSend(finalMsg);
}
}
render() {
if (Platform.OS === 'android'){
return this._renderAndroidView();
}
return this._renderIosView();
}
_renderAndroidView(){
return this._onModalBoxClosed()}
style={[styles.container]} position={'bottom'} ref={'modal'}>
this.closeInputBar()}>
this._toogleShowEmojiView()}>
this._onSelectionChange(event)}
onChangeText={(text) => this._onInputChangeText(text)}
onFocus={() => this._onFocus()}
defaultValue={this.state.inputValue}/>
this._onSendMsg()}>
发送
{
this.state.isEmotionsVisible &&
this._onEmojiSelected(code)}/>
}
;
}
_renderIosView(){
return
this.closeInputBar()}>
this._toogleShowEmojiView()}>
this._onSelectionChange(event)}
onChangeText={(text) => this._onInputChangeText(text)}
onFocus={() => this._onFocus()}
defaultValue={this.state.inputValue}/>
this._onSendMsg()}>
发送
{
this.state.isEmotionsVisible &&
this._onEmojiSelected(code)}/>
}
;
}
}
Line.defaultProps = {
isVisible: false,
};
ChatInputBar.propTypes = {
onSend:PropTypes.func, //返回text文本
isVisible:PropTypes.bool,
};
const styles = StyleSheet.create({
container: {
width:'100%',
height:235,
backgroundColor:'transparent',
},
box_container: {
flex:1,
},
inputContainer: {
width:'100%',
position:'absolute',
bottom:0,
},
textContainer: {
width:'100%',
height:48,
flexDirection:'row',
backgroundColor:'white',
alignItems:'center',
},
outside: {
flex:1,
width:'100%',
},
emojiStyle:{
height:28,
width:28,
marginLeft:10,
},
inputStyle:{
flex:1,
paddingTop:8,
paddingBottom:8,
paddingLeft:10,
paddingRight:10,
height:32,
marginLeft:10,
marginRight:10,
backgroundColor:'#f5f5f5',
borderWidth:0,
borderRadius:20,
fontSize:15,
},
sendBtnTextStyle:{
fontSize:15,
color:'#bbbbbb'
},
sendBtnStyle:{
height:32,
width:62,
justifyContent:'center',
alignItems:'center',
marginRight:10,
borderRadius:15,
backgroundColor:'#f5f5f5'
},
});