请尊重作者的辛勤劳动!!!

使用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();
}

我会经常的访问论坛,我也刚使用不久,希望大家能够多给些建议,多交流,我们一起做得更好。

转载于:https://www.cnblogs.com/cczhoufeng/p/4813753.html

apicloud+融云实现即时通讯相关推荐

  1. 融云 web 即时通讯

    融云 web 即时通讯 ☺ 官网https://www.rongcloud.cn/?utm_source=baiduBrand&utm_term=rongyun 老版本但更为详细的开发文档ht ...

  2. 基于融云的即时通讯开发(一)

    一.概述 现在的应用中,即时通讯功能已经很普遍了,从这篇文章开始,我们以第三方平台融云的服务为基础,研究一下如何开发一个具有及时通信功能的软件. 首先,进入融云的官网,地址如下: http://ron ...

  3. 兼具高效与易用,融云 IM 即时通讯长连接协议设计思路

    无论是 PC 端还是移动端,接入网络实现通信都需要建立双端的连接.关注[融云全球互联网通信云]了解更多 客户端和服务端建立连接后不断开,然后进行通信(也就是发送报文)的方式就是长连接. 与之相反,短连 ...

  4. 融云RongIMKit即时通讯开发(让我们聊起来)

    1.前言 现在APP功能越来越多,聊天成为很重要的一个功能,现在市面上流行的即时通讯SDK基本上只有融云和环信,而近年来融云在各个方面都有超过环信的趋势,所以在项目中用到融云的地方越来越多.那我们是不 ...

  5. iOS---集成融云SDK即时通讯

    链接:https://www.jianshu.com/p/eabfb0a93cf9 相信大家在项目中会用到即时通讯功能,自己去写的话会需要前后台合作,会大大加大开发的周期,所以考虑使用第三方的即时通讯 ...

  6. 30 分钟集成融云 IM 即时通讯

    最近公司要做一个社交 app,对于时间就是金钱的当今社会,招聘大量人才去搭建通讯系统肯定是不划算的,花费人力物力财力做出来的 app,可能还没人用.那就瞎了.所以毋庸置疑,一拍即合,用第三方的.就开始 ...

  7. PC端使用融云IM即时通讯

    融云PC端开发者文档 引入 在public的index.html下引入 <script src="https://cdn.ronghub.com/RongIMLib-2.5.0.min ...

  8. 融云 IM 即时通讯的跨应用通信能力

    我们常用"跨服聊天"来形容不在统一频道.无法顺畅沟通的鸡同鸭讲现象.关注[融云全球互联网通信云]了解更多 仅一字之差,在通信能力中,"跨 App 聊天"功能则代 ...

  9. laravel composer 融云im即时通信

    laravel7使用composer开发融云im即时通信 开发环境 需要做的准备 开始开发 开发环境 包管理:Composer PHP框架:Laravel7 融云IM:V3.0 需要做的准备 本文档适 ...

最新文章

  1. 效率提升多倍, 推荐值得收藏40 个命令总结
  2. 全排列(含递归和非递归的解法)
  3. 【原创】新手入门一篇就够:从零开发移动端IM
  4. C语言再学习 -- 存储类、链接
  5. springboot文件上传服务器,SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile)
  6. unity3d干货分享:实现敌人锥形视角的3个方法
  7. 一个支持Abort的BackgroundWorker
  8. Oracle Discover产品简介
  9. 介绍一个基于simhash作海量文章排重的库:simhashpy
  10. mcse 2000 认证介绍
  11. php自动释放mysql连接,php怎么关闭mysql连接
  12. 整合Solr到Tomcat服务器,并配置IK分词
  13. 【matlab选题推荐三】基于MATLAB的答题卡自动阅卷记分系统
  14. E8.Net工作流开发架构
  15. 决策树应用实例③——银行借贷模型
  16. 微信发送语音功能测试用例
  17. c# Environment.GetCommandLineArgs
  18. linux mantis安装包,Linux下安装mantis
  19. python 关键词 抓取网页_python网络爬虫爬取网页内容
  20. 软件测试好学吗 有哪些好的学习建议

热门文章

  1. 张奕卉|可信区块链溯源:因为透明,所以可信
  2. 迪克的空间开通了!密友招募中!!
  3. MBD-有感(Hall)BLDC闭环控制模型
  4. iOS学习之非代码获取iPhone型号及其他信息
  5. 软件测试-黑盒测试:等价类划分法
  6. 7-4 逆序对 (14 分)
  7. 2.Markdown段落
  8. 常用浏览器兼容性代码
  9. 诺基亚android one机型,这风格似曾相识?诺基亚Android One新机有种Lumia味道
  10. PI SXI_MONITOR查询的表