该套代码为从项目案例中提取的,可以直接拿去使用,主要包含了单聊及消息的处理。主要分三个页面处理完成,入口首页(index)、消息列表页(message)、会话页面(chat)index.html 页面(app入口页面)
var rong;apiready=function(){ rong = api.require('rongCloud2'); //判断用户登录成功后执行方法 rongCloud();}function rongCloud(){ //初始化 init(); //消息的监听,监听到新消息后将消息广播出去,在会话页面监听接收并判断 setOnReceiveMessageListener(); //连接融云服务器 connect(); //监听获取某一会话最新消息记录 api.addEventListener({ name: 'getLatestMessages' }, function(ret){ if(ret && ret.value){ var value = ret.value; getLatestMessages(value.targetId,value.type); } }); //监听获取某一会话历史消息记录 api.addEventListener({ name: 'getHistoryMessages' }, function(ret){ if(ret && ret.value){ var value = ret.value; getHistoryMessages(value.targetId,value.type,value.oldestMessageId); } }); //监听发送新消息,监听完成后将消息再次广播出去,列表级会话页面监听接收 api.addEventListener({ name:'sendMessage' },function(ret){ if(ret && ret.value){ var data = ret.value; //目标id,消息内容,消息类型 sendMessage(data.targetId,data.conversationType,data.objectName,data.message); } })}//初始化融云 function init(){ rong.init(function(ret, err){ }); }/***全局消息监听*整个app项目中,所有的消息监听事件都在此方法中完成,如果正在会话,监听到消息后通过api.sendEvent方法广播出去*/function setOnReceiveMessageListener(){ rong.setOnReceiveMessageListener(function (ret, err) { if(ret){ //将监听到的消息广播出去,在会话页面接收 api.sendEvent({ name: 'setOnReceiveMessageListener', extra: {result:ret.result} }); switch(ret.result.message.objectName){ //文字消息 case 'RC:TxtMsg': var notificationMessage = ret.result.message.content.text; break; //图片消息 case 'RC:ImgMsg': var notificationMessage = '[图片]'; break; //语音消息 case 'RC:VcMsg': var notificationMessage = '[语音]'; break; } } })}/***连接融云服务器*连接成功后使用getConversationList获取会话列表*/function connect(){ //根据本地用户id,从服务器端获取用户融云的token var token = $api.getStorage('rongCloudToken'); rong.connect({ token: ''+token+'' },function(ret, err){ if (ret.status == 'success'){ //连接成功后获取会话列表 getConversationList(); } });}//获取会话列表function getConversationList(){ rong.getConversationList(function (ret, err) { if(ret.status=='success'){ //广播会话列表事件 api.sendEvent({ name: 'getConversationList', extra: {result:ret.result,status:ret.status} }); } })}//获取某一会话的最新消息记录function getLatestMessages(targetId,type){ rong.getLatestMessages({ conversationType: ''+type+'', targetId: ''+targetId+'', count: 20 }, function (ret, err) { if(ret.status=='success'){ //将获得的历史消息广播出去,在会话页面接收 api.sendEvent({ name: 'backLatestMessages', extra: {result:ret.result,status:ret.status} }); } })}//获取某一会话历史消息记录function getHistoryMessages(targetId,type,oldestMessageId){ rong.getHistoryMessages({ conversationType: ''+type+'', targetId: ''+targetId+'', oldestMessageId: ''+oldestMessageId+'', count: 20 }, function (ret, err) { if(ret.status=='success'){ //将获得的历史消息广播出去,在会话页面接收 api.sendEvent({ name: 'backHistoryMessages', extra: {result:ret.result,status:ret.status} }); } })}//发送消息function sendMessage(targetId,conversationType,objectName,message){ switch(objectName){ //文字消息 case 'RC:TxtMsg': rong.sendTextMessage({ conversationType: ''+conversationType+'', targetId: ''+targetId+'', text: ''+message+'', extra: '' }, function (ret, err) { if (ret.status == 'prepare'){ //发送准备,广播出去,在会话页面监听接收 api.sendEvent({ name: 'backSendMessage', extra: {result:ret.result} }); insertMessage(targetId,conversationType,objectName,ret.result); }else if (ret.status == 'success'){ //发送成功的处理 }else if (ret.status == 'error'){ //发送失败的处理 //api.toast({ msg: err.code }); } }) break; //图片消息 case 'RC:ImgMsg': rong.sendImageMessage({ conversationType: ''+conversationType+'', targetId: ''+targetId+'', imagePath: ''+message+'', extra: '' }, function (ret, err) { if (ret.status == 'prepare'){ //发送准备,广播出去,在会话页面监听接收 api.sendEvent({ name: 'backSendMessage', extra: {result:ret.result} }); insertMessage(targetId,conversationType,objectName,ret.result); }else if (ret.status == 'progress'){ //广播图片的进度 }else if (ret.status == 'success'){ api.sendEvent({ name: 'backSendMessageSuccess', extra: {messageId:ret.result.message.messageId} }); }else if (ret.status == 'error'){ api.toast({ msg: err.code }); } }); break; //语音消息 case 'RC:VcMsg': rong.sendVoiceMessage({ conversationType: ''+conversationType+'', targetId: ''+targetId+'', voicePath: ''+message.path+'', duration: ''+message.duration+'', extra: '' }, function (ret, err) { if (ret.status == 'prepare'){ //发送准备,广播出去,在会话页面监听接收 api.sendEvent({ name: 'backSendMessage', extra: {result:ret.result} }); insertMessage(targetId,conversationType,objectName,ret.result); }else if (ret.status == 'success'){ api.toast({ msg: ret.result.message.messageId }); } else if (ret.status == 'error'){ api.toast({ msg: err.code }); } } ); break; } }
消息列表页核心代码
HTMLJS核心代码apiready=function(){ //请求获取会话列表 api.sendEvent({ name: 'requestConversationList' }); //监听新消息 api.addEventListener({ name: 'setOnReceiveMessageListener' }, function(ret, err){ if(ret && ret.value){ var result = ret.value.result; if($api.byId("target-"+result.message.targetId)){ //如果存在更新消息内容 //此处也定义个id,更消息内容类型做个判断 switch(result.message.objectName){ //文字消息 case 'RC:TxtMsg': $api.text($api.byId("targetMessage-"+result.message.targetId),result.message.content.text); break; //图片消息 case 'RC:ImgMsg': $api.text($api.byId("targetMessage-"+result.message.targetId),"[图片]"); break; //语音消息 case 'RC:VcMsg': $api.text($api.byId("targetMessage-"+result.message.targetId),"[语音]"); break; } //将当前消息容器移动到顶部 if(result.message.conversationType!='CUSTOMER_SERVICE' && $api.dom("#messageList > li")){ $api.byId("messageList").insertBefore($api.byId("target-"+result.message.targetId),$api.byId("messageList").childNodes[0]); } }else{ //如果不存在写入 var html=''; if(result.message.conversationType=='CUSTOMER_SERVICE'){ }else if(result.message.conversationType=='PRIVATE'){ html += '
' html += ' '; //此处也定义个id,更消息内容类型做个判断 switch(result.message.objectName){ //文字消息 case 'RC:TxtMsg': html += '
'; html += ''+result.message.content.text+'
'; break; //图片消息 case 'RC:ImgMsg': html += '[图片]
'; break; //语音消息 case 'RC:VcMsg': html += '[语音]
'; break; } html += ' ' html += ' ...'; //此处也定义个id,更消息内容类型做个判断 switch(messageList[i].objectName){ //文字消息 case 'RC:TxtMsg': html += '
'; html += ''+messageList[i].latestMessage.text+'
'; break; //图片消息 case 'RC:ImgMsg': html += '[图片]
'; break; //语音消息 case 'RC:VcMsg': html += '[语音]
'; break; } html += ' ' html += ' '; //此处也定义个id,更消息内容类型做个判断 switch(result.message.objectName){ //文字消息 case 'RC:TxtMsg': html += '
'; html += ''+result.message.content.text+'
'; break; //图片消息 case 'RC:ImgMsg': html += '我:[图片]
'; break; //语音消息 case 'RC:VcMsg': html += '我:[语音]
'; break; } html += '会话(单聊)页面核心代码:
结合UIChatBox模块
var myAvatar, targetId,targetAvatar,targetNickname,oldestMessageId='-1', chatBox, sourcePath = "widget://image/emotion",//表情存放目录 emotionData;//存储表情apiready = function(){ //从本地数据存贮获取我的头像 myAvatar = $api.getStorage('avatar'); targetId = api.pageParam.targetId;//传递过来的目标用户id targetAvatar = api.pageParam.targetAvatar;//传递过来的目标用户头像 targetNickname = api.pageParam.targetNickname;//传递过来的目标用户昵称 api.parseTapmode();//优化点击事件(300) //表情图片处理 getImgsPaths(sourcePath, function (emotion) { emotionData = emotion; }); //获取最新消息记录 getLatestMessages(); //监听来自消息列表的新消息 api.addEventListener({ name: 'setOnReceiveMessageListener' }, function(ret){ if(ret && ret.value){ var result = ret.value.result; //如果当前消息的目标id等于当前会话目标id,写入 if(result.message.targetId==targetId){ var html = ''; html += ''; html += ''; $api.append($api.byId("messageList"),html); api.parseTapmode(); //容器自动滚动至底部的处理,加个100毫秒演示防止不成功 setTimeout(function(){ window.scrollTo(0,$api.offset($api.byId("messageList")).h); },100) } } }) //监听发送的新消息 api.addEventListener({ name: 'backSendMessage' }, function(ret){ if(ret && ret.value){ var result = ret.value.result; //如果当前消息的目标id等于当前会话目标id,写入 if(result.message.targetId==targetId){ var html = ''; html += ''; html += ''; html += ' '; switch(result.message.objectName){ //文字消息 case 'RC:TxtMsg': html += ' '+transText(result.message.content.text)+''; break; //图片消息 case 'RC:ImgMsg': html += ' '; break; //语音消息 case 'RC:VcMsg': html += ''; html += ''+result.message.content.duration+'s'; html += ' '; break; } html += ''; html += ''; $api.append($api.byId("messageList"),html); api.parseTapmode(); window.scrollTo(0,$api.offset($api.byId("messageList")).h); } } }) //监听发送的新消息是否完成 api.addEventListener({ name: 'backSendMessageSuccess' }, function(ret){ if(ret && ret.value){ if($api.byId("messageStatus-"+ret.value.messageId)){ $api.remove($api.byId("messageStatus-"+ret.value.messageId)); } } }) //下拉加载历史消息 api.setRefreshHeaderInfo({ visible: true, loadingImg: 'widget://image/ptr_pull.png', bgColor: '#ffffff', textColor: '#ff7372', textDown: '下拉加载', textLoading: '加载中', textUp: '松开加载', showTime: false }, function(ret, err){ api.refreshHeaderLoading(); //发送一个获取历史消息的事件 api.sendEvent({ name: 'getHistoryMessages', extra: {targetId:targetId,type:'PRIVATE',oldestMessageId:oldestMessageId} }); api.refreshHeaderLoadDone(); //从服务器加载数据,完成后调用api.refreshHeaderLoadDone()方法恢复组件到默认状态 }); //监听获取历史消息 api.addEventListener({ name: 'backHistoryMessages' }, function(ret){ if(ret && ret.value.result){ var result = ret.value.result; var myUserid = $api.getStorage('userid'); //重新排序 var messageList = result.sort(getSortFun('asc', 'sentTime')); oldestMessageId = messageList[0].messageId; var html = ''; for(var i in messageList){ if(messageList[i].senderUserId==myUserid){ //当前发送用户 html += ''; html += ''; html += ' '; switch(result.message.objectName){ //文字消息 case 'RC:TxtMsg': html += ' '+transText(result.message.content.text)+''; break; //图片消息 case 'RC:ImgMsg': html += ''; html += ''; html += ' '; break; //语音消息 case 'RC:VcMsg': //alert(JSON.stringify(ret.value.message.content)); html += ''+result.message.content.duration+'s'; html += ' '; break; } html += ''; html += ''; html += ''; html += ' '; }else{ html += ''; html += ''; } $api.prepend($api.byId("messageList"),html); api.parseTapmode(); } }); //chatbox部分 chatBox = api.require('UIChatBox'); openChatBox(); //监听键盘聊天框键盘弹出,用于调整聊天窗口高度 chatBox.addEventListener({ target: 'inputBar', name: 'move' }, function(ret,err){ if(ret.panelHeight>0){ api.setFrameAttr({ name: 'chat_private_frm', rect:{ h:api.frameHeight-ret.panelHeight } }); }else{ api.setFrameAttr({ name: 'chat_private_frm', rect:{ h:api.frameHeight } }); } setTimeout(function(){ window.scrollTo(0,$api.offset($api.byId("messageList")).h); },200) }); //监听按下录音 chatBox.addEventListener({ target: 'recordBtn', name: 'press' }, function(ret,err){ api.startRecord({ //path: 'fs://1.amr' }); }); //监听松开录音键 chatBox.addEventListener({ target: 'recordBtn', name: 'press_cancel' }, function(ret,err){ //松开后停止录音 api.stopRecord( function(ret,err){ if (ret && ret.duration > 0) { api.sendEvent({ name:'sendMessage', extra: { targetId:targetId, objectName:'RC:VcMsg', conversationType:'PRIVATE', message:ret } }) } } ); });}//获取最新消息记录function getLatestMessages(){ //通过sendEvent方法从message_list中获取当前会话历史消息,发送目标id,消息类型,最后一条id api.sendEvent({ name: 'getLatestMessages', extra: {targetId:targetId,type:'PRIVATE'} }); //监听获取历史消息 api.addEventListener({ name: 'backLatestMessages' }, function(ret){ //alert(JSON.stringify(ret.value)); if(ret && ret.value.result){ var result = ret.value.result; var myUserid = $api.getStorage('userid'); //重新排序 var messageList = result.sort(getSortFun('asc', 'sentTime')); oldestMessageId = messageList[0].messageId; var html = ''; for(var i in messageList){ if(messageList[i].senderUserId==myUserid){ //当前发送用户 html += ''; html += ''; html += ' '; } switch(messageList[i].objectName){ //文字消息 case 'RC:TxtMsg': html += ' '+transText(messageList[i].content.text)+''; break; //图片消息 case 'RC:ImgMsg': html += ' '; break; //语音消息 case 'RC:VcMsg': //html += ' [语音消息]'; html += ''; html += ''+messageList[i].content.duration+'s'; html += ' '; break; } html += ''; html += ''; html += ''; html += ' '; }else{ html += ''; html += ''; } $api.prepend($api.byId("messageList"),html); api.parseTapmode(); setTimeout(function(){ window.scrollTo(0,$api.offset($api.byId("messageList")).h); },300) } });}//排序函数function getSortFun(order, sortBy) { var ordAlpah = (order == 'asc') ? '>' : '<'; var sortFun = new Function('a', 'b', 'return a.' + sortBy + ordAlpah + 'b.' + sortBy + '?1:-1'); return sortFun;}//表情处理function transText(text, imgWidth, imgHeight){ var imgWidth = imgWidth || 24; var imgHeight = imgHeight || 24; var regx= /\[(.*?)\]/gm; var textTransed = text.replace(regx,function(match){ var imgSrc = emotionData[match]; if( !imgSrc){ /* 说明不对应任何表情,直接返回即可.*/ return match; } var img = " "; return img; }); return textTransed; }/*获取所有表情图片的名称和真实URL地址,以JSON对象形式返回。其中以表情文本为 属性名,以图片真实路径为属性值*/function getImgsPaths(sourcePathOfChatBox, callback){ var jsonPath = sourcePathOfChatBox + "/emotion.json";//表情的JSON数组 api.readFile({ path: jsonPath },function(ret,err){ if(ret.status){ var emotionArray = JSON.parse(ret.data); var emotion = {}; for(var i in emotionArray){ var emotionItem = emotionArray[i]; var emotionText = emotionItem["text"]; var emotionUrl = "../image/emotion/"+emotionItem["name"]+".png"; emotion[emotionText] = emotionUrl; } /*把emotion对象 回调出去*/ if("function" === typeof(callback)){ callback(emotion); } } });}function openChatBox(){ chatBox.open({ placeholder: '', maxRows: 4, emotionPath: 'widget://image/emotion', texts: { recordBtn: { normalTitle: '按住 说话', activeTitle: '松开 结束' } }, styles: { inputBar: { borderColor: '#d9d9d9', bgColor: '#f2f2f2' }, inputBox: { borderColor: '#B3B3B3', bgColor: '#FFFFFF' }, emotionBtn: { normalImg: 'widget://image/chatBox/face1.png' }, extrasBtn: { normalImg: 'widget://image/chatBox/add1.png' }, keyboardBtn: { normalImg: 'widget://image/chatBox/key1.png' }, speechBtn: { normalImg: 'widget://image/chatBox/key3.png' }, recordBtn: { normalBg: '#c4c4c4', activeBg: '#999999', color: '#000', size: 14 }, indicator: { target: 'both', color: '#c4c4c4', activeColor: '#9e9e9e' } }, extras: { titleSize: 10, titleColor: '#a3a3a3', btns: [{ title: '图片', normalImg: 'widget://image/chatBox/album1.png', activeImg: 'widget://image/chatBox/album2.png' },{ title: '拍照', normalImg: 'widget://image/chatBox/cam1.png', activeImg: 'widget://image/chatBox/cam2.png' }] } }, function(ret){ //点击附加功能面板 if(ret.eventType == 'clickExtras'){ //alert("用户点击了第"+ ret.index +"个按钮"); if(ret.index==0){ //图片 api.getPicture({ sourceType: 'library', encodingType: 'jpg', mediaValue: 'pic', destinationType: 'url', allowEdit: true, quality: 70, targetWidth:320, saveToPhotoAlbum: false }, function(ret, err){ if (ret) { api.sendEvent({ name:'sendMessage', extra: { targetId:targetId, objectName:'RC:ImgMsg', conversationType:'PRIVATE', message:ret.data } }) } }); }else if(ret.index==1){ //图片 api.getPicture({ sourceType: 'camera', encodingType: 'jpg', mediaValue: 'pic', destinationType: 'url', allowEdit: true, quality: 70, targetWidth:640, saveToPhotoAlbum: false }, function(ret, err){ if (ret) { api.sendEvent({ name:'sendMessage', extra: { targetId:targetId, objectName:'RC:ImgMsg', conversationType:'PRIVATE', message:ret.data } }) } }); } } //点击发送按钮 if(ret.eventType == 'send' && ret.msg){ //通过sendEvent将发送内容广博,消息页面接收并广播回来 //单聊文字消息类型 api.sendEvent({ name:'sendMessage', extra: { targetId:targetId, objectName:'RC:TxtMsg', conversationType:'PRIVATE', message:ret.msg } }) //alert('输入的内容是:'+ transText(ret.msg)); } });}'; html += ''; html += ' '; } switch(messageList[i].objectName){ //文字消息 case 'RC:TxtMsg': html += ' '+transText(messageList[i].content.text)+''; break; //图片消息 case 'RC:ImgMsg': html += ' '; break; //语音消息 case 'RC:VcMsg': //html += ' [语音消息]'; html += ''; html += ''+messageList[i].content.duration+'s'; html += ' '; break; } html += '