请尊重作者的辛勤劳动!!!
使用apicloud开发已经快2个月了,起初的目的就是为了实现安卓和苹果的兼容,属于一个试验项目,究竟apicloud是否能够满足公司的要求?最 终看来还是不错的,使用apicloud+融云实现了类似微信即时通讯的功能。看到有很多后来的人依然在这块挣扎,我就把自己的实现思路和成果分享出来和 大家一起交流一下,我也是第一次做手机开发,有很多经验不足的地方,希望大家能够直接指出来,我也不断完善自己的产品。
这次没有使用本地数据库,所有数据都是从融云和服务器获取,会影响性能,下一步会把数据本地化处理,再将优化后的代码和大家交流。 具体实现的思路,说的可能会有些混乱,希望大家能谅解~ 一、功能说明: 1. 登录功能:类似微信,登录后记住当前人账号和密码,记在了Storage里,可能会有安全性问题,想在第二版优化时保存在数据库中; 2. 通讯录功能:类似微信,包括群组及好友列表 3. 历史会话列表:类似微信,包括群组及个人的历史会话列表 4. 发送内容:包括文本、语音和图片 二、使用的模块 包括:fs、imageBrowser、bubbleMenu、listContact、UIMediaScanner、rongCloud、UIChatBox 三、实现思路: PS:这里借鉴了 “流浪男” 的一篇文章,感谢他的对我实现思路的重大启发,原文:http://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=8715 使用论坛中的aui.css样式 感谢技术客服 技术支持-M 的辛勤帮助 感谢 吴勇 兄弟的帮助 1. 登录操作,登录时访问服务器(自己的云服务器)获取token,服务器使用的是java的sdk获取token,组装token和人员的所有信息json返回到app,保存在storage里,后期会存到本地数据库中; 2. 主界面,包括4个菜单,分别为会话历史页面、通讯录页面、应用页面和个人设置页面,所有的和融云相关的业务逻辑都在hh_index_window里面初始化,其他页面获取数据时,都是采取监听模式获取数据; 3. 会话历史页面:hh_index_window.html<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport --> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 --> <meta name="format-detection" content="telephone=no"/> <title>会话列表</title> <link rel="stylesheet" type="text/css" href="../../css/aui.css" /> <style> .span_name { width: 20%; /*font-size: 18px;*/ /*text-align: center;*/ display: inline-block; /*word-break: keep-all;*/ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } </style> </head> <body> <!--<div class="aui-content"><input type="button" value="为了测试,点击这里清空会话" οnclick="clearConversations();"/>--> <ul class="aui-user-view"> <!--<li class="aui-user-view-cell aui-img" οnclick="openNewsList();"> <img class="aui-img-object aui-pull-left" src="../../image/person/demo1.png"> <div class="aui-img-body"> <span>系统消息1<em>10:22</em></span> <p class='aui-ellipsis-1'> 理想家校通上线啦~~~ </p> </div>--> <!--<div id="notify" style="height:0px;"> <div class="circle"> <p id="messages" class="circle_p"></p> </div> </div>--> <!--</li>--> <!--会话列表--> <div id="hhlist_div"></div> <script type="text/html" id="hhlist_script"> <% if(result.length == 0){ %> <div style="text-align:center;color:#666;"><span>您还没有会话记录,快去找小伙伴们聊天 吧~~</span></div> <% }else{ %> <%for(var i=0; i<result.length; i++) {%> <li id="<%=result[i].targetId %>" alt="<%=result[i].conversationType %>" class="aui-user-view-cell aui-img" οnclick="openHhList('<%=result[i].targetId %>','<%=result[i].latestMessageId %>','<%=result[i].person_name %>','<%=result[i].conversationType %>','hh_index');"> <img class="aui-img-object aui-pull-left" src="<%=result[i].avatar_url %>"> <div class="aui-img-body"> <span><span class="span_name"><%=result[i].person_name %></span><em><%=g_time.getTime(result[i].receivedTime,1) %></em></span> <% if(result[i].objectName == 'RC:VcMsg') { %> <p class='aui-ellipsis-1'>[语音]</p> <% } %> <% if(result[i].objectName == 'RC:TxtMsg') { %> <p class='aui-ellipsis-1'><%=result[i].latestMessage.text %></p> <% } %> <% if(result[i].objectName == 'RC:ImgMsg') { %> <p class='aui-ellipsis-1'>[图片]</p> <% } %> </div> <% if(result[i].unreadMessageCount > 0) { %> <div style="height:0px;"> <div class="circle"> <p class="circle_p"><%=result[i].unreadMessageCount %></p> <input type="hidden" class="unread_count" value="<%=result[i].unreadMessageCount %>"/> </div> </div> <% } %> </li> <%}%> <% } %> </script> </ul> <!--</div>--> <script type="text/javascript" src="../../script/api.js"></script> <script type="text/javascript" src="../../script/template.js"></script> <script type="text/javascript" src="../../script/date.js"></script> <!-- 长按控件 周枫 2015.08.05 --> <script type="text/javascript" src="../../script/hammer.min.js"></script> <script type="text/javascript" src="../../script/base_config.js"></script> <script type="text/javascript" src="../../script/huihua/hh_index_window.js"></script> </body> </html>
/* * 把所有的融云类的处理全部放在消息列表页,然后通过APICloud的api.sendEvent和api.addEventListener 来处理融云的一些事件。 记住除了消息列表页其他页面不要做融云的任何链接处理 */ //定义融云 var rong; //内容高度 var rect_h; //header高度 var header_h; apiready = function() { api.showProgress({ title : '加载中...', modal : false }); rect_h = api.pageParam.rect_h; header_h = api.pageParam.header_h; //加载融云模块 rong = api.require('rongCloud'); //融云初始化 rongCloud(); //监听来自会话页面发送消息的事件 api.addEventListener({ name : 'sendMessage' }, function(ret) { if (ret && ret.value) { var value = ret.value; switch(value.type) { case 'text': sendMessage('' + value.type + '', '' + value.targetId + '', '' + value.content + '', '' + value.extra + '', '' + value.conversationType + ''); break; case 'pic': //判断是照相还是选择,选择是数组,照相是一个 switch(value.pic_source) { case 'camera': sendPicture('' + value.targetId + '', '' + value.imgSrc + '', '' + value.extra + '', '' + value.conversationType + ''); break; case 'album': // alert(JSON.stringify(value)); var img_list = value.img_list; for (var i = 0; i < img_list.length; i++) { // alert(value.img_list.image_list[i].path+'123123'); //图片真实地址 var img_temp = img_list[i].path; var img_url; //文件后缀名,如:png,jpg, mp4 var suffix = img_list[i].suffix; var obj_scan = api.require('UIMediaScanner'); if (api.systemType == 'ios') { //虚拟路径转真实路径 obj_scan.transPath({ path : img_temp }, function(ret) { //发送图片格式 if (suffix == 'png' || suffix == 'jpg') { sendPicture('' + value.targetId + '', '' + ret.path + '', '' + value.extra + '', '' + value.conversationType + ''); } }); } else if (api.systemType = "android") { // api.alert({ // msg:img_temp // },function(ret,err){ // //coding... // }); //发送图片格式 if (suffix == 'png' || suffix == 'jpg') { sendPicture('' + value.targetId + '', '' + img_temp + '', '' + value.extra + '', '' + value.conversationType + ''); } } } break; } break; case 'voi': sendVoice('' + value.targetId + '', '' + value.voicePath + '', '' + value.duration + '', '' + value.extra + '', '' + value.conversationType + ''); break; } } }); //监听来自会话页面获取历史会话的事件 api.addEventListener({ name : 'getHistory' }, function(ret) { if (ret && ret.value) { var value = ret.value; getHistoryMessagesById(value.type, value.target_id, value.old_msg_id, value.msg_count); } }); //监听来自通讯录页面获取最新会话id的事件 api.addEventListener({ name : 'getOldMessageId' }, function(ret) { if (ret && ret.value) { var value = ret.value; getLatestMessagesById(value.conver_type, value.target_id, value.count, function(mes_list) { var old_msg_id = -1; if (getJsonObjLength(mes_list) != 0) { old_msg_id = mes_list[0].messageId; } //发送target_id获取最新会话id api.sendEvent({ name : 'setOldMessageId', extra : { old_msg_id : old_msg_id } }); }); } }); //监听来注销页面的事件 api.addEventListener({ name : 'logout' }, function(ret) { rong.disconnect(false); }); //系统消息未读使用 // var messages = Math.floor((Math.random()*10)+1); // document.getElementById("messages").innerHTML = messages; } /* * 打开会话页面 * 周枫 * 2015-08-03 */ function openHhList(target_id, old_msg_id, person_name, conver_type, h_from) { //清除未读信息 cleanMsg(target_id, conver_type); getCoversationList(); //如果是群组,则获取群组人员姓名json if (conver_type == "GROUP") { getGroupInfoById(target_id); } api.openWin({ name : 'hh_chat_window', url : 'hh_chat_window.html', bounces : true, animation : 'push', delay : 1, scrollToTop : true, pageParam : { 'targetId' : target_id, 'old_msg_id' : old_msg_id + 1, 'conver_type' : conver_type, 'person_name' : person_name, 'header_h' : header_h, 'conver_type' : conver_type, 'h_from' : h_from }, rect : { x : 0, y : 'auto', w : 'auto', h : 'auto' } }); $api.addEvt($api.byId('back'), 'click', function() { api.closeWin(); }); // }); } /** * 打开消息列表页面 * 周枫 * 2015.08.17 */ function openNewsList() { api.openWin({ name : 'xx_index_window', url : 'xx_index_window.html', bounces : true, animation : 'push', delay : 1, scrollToTop : true, pageParam : { 'header_h' : header_h }, rect : { x : 0, y : 'auto', w : 'auto', h : 'auto' } }); } /* * 融云初始化 * 周枫 * 2015-08-03 */ function rongCloud() { var token = $api.getStorage('mytoken'); //融云初始化 rong.init(function(ret, err) { if (ret.status == "success") { api.execScript({ name : 'index', script : 'setTitle("会话");' }); } else { api.execScript({ name : 'index', // frameName : 'hh_index', script : 'setTitle("连接失败");' }); } }); //监听新消息 receiveMessageListener(); //连接 rong.connect({ token : '' + token + '' }, function(ret, err) { if (ret.status == 'success') { //清空所有会话 // clearConversations(); //消息列表 getCoversationList(); //初始化当前人员群组信息 // initPersonGroup(); // quitGroup(); } else { var err_code = err.code; switch(err_code) { case "-1": api.toast({ msg : "对不起,客户端发生未知错误!", location : 'middle' }); break; case "2002": api.toast({ msg : "对不起,客户端数据包不完整,请求数据包有缺失!", location : 'middle' }); break; case "2003": api.toast({ msg : "对不起,服务器不可用!", location : 'middle' }); break; case "2004": api.toast({ msg : "对不起,请重新向身份认证服务器获取 Token!", location : 'middle' }); break; case "2005": api.toast({ msg : "对不起,可能是错误的 App Key,或者 App Key 被服务器积极拒绝!", location : 'middle' }); break; case "2006": api.toast({ msg : "对不起,服务端数据库错误!", location : 'middle' }); break; case "5004": api.toast({ msg : "对不起,服务器超时!", location : 'middle' }); break; case "-10000": api.toast({ msg : "对不起,未调用 init 方法进行初始化!", location : 'middle' }); break; case "-10002": api.toast({ msg : "对不起,输入参数错误!", location : 'middle' }); break; } } }); } /* * 监听新消息 当有新消息传来时,利用sendEvent发出一个事件,同时传递消息内容,可以在会话页面进行一次监听接收 * 周枫 * 2015-08-03 */ function receiveMessageListener() { rong.setOnReceiveMessageListener(function(ret, err) { // api.alert({ // msg:JSON.stringify(ret) // },function(ret,err){ // //coding... // }); if (ret.status == "success") { //发送事件 api.sendEvent({ name : 'getNewMessage', extra : { data : ret.result.message } }) // cleanMsg(ret.result.message.targetId,ret.result.message.conversationType); getCoversationList(); } }) } /* * 获取会话消息列表 * 周枫 * 2015-08-03 */ function getCoversationList() { //消息列表 rong.getConversationList(function(ret, err) { if (ret.status == 'success') { sendConListReJson(ret, function(list_json) { beforeRender(list_json); // api.alert({ // msg:JSON.stringify(list_json) // }); var html_type = template.render('hhlist_script', list_json); document.getElementById('hhlist_div').innerHTML = html_type; api.hideProgress(); //未读总条数,显示在APP右上角 var unread_sum = 0; var unread_arr = $api.domAll('.unread_count'); for (var i = 0; i < unread_arr.length; i++) { var unread_count = parseInt($api.val(unread_arr[i])); unread_sum = unread_sum + unread_count; } //设置应用图标右上角数字,支持所有iOS手机,以及部分Android手机,如小米和三星的某些型号 api.setAppIconBadge({ badge : unread_sum }); var aui_img = $api.domAll('.aui-user-view-cell'); //如果之前有系统消息,需要改成从1开始循环,去掉系统消息 for (var i = 0; i < aui_img.length; i++) { (function(i) { var id = $api.attr(aui_img[i], "id"); //长按删除,3秒 var myHanmer = new Hammer($api.byId(id)); myHanmer.on("press", function(e) { api.confirm({ title : "提示", msg : "确认删除当前会话吗?", buttons : ["取消", "确定"] }, function(ret, err) { if (1 == ret.buttonIndex) { return; } else { //删除会话 clearMessageById($api.attr(myHanmer.input.target, 'id'), $api.attr(myHanmer.input.target, 'alt')); } }); // alert($api.attr(myHanmer.input.target,'id')); }); })(i); } }); } else { var errJson = JSON.stringify(err); // api.alert({ // msg : "err=" + errJson // }); } }); } /** * 获取某一会话的最新消息记录 */ function getLatestMessagesById(conver_type, target_id, count, callback) { rong.getLatestMessages({ conversationType : conver_type, targetId : target_id + '', count : parseInt(count) }, function(ret, err) { if (ret.status == "success") { callback(ret.result); } else { api.alert({ msg : '获取某一会话的最新消息记录失败' }); } }) } /** * 获取历史聊天记录 * 周枫 * 2015.08.20 */ function getHistoryMessagesById(conver_type, target_id, old_msg_id, msg_count) { rong.getHistoryMessages({ conversationType : conver_type, targetId : target_id, oldestMessageId : parseInt(old_msg_id), count : msg_count }, function(ret, err) { if (ret.status == 'success') { // alert('222:' + JSON.stringify(ret.result)); api.sendEvent({ name : 'setHistory', extra : { data : ret.result } }); } else { api.alert({ msg : '对不起,获取历史会话信息失败' }); } }) } /* *发送消息的函数 注意要放在消息列表页,不要放在会话页面 在会话页面利用sendEvent发出一个发送消息的事件,在消息列表页监听 * 周枫 * 2015-08-03 */ function sendMessage(type, targetId, content, extra, conversationType) { // api.alert({ // msg: 'type:'+type+',targetId:'+targetId+',content:'+content+',conversationType:'+conversationType // },function(ret,err){ // //coding... // }); rong.sendTextMessage({ conversationType : '' + conversationType + '', targetId : '' + targetId + '', text : '' + content + '', extra : '' + extra + '' }, function(ret, err) { if (ret.status == 'prepare') { //单聊准备发送,向会话页面发送正在发送消息事件 api.sendEvent({ name : 'insertSendMessage', extra : { data : ret.result } }) //清除未读信息 cleanMsg(ret.result.message.targetId, conversationType); } else if (ret.status == 'success') { //成功后处理 getCoversationList(); } else if (ret.status == 'error') { //失败 api.alert({ msg : '发送信息失败:' + err.msg }); } }); } /** * 发送图片消息 * 周枫 * 2015.08.11 * @param {Object} sendMsg */ function sendPicture(target_id, img_url, extra, conversationType) { // api.alert({ // msg : 'img_url:' + img_url + ',target_id:' + target_id // }, function(ret, err) { // //coding... // }); rong.sendImageMessage({ conversationType : conversationType, targetId : target_id, imagePath : img_url, extra : extra }, function(ret, err) { if (ret.status == 'prepare') { //单聊准备发送,向会话页面发送正在发送消息事件 api.sendEvent({ name : 'insertSendMessage', extra : { data : ret.result } }) //清除未读信息 cleanMsg(ret.result.message.targetId, conversationType); } else if (ret.status == 'progress') { } else if (ret.status == 'success') { } else if (ret.status == 'error') { var err_code = err.code; switch(err_code) { case -2: api.alert({ msg : '对不起,图片发送失败' }); break; case -1: api.alert({ msg : '对不起,图片发送失败,未知错误' }); break; case 3001: api.alert({ msg : '对不起,图片发送失败,服务器超时' }); break; case 405: api.alert({ msg : '对不起,图片发送失败,您在黑名单中' }); break; case -10000: api.alert({ msg : '对不起,图片发送失败,未调用 init 方法进行初始化' }); break; case -10001: api.alert({ msg : '对不起,图片发送失败,未调用 connect 方法进行连接' }); break; case -10002: api.alert({ msg : '对不起,图片发送失败,输入参数错误' }); break; } } }); } /* * 发送语音消息 * 周枫 * 2015.08.12 * */ function sendVoice(target_id, voicePath, duration, extra, conversationType) { rong.sendVoiceMessage({ conversationType : conversationType, targetId : target_id, voicePath : voicePath, duration : parseInt(duration), extra : extra }, function(ret, err) { if (ret.status == 'prepare') { //单聊准备发送,向会话页面发送正在发送语音事件 api.sendEvent({ name : 'insertSendMessage', extra : { data : ret.result } }) //清除未读信息 cleanMsg(target_id, conversationType); } else if (ret.status == 'success') { } else if (ret.status == 'error') { var err_code = err.code; switch(err_code) { case -2: api.alert({ msg : '对不起,语音发送失败' }); break; case -1: api.alert({ msg : '对不起,图片发送失败,未知错误' }); break; case 3001: api.alert({ msg : '对不起,图片发送失败,服务器超时' }); break; case 405: api.alert({ msg : '对不起,图片发送失败,您在黑名单中' }); break; case -10000: api.alert({ msg : '对不起,图片发送失败,未调用 init 方法进行初始化' }); break; case -10001: api.alert({ msg : '对不起,图片发送失败,未调用 connect 方法进行连接' }); break; case -10002: api.alert({ msg : '对不起,图片发送失败,输入参数错误' }); break; } } }); } /* * 发送会话历史列表返回增加头像和姓名和时间的json * 周枫 * 2015-08-05 */ function sendConListReJson(con_list, callback) { api.ajax({ url : BASE_URL_ACTION + '/rongcloud/getConListReList', method : 'post', dataType : 'json', data : { values : { "con_list" : con_list, "ip_addr" : BASE_SERVER_IP, "app_type" : BASE_APP_TYPE } } }, function(ret, err) { if (ret) { if (ret.status == 'success') { $api.setStorage('hh_index_list', ret.result); callback(ret); } else { api.alert({ msg : '对不起,获取会话列表失败' }); } } }); } /* * 清空某一会话的所有聊天消息记录 * 周枫 * 2015-08-05 */ function clearMessageById(user_id, conver_type) { //首先移除会话列表 rong.removeConversation({ conversationType : conver_type, targetId : user_id }, function(ret, err) { if (ret.status == 'success') { //再真实删除聊天记录 rong.clearMessages({ conversationType : conver_type, targetId : user_id }, function(ret, err) { if (ret.status == 'success') { // api.toast({ // msg : '操作成功', // duration : 1000, // location : 'middle' // }); //重新获取会话列表 getCoversationList(); } }); } }) } /* * 清空所有会话及会话消息 * 周枫 * 2015-08-05 */ function clearConversations() { rong.clearConversations({ conversationTypes : ['PRIVATE', 'GROUP', 'SYSTEM'] }, function(ret, err) { if (ret.status == 'success') { } else { api.alert({ msg : '对不起,删除失败' }); } //重新获取会话列表 getCoversationList(); }) } /* * 清除未读信息红点和条数 * 周枫 * 2015-08-03 */ function cleanMsg(target_id, conver_type) { rong.getHistoryMessages({ conversationType : conver_type, targetId : target_id, oldestMessageId : -1, count : 1 }, function(ret, err) { if (ret.status != "success") { api.alert({ msg : '清除未读信息失败' }); } }) } /** * 废弃,因为融云初始化有问题 * 同步当前用户所属的群组信息到融云服务器 * PS:由于apicloud的参数问题,所以暂时启用了 * 周枫 * 2015.08.24 */ function initPersonGroup() { var person_id = $api.getStorage('person_id'); var identity_id = $api.getStorage('identity'); var ip_addr = BASE_SERVER_IP; //获取当前人员群组信息 api.ajax({ url : BASE_URL_ACTION + '/group/queryMyGroupForApp?person_id=' + person_id + '&identity_id=' + identity_id + '&ip_addr=' + ip_addr, method : 'get', dataType : 'text' }, function(ret, err) { var p_group = eval('(' + ret + ')'); if (p_group.success == true) { //同步当前用户所属的群组信息到融云服务器 rong.syncGroup({ groups : // p_group.groups [{ // groupId : '975', // groupName : '张福才', // portraitUri : '../../image/person/group.png' id : '975', name : '张福才', portraitUrl : '../../image/person/group.png' }, { // groupId : '976', // groupName : '张福才2', // portraitUri : '../../image/person/group.png' id : '976', name : '张福才2', portraitUrl : '../../image/person/group.png' }] }, function(ret, err) { api.toast({ msg : JSON.stringify(ret) }); }) } else { api.alert({ msg : '初始化群组信息失败:' + p_group.info }); } }); } function beforeRender(data) { var g_time = new getTimeTemplate(); //g_time为想在template的标签中执行的函数 data.g_time = g_time; }
这个页面主要包括加载融云的初始化和各种操作,所有函数都有注释就不解释了,总之,其他页面使用数据时都是使用监听获取数据的 4. 会话页面,包括hh_chat_window.html和hh_chat_frame.html两个页面,相关代码写在对应的js中 hh_chat_window.html
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport --> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 --> <meta name="format-detection" content="telephone=no"/> <title>APP</title> <link rel="stylesheet" type="text/css" href="../../css/aui.css" /> <!--<link rel="stylesheet" type="text/css" href="../../css/api.css"/>--> </head> <style> .history-date { font-size: 12px; } #message-content { overflow-y: auto; } #wrap { height: 100%; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -webkit-flex-flow: column; flex-flow: column; } .topbar { background: #1abc9c; height: 50px; /*border-bottom: 1px solid #DDDFE3;*/ line-height: 50px; text-align: center; display: none; color: #ffffff; font-size: 18px; } .activebar { display: block; } .back { position: absolute; padding: 1px 10px 0px 10px; height: 29px; font-size: 15px; /*color: #EFEDED;*/ /*z-index: 99999;*/ } .mTitle { width: 50%; font-size: 18px; text-align: center; display: inline-block; word-break: keep-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } </style> <body> <div id="wrap"> <header class="aui-bar aui-bar-nav aui-bar-primary" id="aui-header"> <div id="cloud" class="topbar activebar"> <div id="back" class="back" οnclick="back();" tapmode=""> <i class="aui-iconfont aui-icon-left"></i> </div> <div class="mTitle" id="mTitle"></div> <a id='menu' class="aui-iconfont aui-icon-friends aui-pull-right" style="display:none;" οnclick="showGroupListById();"></a> </div> </header> <div class="aui-content aui-content-padded" id="message-content"> <p class="aui-text-center history-date"></p> </div> </div> <script type="text/javascript" src="../../script/api.js" ></script> <script type="text/javascript" src="../../script/base_config.js" ></script> <script type="text/javascript" src="../../script/huihua/hh_chat_window.js"></script> </body> </html>
hh_chat_window.js
var header_t; //顶部header高度 var header_h; //发送id var target_id; var conver_type; var h_from; var person_name; apiready = function() { //定位header位置,留出上面电池等空隙,苹果需要 var header = $api.byId('aui-header'); $api.fixStatusBar(header); header_t = $api.offset($api.byId('cloud')); header_h = api.pageParam.header_h; //当前会话用户id和当前会话历史消息从消息列表页点击传递进来 target_id = api.pageParam.targetId; //真实姓名 person_name = api.pageParam.person_name; conver_type = api.pageParam.conver_type; //从哪个页面进入的聊天界面 h_from = api.pageParam.h_from; initHeaer(); //当前target_id的最大会话id var old_msg_id = api.pageParam.old_msg_id; //打开聊天内容frame页面 api.openFrame({ name : 'hh_chat_frame', scrollToTop : true, allowEdit : true, url : '../../html/huihua/hh_chat_frame.html', pageParam : { 'target_id' : target_id, 'old_msg_id' : old_msg_id, 'conver_type' : conver_type }, rect : { x : 0, y : header_h, w : api.winWidth, h : api.winHeight - header_h - 50, }, //页面是否弹动 为了下拉刷新使用 bounces : true }); //安卓关闭 if (api.systemType == 'android') { backFromChatForAndroid(); } //加载uichatbox模块 initUichatbox(); }; /** * 安卓点击返回的时候 * 周枫 * 2015.08.31 */ function backFromChatForAndroid() { api.addEventListener({ name : "keyback" }, function(ret, err) { back(); }); } /** *返回会话列表页面 * 周枫 * 2015.08.08 */ function back() { switch(h_from) { case 'hh_index': //清楚红点 api.execScript({ name : 'index', frameName : 'hh_index', script : 'cleanMsg("' + target_id + '","' + conver_type + '");' }); //重新获取会话列表 api.execScript({ name : 'index', frameName : 'hh_index', script : 'getCoversationList();' }); break; case 'txl_index': //清楚红点 api.execScript({ name : 'index', frameName : 'hh_index', script : 'cleanMsg("' + target_id + '","' + conver_type + '");' }); //重新获取会话列表 api.execScript({ name : 'index', frameName : 'hh_index', script : 'getCoversationList();' }); api.execScript({ name : 'index', frameName : 'txl_index', script : 'loadData();' }); api.execScript({ name : 'index', frameName : 'txl_index', script : 'showMyself();' }); break; case 'txl_content': //清楚红点 api.execScript({ name : 'index', frameName : 'hh_index', script : 'cleanMsg("' + target_id + '","' + conver_type + '");' }); //重新获取会话列表 api.execScript({ name : 'index', frameName : 'hh_index', script : 'getCoversationList();' }); api.execScript({ name : 'txl_content_window', frameName : 'txl_content_frame', script : 'loadData();' }); api.execScript({ name : 'txl_content_window', frameName : 'txl_content_frame', script : 'showMyself();' }); break; } api.closeWin(); } function reloadTxlIndex() { // api.alert({ // msg : '11111' // }, function(ret, err) { // //coding... // }); api.execScript({ name : 'index', frameName : 'txl_index', script : 'loadData();' }); } /** *加载uichatbox模块 * 周枫 * 2015.08.08 */ function initUichatbox() { //引入chatbox var chatBox = api.require('UIChatBox'); //获取表情存放路径 var sourcePath = BASE_EMOTION_PATH; //表情存放目录 var emotionData; //存储表情 getImgsPaths(sourcePath, function(emotion) { emotionData = emotion; }) chatBox.open({ placeholder : '', //输入框显示的最大行数(高度自适应) maxRows : 4, //自定义表情文件夹(表情图片所在的文件夹,须同时包含一个与该文件夹同名的.json配置文件)的路径 //.json文件内的 name 值必须与表情文件夹内表情图片名对应 emotionPath : sourcePath, //聊天输入框模块可配置的文本 texts : { //(可选项)JSON对象;录音按钮文字内容 recordBtn : { //(可选项)字符串类型;按钮常态的标题,默认:'按住 说话' normalTitle : '按住 说话', //(可选项)字符串类型;按钮按下时的标题,默认:'松开 结束' activeTitle : '松开 结束' } }, //模块各部分的样式集合 styles : { //(可选项)JSON对象;输入区域(输入框及两侧按钮)整体样式 inputBar : { borderColor : '#d9d9d9', bgColor : '#f2f2f2' }, //(可选项)JSON对象;输入框样式 inputBox : { borderColor : '#B3B3B3', bgColor : '#FFFFFF' }, //JSON对象;表情按钮样式 emotionBtn : { normalImg : BASE_CHATBOX_PATH + '/chatBox_face1.png' }, //(可选项)JSON对象;附加功能按钮样式,不传则不显示附加功能按钮 extrasBtn : { normalImg : BASE_CHATBOX_PATH + '/chatBox_add1.png' }, //JSON对象;键盘按钮样式 keyboardBtn : { normalImg : BASE_CHATBOX_PATH + '/chatBox_key1.png' }, //(可选项)JSON对象;输入框左侧按钮样式,不传则不显示左边的语音按钮 speechBtn : { normalImg : BASE_CHATBOX_PATH + '/chatBox_key1.png' }, //JSON对象;“按住 录音”按钮的样式 recordBtn : { //(可选项)字符串类型;按钮常态的背景,支持rgb,rgba,#,图片路径(本地路径,fs://,widget://);默认:'#c4c4c4' normalBg : '#c4c4c4', //(可选项)字符串类型;按钮按下时的背景,支持rgb,rgba,#,图片路径(本地路径,fs://,widget://);默认:'#999999'; //normalBg 和 activeBg 必须保持一致,同为颜色值,或同为图片路径 activeBg : '#999999', color : '#000', size : 14 }, //(可选项)JSON对象;表情和附加功能面板的小圆点指示器样式,若不传则不显示该指示器 indicator : { //(可选项)字符串类型;配置指示器的显示区域;默认:'both' //取值范围: //both(表情和附加功能面板皆显示) //emotionPanel(表情面板显示) //extrasPanel(附加功能面板显示) target : 'both', color : '#c4c4c4', activeColor : '#9e9e9e' } }, //(可选项)点击附加功能按钮,打开的附加功能面板的按钮样式,配合 extrasBtn 一起使用,若 extrasBtn 参数内 normalImg 属性不传则此参数可不传 extras : { titleSize : 10, titleColor : '#a3a3a3', //数组类型;附加功能按钮的样式 btns : [{ title : '图片', //(可选项)字符串类型;按钮常态的背景图片 normalImg : BASE_CHATBOX_PATH + '/chatBox_album1.png', //(可选项)字符串类型;按钮按下时的背景图片 activeImg : BASE_CHATBOX_PATH + '/chatBox_album2.png' }, { title : '拍照', normalImg : BASE_CHATBOX_PATH + '/chatBox_cam1.png', activeImg : BASE_CHATBOX_PATH + '/chatBox_cam2.png' }] } }, function(ret, err) { //字符串类型;回调的事件类型, //取值范围: //show(该模块打开成功) //send(用户点击发送按钮) //clickExtras(用户点击附加功能面板内的按钮) //数字类型;当 eventType 为 clickExtras 时,此参数为用户点击附加功能按钮的索引,否则为 undefined //字符串类型;当 eventType 为 send 时,此参数返回输入框的内容,否则返回 undefined //点击附加功能面板 if (ret.eventType == 'clickExtras') { var c_index = ret.index; switch(c_index) { case 0: // api.confirm({ // title : "提示", // msg : "您想要从哪里选取图片 ?", // buttons : ["现在照", "相册选", "取消"] // }, function(ret, err) { // //定义图片来源类型 // var sourceType; // if (1 == ret.buttonIndex) {/* 打开相机*/ // sourceType = "camera"; // } else if (2 == ret.buttonIndex) { // sourceType = "album"; // } else { // return; // } //相册选 getPicture("album"); // }); break; case 1: //现在照 getPicture("camera"); break; } } //点击发送按钮 if (ret.eventType == 'send') { /* *1.用户输入文字或表情 */ /*用户输入表情或文字*/ /*使用读文件方法,读json*/ var sendMsg = transText(ret.msg); if ($api.trimAll(sendMsg).length != 0) { //发送消息的函数,后面会有介绍 //发送消息 // chat(sendMsg); api.execScript({ name : '', frameName : 'hh_chat_frame', script : 'sendText("' + sendMsg + '","' + conver_type + '")' }); /*将文字中的表情符号翻译成图片,并可自定义图片尺寸*/ function transText(text, imgWidth, imgHeight) { var imgWidth = imgWidth || 30; var imgHeight = imgHeight || 30; var regx = /\[(.*?)\]/gm; var textTransed = text.replace(regx, function(match) { var imgSrc = emotionData[match]; if (!imgSrc) { //说明不对应任何表情,直接返回 return match; } var img = "<img src=" + imgSrc + " width=" + imgWidth + " height=" + imgHeight + ">"; return img; }); textTransed = transferBr(textTransed); return textTransed; } } else { //为ipad写的 api.toast({ msg : '对不起,消息不能为空', duration : 2000, location : "middle" }); } } }); //加载录音按钮事件 /** press(按下录音按钮) press_cancel(松开录音按钮) move_out(按下录音按钮后,从按钮移出) move_out_cancel(按下录音按钮后,从按钮移出并松开按钮) move_in(move_out 事件后,重新移入按钮区域) */ chatBox.addEventListener({ target : 'recordBtn', name : 'press' }, function(ret, err) { //开始录音 startRecord(); }); //(松开录音按钮) chatBox.addEventListener({ target : 'recordBtn', name : 'press_cancel' }, function(ret, err) { stopRecord(); }); //move_out(按下录音按钮后,从按钮移出) chatBox.addEventListener({ target : 'recordBtn', name : 'move_out' }, function(ret, err) { api.execScript({ name : '', frameName : 'hh_voice_window', script : 'moveOut()' }); }); //move_out_cancel(按下录音按钮后,从按钮移出并松开按钮) chatBox.addEventListener({ target : 'recordBtn', name : 'move_out_cancel' }, function(ret, err) { api.stopRecord(function(ret, err) { if (ret) { removefile(ret.path); } }); api.closeFrame({ name : 'hh_voice_window' }); }); //move_in(move_out 事件后,重新移入按钮区域) chatBox.addEventListener({ target : 'recordBtn', name : 'move_in' }, function(ret, err) { api.execScript({ name : '', frameName : 'hh_voice_window', script : 'moveIn()' }); }); //输入框绑定 /** * move(输入框所在区域弹动事件) change(输入框所在区域高度改变) showRecord(用户点击左侧语音按钮) showEmotion(用户点击表情按钮) showExtras(用户点击右侧附加功能按钮,如果 open 时传了 extras 参数才会有此回调) */ //move(输入框所在区域弹动事件) 就是输入框收起和弹出变化 chatBox.addEventListener({ target : 'inputBar', name : 'move' }, function(ret, err) { // api.toast({msg: JSON.stringify(ret),location: 'top'}); //50 // api.toast({msg: JSON.stringify(err),location: 'middle'}); //283 //点击输入框时会话界面高度发生变化 setChatFrameByInputMove(ret.inputBarHeight, ret.panelHeight); }); //change(输入框所在区域高度改变) chatBox.addEventListener({ target : 'inputBar', name : 'change' }, function(ret, err) { // api.toast({msg: JSON.stringify(ret),location: 'top'}); //50 // api.toast({msg: JSON.stringify(err),location: 'middle'}); //283 //点击输入框时会话界面高度发生变化 setChatFrameByInputChange(ret.inputBarHeight, ret.panelHeight); }); } /** *发送消息 * 周枫 * 2015.08.08 * @param {Object} sendMsg */ //function chat(sendMsg) { // //向会话列表页发送消息事件 // api.sendEvent({ // name : 'sendMessage', // extra : { // type : 'text', // targetId : '' + target_id + '', // content : sendMsg, // conversationType : 'PRIVATE', // extra : '' // } // }) //} /** * 删除文件 * 周枫 * 2015.08.10 * @param {Object} path */ function removefile(path) { var fs = api.require('fs'); fs.remove({ path : path }, function(ret, err) { if (ret.status != true) { // api.alert({ // msg : err.msg // }, function(ret, err) { // //coding... // }); } }); } /** *开始录音 * 周枫 * 2015.08.10 */ function startRecord() { api.openFrame({ name : 'hh_voice_window', url : '../../html/huihua/hh_voice_window.html', scrollToTop : true, rect : { x : 0, y : 0, w : api.winWidth, h : api.winHeight - 50, }, }); //点击后播放开启录音的声音 api.startPlay({ path : 'widget://res/LowBattery.mp3' }, function() { api.startRecord(); }); } /** * 结束录音 * path:'', //字符串,返回的音频地址 duration:0 //数字类型,音频的时长 * 周枫 * 2015.08.10 */ function stopRecord() { api.stopRecord(function(ret, err) { if (ret) { if (ret.duration == 0) { api.execScript({ name : '', frameName : 'hh_voice_window', script : 'moveShort()' }); removefile(ret.path); } else { api.sendEvent({ name : 'setVoice', extra : { voice_result : ret, conver_type : conver_type } }); // api.execScript({ // name : '', // frameName : 'hh_chat_frame', // script : 'sendVoi("' + ret.path + '",' + ret.duration + ')' // }); // // sendVoiceMessage(mytoken, ret.path, ret.duration); // $api.val($api.byId("record_hid"), ret.path); } setTimeout("api.closeFrame({name: 'hh_voice_window'})", 400); } }); } /** * 点击输入框时会话界面高度发生变化 * inputBarHeight: 50, //数字类型;输入框及左右按钮整体区域的高度,仅当监听 inputBar 的 move 和 change 事件时本参数有值 panelHeight: 300 //数字类型;输入框下边缘距离屏幕底部的高度,仅当监听 inputBar 的 move 和 change 事件时本参数有值 * 周枫 * 2015.08.10 */ function setChatFrameByInputMove(inputBarHeight, panelHeight) { if (inputBarHeight > 0) {//输入框打开时 api.setFrameAttr({ name : 'hh_chat_frame', rect : { x : 0, y : header_h, w : api.winWidth, h : api.winHeight - header_h - inputBarHeight - panelHeight - 35, }, }); } else {//关闭时 api.setFrameAttr({ name : 'chatFrame', rect : { x : 0, y : header_h, w : api.winWidth, h : api.winHeight - header_h - inputBarHeight - 35, }, }); } setTimeout('setBottom()', 200); } /** * 输入框内文字行数,现设置为最多4行 * inputBarHeight: 50, //数字类型;输入框及左右按钮整体区域的高度,仅当监听 inputBar 的 move 和 change 事件时本参数有值 panelHeight: 300 //数字类型;输入框下边缘距离屏幕底部的高度,仅当监听 inputBar 的 move 和 change 事件时本参数有值 * 周枫 * 2015.08.10 */ function setChatFrameByInputChange(inputBarHeight, panelHeight) { api.setFrameAttr({ name : 'hh_chat_frame', rect : { x : 0, y : header_h, w : api.winWidth, h : api.winHeight - header_h - inputBarHeight - panelHeight - 35, }, }); setTimeout('setBottom()', 200); } function setBottom() { api.execScript({ name : '', frameName : 'hh_chat_frame', script : 'goBottom()' }); } /** * 通过系统相册或拍照获取图片和视频 sourceType:(可选项)图片源类型,从相册、图片库或相机获取图片, library:图片库,camera:相机,album:相册 encodingType:(可选项)返回图片类型,jpg或png,默认值:png mediaValue:(可选项)媒体类型,图片或视频 ,pic:图片,video:视频 destinationType:(可选项)返回数据类型,指定返回图片地址或图片经过base64编码后的字符串 allowEdit:(可选项)是否可以选择图片后进行编辑,只支持iOS,默认值:false quality:(可选项)图片质量,只针对jpg格式图片(0-100整数),默认值:50 targetWidth:(可选项)压缩后的图片宽度,图片会按比例适配此宽度,默认值:原图宽度 targetHeight:(可选项)压缩后的图片高度,图片会按比例适配此高度,默认值:原图高度 saveToPhotoAlbum:(可选项)拍照或录制视频后是否保存到相册,默认值:false callback { data:"", //图片路径 base64Data:"", //base64数据,destinationType为base64时返回 duration:0 //视频时长(数字类型) } * 通过系统相册或拍照获取图片和视频 * 周枫 * 2015.08.11 * @param {Object} sourceType */ function getPicture(sourceType) { switch(sourceType) { case 'camera': //获取一张图片 api.getPicture({ sourceType : sourceType, encodingType : 'png', mediaValue : 'pic', allowEdit : false, quality : 80, // targetWidth : 100, // targetHeight : 1280, saveToPhotoAlbum : true }, function(ret, err) { if (ret) { var imgSrc = ret.data; if (imgSrc != "") { api.sendEvent({ name : 'setPicurl', extra : { imgSrc : imgSrc, pic_source : 'camera', conver_type : conver_type } }); } // sendPic(imgSrc); } }); break; case 'album': //UIMediaScanner 是一个多媒体扫描器,可扫描系统的图片、视频等多媒体资源 var obj = api.require('UIMediaScanner'); obj.open({ //(可选项)图片显示的列数,须大于1 column : 4, //(可选项)图片排序方式,asc(旧->新),desc(新->旧) sort : { key : 'time', order : 'desc' }, //(可选项)模块各部分的文字内容 texts : { stateText : '已选择*项', cancelText : '取消', finishText : '完成' }, styles : { bg : '#fff', mark : { icon : '', position : 'top_right', size : 20 }, nav : { bg : '#eee', stateColor : '#000', stateSize : 18, cancleBg : 'rgba(0,0,0,0)', cancelColor : '#000', cancelSize : 18, finishBg : 'rgba(0,0,0,0)', finishColor : '#000', finishSize : 18 } } }, function(ret) { //callback // list: [{ //数组类型;返回选定的资源信息数组 //path: '', //字符串类型;资源路径,返回资源在本地的绝对路径 //thumbPath: '', //字符串类型;缩略图路径,返回资源在本地的绝对路径 //suffix: '', //字符串类型;文件后缀名,如:png,jpg, mp4 //size: 1048576, //数字类型;资源大小,单位(Bytes) //time: '2015-06-29 15:49' //字符串类型;资源创建时间,格式:yyyy-MM-dd HH:mm:ss //}] if (ret) { if (getJsonObjLength(ret.list) != 0) { api.sendEvent({ name : 'setPicurl', extra : { image_list : ret.list, pic_source : 'album', conver_type : conver_type } }); } } }); break; } } /** * 根据群组id获取群组信息页面 * 周枫 * 2015.09.11 */ function showGroupListById() { getGroupListById(function(group_list) { api.openWin({ name : 'hh_group_window', url : 'hh_group_window.html', bounces : true, animation : 'push', delay : 1, scrollToTop : true, pageParam : { 'targetId' : target_id, 'header_h' : header_h, 'group_list' : group_list, 'group_name' : person_name }, rect : { x : 0, y : 'auto', w : 'auto', h : 'auto' } }); }); } function getGroupListById(callback) { api.ajax({ url : BASE_URL_ACTION + '/dsjxt/getPersonInfoByGroupId?groupId=' + target_id + '&app_type=' + BASE_APP_TYPE, method : 'get', dataType : 'text' }, function(ret, err) { var obj = eval('(' + ret + ')'); if (obj) { callback(obj); } }); } function initHeaer() { //如果是群组会话,则显示右上角群组成员 if (conver_type == 'GROUP') { $api.css($api.byId('menu'), 'display:inline;'); } $api.html($api.byId('mTitle'), person_name); }
hh_chat_frame.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport --> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 --> <meta name="format-detection" content="telephone=no"/> <title>会话页面frame</title> <link rel="stylesheet" type="text/css" href="../../css/aui.css" /> <style> .history-date { font-size: 12px; text-align: center;} .pic_thumb { max-width:100px;} </style> </head> <body> <div class="aui-content aui-content-padded" style="padding-top:10px; padding-bottom: 10px;" id="message-content"> <!--<div class="aui-chat-sender history-date" id="hh_update_div"><p>上拉加载会话记录...</p></div>--> <!--<div class="aui-chat-sender"> <div class="aui-chat-sender-avatar"><img src="../../image/person/demo_m.png"></div> <div class="aui-chat-sender-cont"> <div class="aui-chat-right-triangle"></div> <span>6''<img id="voice_123" alt="98" src="../../image/chatBox/msendlog.png" width="40px" height="30px" οnclick="playVoice('123','path',0);"/></span> </div> </div> <div class="aui-chat-receiver"> <div class="aui-chat-receiver-avatar"><img src="../../image/person/demo_w.png"></div> <div class="aui-chat-receiver-cont"> <div class="aui-chat-left-triangle"></div> <span>你好!</span> </div> </div> <div class="aui-chat-sender history-date"><p>7-16 20:00</p></div> <div class="aui-chat-sender"> <div class="aui-chat-sender-avatar"><img src="../../image/person/demo_m.png"></div> <div style="float:right; margin: 0 10px 10px 20px; "><em>[图片]</em></div> <div class="aui-chat-sender-cont"> <div class="aui-chat-right-triangle"></div>--> <!--<span><img style=" width: 10px; height: 10px; margin-right: 10px; " alt="99" src="../../image/loading_more.gif"/></span>--> <!--<span>Hello!!</span>--> <!--</div> </div> <div class="aui-chat-receiver"> <div class="aui-chat-receiver-avatar"><img src="../../image/person/demo_w.png"></div> <div class="aui-chat-receiver-title"><em>[图片]</em></div> <div class="aui-chat-receiver-cont"> <div class="aui-chat-left-triangle"></div> <span>你好!</span> </div> </div>--> </div> </body> <script type="text/javascript" src="../../script/api.js"></script> <script type="text/javascript" src="../../script/date.js"></script> <script type="text/javascript" src="../../script/base_config.js"></script> <script type="text/javascript" src="../../script/huihua/hh_chat_frame.js"></script> </html>
hh_chat_frame.js
//最后一条消息的 Id,获取此消息之前的 count 条消息,没有消息第一次调用应设置为: -1 var old_msg_id = -1; //定义发送人 var target_id; var conver_type; apiready = function() { //当前target_id的历史聊天记录 var historyMessages = api.pageParam.historyMessages; target_id = api.pageParam.target_id; old_msg_id = api.pageParam.old_msg_id; conver_type = api.pageParam.conver_type; //页面加载时获取历史信息 setTimeout('initGetHistory("' + target_id + '", "' + old_msg_id + '", "' + conver_type + '", ' + 10 + ')', '200'); setTimeout('goBottom()', 500); //监听收到新消息写入 api.addEventListener({ name : 'getNewMessage' }, function(ret) { if (ret && ret.value) { //监听成功 var newMessageData = ret.value; // api.alert({ // msg : JSON.stringify(newMessageData) // }); // api.alert({msg:newMessageData.data.objectName }); //根据targetId和当前会话用户id判断一下,如果相等则写入 if (newMessageData.data.targetId == target_id) { //获取会话列表页数据 var hh_index_list = $api.getStorage('hh_index_list'); //会话头像 var receive_img; for (var i = 0; i < hh_index_list.length; i++) { if ((newMessageData.data.targetId == target_id) && (hh_index_list[i].targetId == newMessageData.data.senderUserId)) { receive_img = hh_index_list[i].avatar_url; break; } if ((newMessageData.data.targetId == target_id) && (hh_index_list[i].targetId != newMessageData.data.senderUserId)) { receive_img = BASE_URL_ACTION + '/html/thumb/Material/0D/0D7B3741-0C3D-D93C-BA3D-74668271F934.jpg@50w_50h_100Q_1x.jpg'; } } //如果是群组则显示发送人姓名 if (newMessageData.data.conversationType == "GROUP") { var group_data = $api.getStorage('group_data'); var sender_name = group_data[newMessageData.data.senderUserId]; switch(newMessageData.data.objectName) { case 'RC:TxtMsg': $api.append($api.byId("message-content"), '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-title"><em>' + sender_name + '</em></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + newMessageData.data.content.text + '</span></div></div>'); break; case 'RC:ImgMsg': $api.append($api.byId("message-content"), '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-title"><em>' + sender_name + '</em></div><div class="aui-chat-receiver-img"><div class="aui-chat-left-triangle"></div><span><img class="pic_thumb" οnclick="openImage(\'' + newMessageData.data.content.imageUrl + '\')" src="' + newMessageData.data.content.thumbPath + '"></span></div></div>'); break; case 'RC:VcMsg': // alert('11111111111111111' + JSON.stringify(newMessageData)); var con = ""; con += '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-title"><em>' + sender_name + '</em></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + newMessageData.data.content.duration + '\'\'<img id="voice_' + newMessageData.data.messageId + '" alt="97" src="../../image/chatBox/mrecelog.png" width="40px" height="30px" οnclick="playVoice(\'' + newMessageData.data.messageId + '\',\'' + newMessageData.data.content.voicePath + '\',1);"/></span></div></div>'; // alert(con); $api.append($api.byId("message-content"), con); break; } } else { switch(newMessageData.data.objectName) { case 'RC:TxtMsg': $api.append($api.byId("message-content"), '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + newMessageData.data.content.text + '</span></div></div>'); break; case 'RC:ImgMsg': $api.append($api.byId("message-content"), '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-img"><div class="aui-chat-left-triangle"></div><span><img class="pic_thumb" οnclick="openImage(\'' + newMessageData.data.content.imageUrl + '\')" src="' + newMessageData.data.content.thumbPath + '"></span></div></div>'); break; case 'RC:VcMsg': // alert('11111111111111111' + JSON.stringify(newMessageData)); var con = ""; con += '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + newMessageData.data.content.duration + '\'\'<img id="voice_' + newMessageData.data.messageId + '" alt="97" src="../../image/chatBox/mrecelog.png" width="40px" height="30px" οnclick="playVoice(\'' + newMessageData.data.messageId + '\',\'' + newMessageData.data.content.voicePath + '\',1);"/></span></div></div>'; // alert(con); $api.append($api.byId("message-content"), con); break; } } } } goBottom(); }); //监听发送新消息写入,这个事件主要来处理发送消息插入到会话窗口中 api.addEventListener({ name : 'insertSendMessage' }, function(ret) { if (ret && ret.value) { var newMessageData = ret.value; //我的头像 var sender_img = $api.getStorage('avatar_url'); // alert(JSON.stringify(newMessageData)); //RC:TxtMsg:文本消息,RC:VcMsg:语音消息,RC:ImgMsg:图片消息,RC:LBSMsg:位置消息 switch (newMessageData.data.message.objectName) { case 'RC:TxtMsg': //页面写入发送消息 $api.append($api.byId("message-content"), '<div class="aui-chat-sender"><div class="aui-chat-sender-avatar"><img src="' + sender_img + '"></div><div class="aui-chat-sender-cont"><div class="aui-chat-right-triangle"></div><span>' + newMessageData.data.message.content.text + '</span></div></div>'); break; case 'RC:ImgMsg': if (api.systemType == 'ios') { $api.append($api.byId("message-content"), '<div class="aui-chat-sender"><div class="aui-chat-sender-avatar"><img src="' + sender_img + '"></div><div class="aui-chat-sender-img"><div class="aui-chat-right-triangle"></div><span><img class="pic_thumb" οnclick="openImage(\'' + newMessageData.data.message.content.imageUrl + '\')" src="' + newMessageData.data.message.content.thumbPath + '"></span></div></div>'); } else if (api.systemType == 'android') { $api.append($api.byId("message-content"), '<div class="aui-chat-sender"><div class="aui-chat-sender-avatar"><img src="' + sender_img + '"></div><div class="aui-chat-sender-img"><div class="aui-chat-right-triangle"></div><span><img class="pic_thumb" οnclick="openImage(\'' + newMessageData.data.message.content.localPath + '\')" src="' + newMessageData.data.message.content.thumbPath + '"></span></div></div>'); } break; case 'RC:VcMsg': var con = ""; con += '<div class="aui-chat-sender"><div class="aui-chat-sender-avatar"><img src="' + sender_img + '"></div><div class="aui-chat-sender-cont"><div class="aui-chat-right-triangle"></div><span>' + newMessageData.data.message.content.duration + '\'\'<img id="voice_' + newMessageData.data.message.messageId + '" alt="98" src="../../image/chatBox/msendlog.png" width="40px" height="30px" οnclick="playVoice(\'' + newMessageData.data.message.messageId + '\',\'' + newMessageData.data.message.content.voicePath + '\',0);"/></span></div></div>'; $api.append($api.byId("message-content"), con); break; } } goBottom(); }); //绑定下拉刷新历史会话事件 api.setRefreshHeaderInfo({ visible : true, loadingImg : 'widget://image/local_icon_refresh.png', bgColor : '#F5F5F5', textColor : '#8E8E8E', textDown : '下拉加载更多...', textUp : '松开加载...', showTime : true }, function(ret, err) { //从服务器加载数据,完成后调用api.refreshHeaderLoadDone()方法恢复组件到默认状态 //调用获取历史会话监听 initGetHistory(target_id, old_msg_id, conver_type, 20); }); //获取历史会话监听,渲染页面 api.addEventListener({ name : 'setHistory' }, function(ret) { // api.alert({ // msg:'333:'+JSON.stringify(ret) // },function(ret,err){ // //coding... // }); if (ret && ret.value) { var historyMessages = ret.value.data; // api.alert({ // msg:JSON.stringify(historyMessages) // },function(ret,err){ // //coding... // }); if (historyMessages != '') { var con = ''; //倒叙循环会话记录 for (var i = getJsonObjLength(historyMessages) - 1; i >= 0; i--) { var targetid = historyMessages[i].targetId; var content = ''; //文字还是图片还是声音 RC:TxtMsg:文本消息,RC:VcMsg:语音消息,RC:ImgMsg:图片消息,RC:LBSMsg:位置消息 var type = historyMessages[i].objectName; //SEND 还是 RECEVIE var dir = historyMessages[i].messageDirection; var start = historyMessages[i].sentTime; // var end = new Date(); var g_time = new getTimeTemplate(); //我的头像 var sender_img = $api.getStorage('avatar_url'); //计算会话时间 if (i == historyMessages.length - 1) { con += '<div class="aui-chat-sender history-date"><p>' + g_time.getTime(start, 1) + '</p></div>'; } else { var M1 = historyMessages[i].sentTime; var M2 = historyMessages[i + 1].sentTime; if ((M1 - M2) >= 180 * 1000) { con += '<div class="aui-chat-sender history-date"><p>' + g_time.getTime(start, 1) + '</p></div>'; } } //加载会话内容 if (dir == 'SEND') { switch(type) { case 'RC:TxtMsg': con += '<div class="aui-chat-sender"><div class="aui-chat-sender-avatar"><img src="' + sender_img + '"></div><div class="aui-chat-sender-cont"><div class="aui-chat-right-triangle"></div><span>' + historyMessages[i].content.text + '</span></div></div>'; break; case 'RC:VcMsg': con += '<div class="aui-chat-sender"><div class="aui-chat-sender-avatar"><img src="' + sender_img + '"></div><div class="aui-chat-sender-cont"><div class="aui-chat-right-triangle"></div><span>' + historyMessages[i].content.duration + '\'\'<img id="voice_' + historyMessages[i].messageId + '" alt="98" src="../../image/chatBox/msendlog.png" width="40px" height="30px" οnclick="playVoice(\'' + historyMessages[i].messageId + '\',\'' + historyMessages[i].content.voicePath + '\',0);"/></span></div></div>'; break; case 'RC:ImgMsg': con += '<div class="aui-chat-sender"><div class="aui-chat-sender-avatar"><img src="' + sender_img + '"></div><div class="aui-chat-sender-img"><div class="aui-chat-right-triangle"></div><span><img class="pic_thumb" οnclick="openImage(\'' + historyMessages[i].content.imageUrl + '\')" src="' + historyMessages[i].content.thumbPath + '"></span></div></div>' break; } //渲染发送会话 // $api.prepend($api.byId("message-content"), '<div class="aui-chat-sender"><div class="aui-chat-sender-avatar"><img src="../../image/person/demo2.png"></div><div class="aui-chat-sender-cont"><div class="aui-chat-right-triangle"></div><span>' + historyMessages[i].content.text + '</span></div></div>'); } else { //获取会话列表页数据 var hh_index_list = $api.getStorage('hh_index_list'); //会话头像 var receive_img; for (var j = 0; j < hh_index_list.length; j++) { if (hh_index_list[j].targetId == historyMessages[i].senderUserId) { receive_img = hh_index_list[j].avatar_url; } else { // receive_img = '../../image/person/demo_m.png'; receive_img = BASE_URL_ACTION + '/html/thumb/Material/0D/0D7B3741-0C3D-D93C-BA3D-74668271F934.jpg@50w_50h_100Q_1x.jpg'; } } if (historyMessages[i].conversationType == "GROUP") { //获取群组人员姓名 var group_data = $api.getStorage('group_data'); var sender_name = group_data[historyMessages[i].senderUserId]; switch(type) { case 'RC:TxtMsg': con += '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-title"><em>' + sender_name + '</em></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + historyMessages[i].content.text + '</span></div></div>'; break; case 'RC:VcMsg': con += '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-title"><em>' + sender_name + '</em></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + historyMessages[i].content.duration + '\'\'<img id="voice_' + historyMessages[i].messageId + '" alt="97" src="../../image/chatBox/mrecelog.png" width="40px" height="30px" οnclick="playVoice(\'' + historyMessages[i].messageId + '\',\'' + historyMessages[i].content.voicePath + '\',1);"/></span></div></div>'; break; case 'RC:ImgMsg': con += '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-title"><em>' + sender_name + '</em></div><div class="aui-chat-receiver-img"><div class="aui-chat-left-triangle"></div><span><img class="pic_thumb" οnclick="openImage(\'' + historyMessages[i].content.imageUrl + '\')" src="' + historyMessages[i].content.thumbPath + '"></span></div></div>' break; //渲染接收会话 // $api.prepend($api.byId("message-content"), '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="../../image/person/demo2.png"></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + historyMessages[i].content.text + '</span></div></div>'); } } else { switch(type) { case 'RC:TxtMsg': con += '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + historyMessages[i].content.text + '</span></div></div>'; break; case 'RC:VcMsg': con += '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + historyMessages[i].content.duration + '\'\'<img id="voice_' + historyMessages[i].messageId + '" alt="97" src="../../image/chatBox/mrecelog.png" width="40px" height="30px" οnclick="playVoice(\'' + historyMessages[i].messageId + '\',\'' + historyMessages[i].content.voicePath + '\',1);"/></span></div></div>'; break; case 'RC:ImgMsg': con += '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="' + receive_img + '"></div><div class="aui-chat-receiver-img"><div class="aui-chat-left-triangle"></div><span><img class="pic_thumb" οnclick="openImage(\'' + historyMessages[i].content.imageUrl + '\')" src="' + historyMessages[i].content.thumbPath + '"></span></div></div>' break; //渲染接收会话 // $api.prepend($api.byId("message-content"), '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="../../image/person/demo2.png"></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + historyMessages[i].content.text + '</span></div></div>'); } } } //获取刷新后最后一条ID if (i == historyMessages.length - 1) { old_msg_id = historyMessages[i].messageId; } } // $api.css($api.byId('hh_update_div'), 'display:none;'); // api.alert({ // msg: con // },function(ret,err){ // //coding... // }); //加载历史聊天记录 $api.prepend($api.byId("message-content"), con); } } //通知顶部下拉刷新数据加载完毕,组件会恢复到默认状态 api.refreshHeaderLoadDone(); //隐藏进度提示框 api.hideProgress(); if (old_msg_id == -1) { goBottom(); } }); // //监听发送新消息写入,这个事件主要来处理发送消息插入到会话窗口中 // api.addEventListener({ // name : 'insertSendMessage' // }, function(ret) { // if (ret && ret.value) { // var newMessageData = ret.value; // // alert(JSON.stringify(newMessageData)); // //页面写入发送消息 // $api.append($api.byId("message-content"), '<div class="aui-chat-sender"><div class="aui-chat-sender-avatar"><img src="../../image/person/demo2.png"></div><div class="aui-chat-sender-cont"><div class="aui-chat-right-triangle"></div><span>' + newMessageData.data.message.content.text + '</span></div></div>'); // } // }); // //监听收到新消息写入 // api.addEventListener({ // name : 'getNewMessage' // }, function(ret) { // if (ret && ret.value) { // //监听成功 // var newMessageData = ret.value; // //根据targetId和当前会话用户id判断一下,如果相等则写入 // if (newMessageData.data.targetId == targetId) { // $api.append($api.byId("message-content"), '<div class="aui-chat-receiver"><div class="aui-chat-receiver-avatar"><img src="../../image/person/demo2.png"></div><div class="aui-chat-receiver-cont"><div class="aui-chat-left-triangle"></div><span>' + newMessageData.data.content.text + '</span></div></div>'); // } // } // }); //绑定发送多个图片的监听 sendPic(); //发送语音消息 sendVoi(); //从后台返回到前台 reAppFromBack(); //下拉刷新数据 // refreshHeaderInfo(); } /** *滚动页面底部 * 周枫 * 2015.08.11 */ function goBottom() { document.getElementsByTagName('body')[0].scrollTop = document.getElementsByTagName('body')[0].scrollHeight; } /** * 发送文本消息 * 周枫 * 2015.08.08 * @param {Object} sendMsg */ function sendText(sendMsg, conver_type) { //向会话列表页发送消息事件 api.sendEvent({ name : 'sendMessage', extra : { type : 'text', targetId : '' + target_id + '', content : sendMsg, conversationType : conver_type, extra : '' } }) } /** * 发送图片消息 * 周枫 * 2015.08.11 * @param {Object} img_url */ function sendPic() { api.addEventListener({ name : 'setPicurl' }, function(ret) { if (ret && ret.value) { var value = ret.value; // alert(JSON.stringify(value)); switch(value.pic_source) { case 'camera': //向会话列表页发送消息事件 api.sendEvent({ name : 'sendMessage', extra : { type : 'pic', targetId : '' + target_id + '', imgSrc : value.imgSrc, conversationType : value.conver_type, pic_source : value.pic_source, extra : '' } }) break; case 'album': //向会话列表页发送消息事件 api.sendEvent({ name : 'sendMessage', extra : { type : 'pic', targetId : '' + target_id + '', img_list : value.image_list, conversationType : value.conver_type, pic_source : value.pic_source, extra : '' } }) break; } } }); } /** * 发送语音消息 * 周枫 * 2015.08.12 */ function sendVoi() { api.addEventListener({ name : 'setVoice' }, function(ret) { if (ret && ret.value) { var value = ret.value.voice_result; // alert(JSON.stringify(value)); //向会话列表页发送消息事件 api.sendEvent({ name : 'sendMessage', extra : { type : 'voi', targetId : '' + target_id + '', voicePath : value.path, duration : value.duration, conversationType : ret.value.conver_type, extra : '' } }) } }); } /** * 展示图片 * 周枫 * 2015.08.12 * @param {Object} img_url */ function openImage(img_url) { var img_urls = new Array(); img_urls[0] = img_url; var obj = api.require('imageBrowser'); obj.openImages({ imageUrls : img_urls, //是否以九宫格方式显示图片 showList : false, activeIndex : 0 }); } /** * 播放语音 * 周枫 * 2015.08.12 */ function playVoice(id, voicePath, whosend) { var objs = document.getElementsByTagName("img"); for (var i = 0; i < objs.length; i++) { if (objs[i].alt == '98') { objs[i].src = '../../image/chatBox/msendlog.png'; } else if (objs[i].alt == '97') { objs[i].src = '../../image/chatBox/mrecelog.png'; } } api.stopPlay(); if (whosend == 0) { document.getElementById('voice_' + id).src = '../../image/chatBox/msendgif.gif'; } else { document.getElementById('voice_' + id).src = '../../image/chatBox/mrecegif.gif'; } api.startPlay({ path : voicePath }, function() { if (whosend == 0) { document.getElementById('voice_' + id).src = '../../image/chatBox/msendlog.png'; } else { document.getElementById('voice_' + id).src = '../../image/chatBox/mrecelog.png'; } }); // alert(duration+','+voicePath); } /** * 获取历史聊天记录 * 周枫 * 2015.08.20 * @param {Object} target_id 会话人 * @param {Object} old_msg_id 最新会话id * @param {Object} conver_type 会话类型 * @param {Object} msg_count 获取条数 */ function initGetHistory(target_id, old_msg_id, conver_type, msg_count) { api.sendEvent({ name : 'getHistory', extra : { type : conver_type, old_msg_id : old_msg_id, target_id : target_id, msg_count : msg_count } }); } /** * 从后台返回 * 周枫 * 2015.09.02 */ function reAppFromBack() { api.addEventListener({ name : 'resume' }, function(ret, err) { goBottom(); }); } //点击出现气泡按钮功能,暂未实现 //window.addEventListener("touchstart", showBubbleMenu); // //function showBubbleMenu(event) { // var touch = event.touches[0]; // var centerX = touch.clientX; // var centerY = touch.clientY; // var bubbleMenu = api.require('bubbleMenu'); // var btnArray = [{ // "title" : "复制" // }, { // "title" : "删除" // }]; // // bubbleMenu.open({ // centerX : centerX, // centerY : centerY, // btnArray : btnArray, // fixedOn : api.frameName // }, function(ret, err) { // var btn = btnArray[ret.index]; // api.toast({ // msg : '您点击了:' + btn.title + '按钮', // location : 'top' // }); // }); //}
5. 通讯录页面,包括txl_index_window.html和txl_content_window.html两部分,具体如下txl_index_window.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport --> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 --> <meta name="format-detection" content="telephone=no"/> <title>通讯录列表</title> <link rel="stylesheet" type="text/css" href="../../css/aui.css" /> <style> body { } </style> </head> <body> <script type="text/javascript" src="../../script/api.js"></script> <script type="text/javascript" src="../../script/template.js"></script> <script type="text/javascript" src="../../script/base_config.js"></script> <script type="text/javascript" src="../../script/tongxunlu/txl_index_window.js"></script> </body> </html>
txl_index_window.js
//顶部header高度 var header_h; //var listContact; //定义user_id var person_id; //定义身份 var person_identity; var footer_h; var old_msg_id = -1; apiready = function() { //定位header位置,留出上面电池等空隙,苹果需要 var $header = $api.dom('header'); $api.fixIos7Bar($header); header_h = api.pageParam.header_h; footer_h = api.pageParam.footer_h; //加载 listContact 模块 listContact = api.require('listContact'); person_id = $api.getStorage('person_id'); person_identity = $api.getStorage('identity'); //监听来自通讯录页面获取最新会话id的事件 api.addEventListener({ name : 'setOldMessageId' }, function(ret) { if (ret && ret.value) { var value = ret.value; old_msg_id = value.old_msg_id; } }); }; /** * 加载通讯录列表 * 周枫 * 2015.08.18 */ function loadData() { //根据用户ID获取通讯录数据 getTongXunluByUserId(person_id, person_identity, function(txl_data) { //打开list listContact.open({ y : header_h, w : api.winWidth, h : api.winHeight - header_h - footer_h, cellBgColor : '#FFFFFF', cellHeight : 60, indicator : { }, data : txl_data, borderColor: '#DDDFE3' }, function(ret, err) { api.hideProgress(); // index: //点击某个cell所在区域内的cell的下标 // section: //被点击的cell所在的区域的下标 // key: //被点击的cell的区域的key // clickType: //点击类型,0-cell;1-右边按钮;2-左边的按钮 // btnIndex: //点击按钮时返回其下标 //点击index值 var r_i = ret.index; // api.alert({ // msg:'r_i:'+r_i+',key:'+ret.key+',txl_data:' // },function(ret,err){ // //coding... // }); //json串长度 // var l_d = getJsonObjLength(txl_data.common); //安卓下只有common乱序 // if (ret.key == 'common') { // if (api.systemType == 'android') { // //算出正确的值,因为安卓有BUG倒叙 // r_i = l_d - (r_i + 1); // } // } //名字 var title = txl_data[ret.key][r_i].title; //类型: 1:群组 2:学校 3:班级 4:好友 var t = txl_data[ret.key][r_i].t; //登录名,target_id var target_id = txl_data[ret.key][r_i].login_name; // api.alert({ // msg: 'target_id:'+target_id+',id:'+id+',title:'+title+',t:'+t+',key:'+ret.key + ",index:" + ret.index+',section:'+ret.section // }); if (t == 2 || t == 3) { // hideMyself(); //班级、学校的ID var id = txl_data[ret.key][r_i].id; api.openWin({ name : 'txl_content_window', url : 'txl_content_window.html', bounces : true, scrollToTop : true, animation : 'push', delay : 1, pageParam : { 'header_h' : header_h, 'id' : id, 'title' : title, 't' : t }, rect : { x : 0, y : 'auto', w : 'auto', h : 'auto' } }); } else if (t == 1) { //初始化群组数据给融云服务器 initGroupInfoByUserId(function(init_group_result) { if (init_group_result.code == '200') { //群组 var id = txl_data[ret.key][r_i].id; api.openWin({ name : 'txl_content_window', url : 'txl_content_window.html', bounces : true, scrollToTop : true, animation : 'push', delay : 1, pageParam : { 'header_h' : header_h, 'id' : id, 'title' : title, 't' : t }, rect : { x : 0, y : 'auto', w : 'auto', h : 'auto' } }); } }); } else if (t == 4) { //发送target_id获取最新会话id api.sendEvent({ name : 'getOldMessageId', extra : { target_id : target_id, conver_type : 'PRIVATE', count : 1 } }); //打开会话页面 setTimeout('execHhList("' + target_id + '","' + title + '","PRIVATE");', 500); } hideMyself(); closeMyself(); }); }); } /** * 根据用户ID获取通讯录数据 * 周枫 * 2015.08.21 */ function getTongXunluByUserId(user_id, user_identity, callback) { //api.alert({ // msg:user_id+','+user_identity+','+BASE_APP_TYPE //},function(ret,err){ // //coding... //}); api.ajax({ url : BASE_URL_ACTION + '/dsjxt/getAddressBookInfo?user_id=' + user_id + '&user_identity=' + user_identity + '&app_type=' + BASE_APP_TYPE, method : 'get', dataType : 'text' }, function(ret, err) { var obj = eval('(' + ret + ')'); if (obj) { callback(obj); } }); } /** * 初始化群组数据给融云服务器 * 周枫 * 2015.09.10 */ function initGroupInfoByUserId(callback) { var login_name = $api.getStorage('login_name'); var person_id = $api.getStorage('person_id'); var identity = $api.getStorage('identity'); api.ajax({ url : BASE_URL_ACTION + '/rongcloud/initGroupInfoByUserId?login_name=' + login_name + '&identity=' + identity + '&person_id=' + person_id + '&ip_addr=' + BASE_SERVER_IP + '&app_type=' + BASE_APP_TYPE, method : 'get', dataType : 'json' }, function(ret, err) { if (ret.code != '200') { api.alert({ msg : "对不起,同步群组信息失败。" }); } else { callback(ret); } }); } /** * 关闭列表 * 周枫 * 2015.08.18 */ function closeMyself() { listContact.close(); // api.closeWin(); } function hideMyself() { listContact.hide(); } function showMyself() { listContact.show(); } /** * 延迟打开会话聊天界面 * 周枫 * 2015.08.24 * @param {Object} target_id * @param {Object} title * @param {Object} conver_type * target_id, old_msg_id, person_name, conver_type */ function execHhList(target_id, title, conver_type) { api.execScript({ name : 'index', frameName : 'hh_index', script : 'openHhList("' + target_id + '",' + old_msg_id + ',"' + title + '","' + conver_type + '","txl_index");' }); }
通讯录内容页面 txl_content_window.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport --> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 --> <meta name="format-detection" content="telephone=no"/> <title>会话列表</title> <link rel="stylesheet" type="text/css" href="../../css/aui.css" /> <style> .history-date { font-size: 12px; } #message-content { overflow-y: auto; } #wrap { height: 100%; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -webkit-flex-flow: column; flex-flow: column; } .topbar { background: #1abc9c; height: 50px; /*border-bottom: 1px solid #DDDFE3;*/ line-height: 50px; text-align: center; display: none; color: #ffffff; font-size: 18px; } .activebar { display: block; } .back { position: absolute; padding: 1px 10px 0px 10px; height: 29px; font-size: 15px; /*color: #EFEDED;*/ /*z-index: 99999;*/ } </style> </head> <body> <div id="wrap"> <header class="aui-bar aui-bar-nav aui-bar-primary" id="aui-header"> <div id="cloud" class="topbar activebar"> <div id="back" class="back" οnclick="back()" tapmode=""> <i class="aui-iconfont aui-icon-left"></i> </div> <div class="mTitle" id="mTitle"></div> </div> </header> <div class="aui-content aui-content-padded" id="message-content"> <p class="aui-text-center history-date"></p> </div> </div> <script type="text/javascript" src="../../script/api.js"></script> <script type="text/javascript" src="../../script/base_config.js"></script> <script type="text/javascript" src="../../script/tongxunlu/txl_content_window.js"></script> </body> </html>
txl_content_window.js
//顶部header高度 var header_h; var id; var title; //类型: 1:群组 2:学校 3:班级 4:好友 var t; apiready = function() { //定位header位置,留出上面电池等空隙,苹果需要 var header = $api.byId('aui-header'); $api.fixStatusBar(header); header_h = api.pageParam.header_h; title = api.pageParam.title; $api.html($api.byId('mTitle'), title); id = api.pageParam.id; t = api.pageParam.t; //安卓关闭 if (api.systemType == 'android') { backFromChatForAndroid(); } // api.execScript({ // name:'index', // frameName : 'txl_index', // script : 'closeMyself();' // }); //打开通讯录内容frame页面 api.openFrame({ name : 'txl_content_frame', scrollToTop : true, url : '../../html/tongxunlu/txl_content_frame.html', pageParam : { 'id' : id, 't' : t, 'header_h' : header_h }, rect : { x : 0, y : header_h, w : api.winWidth, h : api.winHeight - header_h, }, //页面是否弹动 为了下拉刷新使用 bounces : true }); } /** *返回会话列表页面 * 周枫 * 2015.08.08 */ function back() { api.execScript({ name : 'index', frameName : 'txl_index', script : 'showMyself();' }); api.execScript({ name : 'index', frameName : 'txl_index', script : 'loadData();' }); //关闭群组页面 api.execScript({ frameName : 'txl_content_frame', script : 'closeMyself();' }); api.closeWin(); } /** * 安卓点击返回的时候 * 周枫 * 2015.08.31 */ function backFromChatForAndroid() { api.addEventListener({ name : "keyback" }, function(ret, err) { back(); }); }
txl_content_frame.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport --> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 --> <meta name="format-detection" content="telephone=no"/> <title>会话列表</title> <link rel="stylesheet" type="text/css" href="../../css/aui.css" /> <style> body{ } </style> </head> <body> <div id="txl_data" style="display:none; text-align: center";>暂无数据</div> <script type="text/javascript" src="../../script/api.js"></script> <script type="text/javascript" src="../../script/base_config.js"></script> <script type="text/javascript" src="../../script/tongxunlu/txl_content_frame.js"></script> </body> </html>
txl_content_frame.js
//var listContact; var id; var header_h; var user_id, user_identity; //类型: 1:群组 2:学校 3:班级 4:好友 var t; var old_msg_id = -1; apiready = function() { //加载 listContact 模块 listContact = api.require('listContact'); id = api.pageParam.id; t = api.pageParam.t; user_id = $api.getStorage('person_id'); user_identity = $api.getStorage('identity'); header_h = api.pageParam.header_h; loadData(); //监听来自通讯录页面获取最新会话id的事件 api.addEventListener({ name : 'setOldMessageId' }, function(ret) { if (ret && ret.value) { var value = ret.value; old_msg_id = value.old_msg_id; } }); }; /** * 加载通讯录列表 * 周枫 * 2015.08.18 */ function loadData() { getGroupInfo(function(group_list) { // api.alert({ // msg:JSON.stringify(group_list) // },function(ret,err){ // //coding... // }); //根据用户ID获取通讯录数据 // getTongXunluByUserId(person_id, person_identity, function(txl_data) { //打开list listContact.open({ y : header_h, w : api.winWidth, h : api.winHeight - header_h, cellBgColor : '#FFFFFF', cellHeight : 60, borderColor: '#DDDFE3', indicator : { }, groupTitle:{ size : 12 }, data : group_list }, function(ret, err) { //点击index值 var r_i = ret.index; //聊天类型 var conver_type = group_list[ret.key][r_i].conver_type; //名字 var title = group_list[ret.key][r_i].title; var target_id; //登录名,target_id switch(conver_type) { case "PRIVATE": target_id = group_list[ret.key][r_i].login_name; break; case "GROUP": target_id = group_list[ret.key][r_i].id; //根据id获取群组内人员信息 getGroupInfoById(target_id); break; } // api.alert({ // msg:target_id // },function(ret,err){ // //coding... // }); //发送target_id获取最新会话id api.sendEvent({ name : 'getOldMessageId', extra : { target_id : target_id, conver_type : conver_type, count : 1 } }); //打开会话页面 setTimeout('execHhList("' + target_id + '","' + title + '","' + conver_type + '");', 500); }); // }); }); } /** * 获取群组信息,包括学校教师,班级学生,群组列表 * 周枫 * 2015.08.25 */ function getGroupInfo(callback) { // api.alert({ // msg: 't:'+t+',id:'+id+',user_id:'+user_id+',user_identity:'+user_identity // },function(ret,err){ // //coding... // }); api.ajax({ url : BASE_URL_ACTION + '/dsjxt/getGroupInfo?t=' + t + '&id=' + id + '&user_id=' + user_id + '&user_identity=' + user_identity +'&app_type=' + BASE_APP_TYPE, method : 'get', dataType : 'text' }, function(ret, err) { var obj = eval('(' + ret + ')'); if (getJsonObjLength(obj) == 0) { $api.css($api.byId("txl_data"), "display:block;"); } else { if (obj) { callback(obj); } } }); } /** * 延迟打开会话聊天界面 * 周枫 * 2015.08.24 * @param {Object} target_id * @param {Object} title * @param {Object} conver_type * target_id, old_msg_id, person_name, conver_type */ function execHhList(target_id, title, conver_type) { closeMyself(); hideMyself(); api.execScript({ name : 'index', frameName : 'hh_index', script : 'openHhList("' + target_id + '",' + old_msg_id + ',"' + title + '","' + conver_type + '","txl_content");' }); } /** * 关闭列表 * 周枫 * 2015.08.18 */ //function closeMyself() { api.alert({ msg:'123123' },function(ret,err){ //coding... }); // listContact.close(); // api.closeFrame(); //} /** * 关闭列表 * 周枫 * 2015.08.18 */ function closeMyself() { listContact.close(); // api.closeWin(); } function hideMyself() { listContact.hide(); } function showMyself() { listContact.show(); }
我会经常的访问论坛,我也刚使用不久,希望大家能够多给些建议,多交流,我们一起做得更好。