七、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天消息项的实现
会话好友列表的实现
1、项目引言
2、腾讯云后台配置TXIM
3、配置项目并实现IM登录
4、会话好友列表的实现
5、聊天输入框的实现
6、聊天界面容器的实现
7、聊天消息项的实现
8、聊天输入框扩展面板的实现
9、聊天会话管理的实现
10、聊天记录的加载与消息收发
11、定位SD配置与收发定位消息
12、贴图表情的定制化开发
13、腾讯云后台配置TRTC功能
14、集成音视频通话功能
15、集成仿微信的拍照,相册选择插件
16、集成美颜功能
17、集成TPNS消息推送(暂未接入)
@
文章概述
整个IM项目的关键点来了,本文将讨论一下聊天消息的实现,如何收发消息并且实现聊天消息的UI显示。
聊天消息项的实现
1.收发聊天消息
1.1 接收聊天消息
接收聊天消息显得很简单,在之前的会话列表实现中已经做过一次,这次我们代码其实差不多,唯一不一样的是接受后我们需要做筛选确定需要回显到聊天消息界面的项目。
绑定消息事件部分的代码如下:
// 这里选择在onLoad绑定,确定不会漏接数据
async onLoad (params) {
// 做好一个变量确定我现在在和谁聊天
this.receiver = params.receiver
// 监听新的消息
this.$txim.$on('onRecvC2CTextMessage', this.onRecvMessageHanlder)
this.$txim.$on('onRecvC2CCustomMessage', this.onRecvMessageHanlder)
this.$txim.$on('onRecvGroupTextMessage', this.onRecvMessageHanlder)
this.$txim.$on('onRecvGroupCustomMessage', this.onRecvMessageHanlder)
this.$txim.$on('onRecvNewMessage', this.onRecvMessageHanlder)
}
接收到消息的回调事件处理如下
// 获取消息
async onRecvMessageHanlder ({ data }) {
let V2TIMMessageManager = this.$txim.getMessageManager()
let senderId = data?.sender?.userID || data?.sender
if (senderId == this.receiver) {
this.HistoryMessageToChatLog([data])
this.$txim.markC2CMessageAsRead(senderId)
await this.$nextTick()
this.$refs.chatLayout.scrollToBottom()
}
},
1.2 发送聊天消息
发送聊天消息实际上demo已经有所封装了,对于文本消息而言发送的代码如下:
// 发送文字 这里需要防抖处理,反正多次点击发送按钮从而出现问题
sendText: _.debounce(async function (text) {
let V2TIMMessageManager = this.$txim.getMessageManager()
// 创建消息结构体
let v2TIMMessage = V2TIMMessageManager.createTextMessage(text)
try {
// 发送消息
let ret = await V2TIMMessageManager.sendMessage(v2TIMMessage, this.receiver)
// 更新聊天消息
this.HistoryMessageToChatLog([ret.data])
} catch (e) {
this.$utils.toast('发送失败')
}
await this.$nextTick()
// 保持滚动到底部
this.$refs.chatLayout.scrollToBottom()
}, 500, { leading: true, trailing: false }),
上面演示的是文本消息,而对于其他消息而言,只是创建的消息结构体不一样,各种消息的结构体如下
// 文本
let v2TIMMessage = V2TIMMessageManager.createTextMessage(text)
// 大表情
let v2TIMMessage = V2TIMMessageManager.createFaceMessage(0, { faceUrl: url })
// 图片
let v2TIMMessage = V2TIMMessageManager.createImageMessage(filePath)
// 视频
let v2TIMMessage = V2TIMMessageManager.createVideoMessage(filePath, 'mp4', timeLen, snapshotPath)
// 语音
let v2TIMMessage = V2TIMMessageManager.createSoundMessage(filePath, timeLen)
// 定位
let v2TIMMessage = V2TIMMessageManager.createLocationMessage(address, longitude, latitude)
2.聊天消息格式化
为了做好组件之间的解耦合,我们需要将腾讯消息的结构体进行格式化,映射为我们消息组件中能识别的结构体,映射部分的代码实际上utils/imUtils文件中已经有所提供了,具体的操作如下(这里需要注意,里面根据了消息记录的elemType做了判断,elemType腾讯TXIM的官方文档对应这里https://im.sdk.qcloud.com/doc/zh-cn/classcom_1_1tencent_1_1imsdk_1_1v2_1_1V2TIMMessageManager.html)
async HistoryMessageToChatLog (msgLogs, unshift) {
for (let item of msgLogs) {
let msgType = [
null,
this.$imUtils.MSG_TEXT,
null,
this.$imUtils.MSG_IMAGE,
this.$imUtils.MSG_AUDIO,
this.$imUtils.MSG_VIDEO,
null,
this.$imUtils.MSG_LOCATION,
this.$imUtils.MSG_TIP_FACE,
][item.elemType]
let dataJson = {
id: item.msgID,
head: '../static/icon_u_head.jpg',
self: item.isSelf,
type: msgType,
data: null
}
switch (msgType) {
case this.$imUtils.MSG_TEXT:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item.elem.text, item)
break
case this.$imUtils.MSG_LOCATION:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item, item.elem.latitude, item.elem.longitude, item.elem.desc, item)
break
case this.$imUtils.MSG_IMAGE:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item.elem.imageList[0].url, item)
break
case this.$imUtils.MSG_AUDIO:
dataJson.data = this.$imUtils.buildMessageItem(msgType, '', item.elem.duration * 1000, item)
break
case this.$imUtils.MSG_VIDEO:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item, item)
break
case this.$imUtils.MSG_TIP_FACE:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item, item)
break
default:
// console.log(item)
}
if (msgType) {
this.chatLogs[unshift ? 'unshift' : 'push'](dataJson)
}
}
}
3.聊天消息回显
聊天消息部分demo已经内置了一个聊天组件,我们可以实现开箱即用,只需要引入组件定义好list即可
首先我们需要引入组件,并且在template对应的位置写好即可
<chat-message-item
v-for="item in chatLogs"
:ref="item.id"
:self="item.self"
:head="item.head"
:type="item.type"
:data="item.data"
:prevent="currentPopItem && currentPopItem.item.id == item.id"
@longpressContent="currentPopItem = { ref: $refs[item.id][0], item }"
>
</chat-message-item>
<script>
import ChatMessageItem from '../components/ChatMessageItem'
export default {
components: { ChatMessageItem },
}
</script>
4.聊天消息弹出菜单
一般而言我们聊天消息还需要有一些操作,比如删除,转发之类的,那么我们也需要为聊天消息增加弹出菜单,这需要我们去做浮动位置的计算,然而demo中已经提供了一个弹出菜单,使得我们可以很简单的实现这个功能。
聊天消息的弹出菜单组件在componetns/ChatMsgItemProp下,开发者需要自己修改成为自己需要的功能,这里我们先引入组件然后加入到template中对应位置
<chat-layout
class="page"
ref="chatLayout"
:end="end"
@upperLoading="loadMoreLog"
@scroll="onChatLayoutScroll"
@clickRoot="onRootClick"
>
<chat-message-item
v-for="item in chatLogs"
:ref="item.id"
:self="item.self"
:head="item.head"
:type="item.type"
:data="item.data"
:prevent="currentPopItem && currentPopItem.item.id == item.id"
@longpressContent="currentPopItem = { ref: $refs[item.id][0], item }"
>
</chat-message-item>
<!-- 这里要明显注意,弹出不是在ChatMessageItem里面的! -->
<chat-msg-item-pop
:show="currentPopItem"
@clickFn="onPopClickFn($event)"
></chat-msg-item-pop>
</chat-layout>
这里我们主要是从chatMessageItem中获取到了长按事件的坐标信息,然后交给chatMsgItemPop,弹出组件会根据坐标计算确定显示位置和方向,计算部分的算法如下:
calcPopPosition () {
let { ref } = this.show
let el = ref.$el
let pop = this.$refs.pop
let content = el.children[2]
dom.getComponentRect(pop, ({ size }) => {
let popSize = size
dom.getComponentRect(content, ({ size }) => {
let contentSize = size
this.popPoint.reverse = (contentSize.top - popSize.height) < 0
this.popPoint.popHeight = popSize.height
this.popPoint.itemHeight = contentSize.height
this.popPoint.touchX = contentSize.left + contentSize.width / 2
this.popPoint.touchY = contentSize.top
})
})
}
通过计算确定了显示位置之后就会显示功能菜单列表,在组件中内置了以下的按钮图标,功能暂未实现,开发者可以自己根据实际需要定制化处理哦。
{ type: 'copy', label: '复制', icon: '/static/icon_copy.png' },
{ type: 'share', label: '转发', icon: '/static/icon_share.png' },
{ type: 'collect', label: '收藏', icon: '/static/icon_collect.png' },
{ type: 'delete', label: '删除', icon: '/static/icon_delete.png' },
{ type: 'ref', label: '引用', icon: '/static/icon_ref_msg.png' },
{ type: 'translate', label: '翻译', icon: '/static/icon_fanyi.png' },
{ type: 'search', label: '搜一搜', icon: '/static/icon_search_fun.png' },
项目开源地址及交流群
项目成品效果查看:请点击项目引言
项目开源地址:https://gitee.com/ckong/Zhimi.OpenSource.UniApp.TXIM.Vue
Uniapp开发交流群:755910061
七、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天消息项的实现的更多相关文章
- 一、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-项目引言
项目文章索引 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展面板的 ...
- 五、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天输入框的实现
会话好友列表的实现 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展 ...
- 二、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-腾讯云后台配置TXIM
项目文章索引 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展面板的 ...
- 三、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-配置项目并实现IM登录
项目文章索引 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展面板的 ...
- 四、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-会话好友列表的实现
会话好友列表的实现 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展 ...
- 八、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天输入框扩展面板的实现
聊天输入框扩展面板的实现 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入 ...
- Android IOS WebRTC 音视频开发总结(七十)-- 移动端音视频技术优化的七个方向
最近直播很火,很多朋友对背后的技术比较感兴趣,所以今天我们整理一篇关于移动端视频优化的文章,这篇文章是我朋友在一个技术大会上分享过的,更多内容请关注我们的微信公众号:rtcblacker 视频直播为什 ...
- Android IOS WebRTC 音视频开发总结(六七)-- 在线教育虽火要做好其实不容易
本文主要介绍在线教育这个行业,文章最早发表在我们的微信公众号上,支持原创,详见这里, 欢迎关注微信公众号blackerteam,更多详见www.rtc.help 最近很多朋友在咨询在线教育的事(其实之 ...
- Android IOS WebRTC 音视频开发总结(四七)-- 深度解读国内首届WebRTC大会背后的真相
本文主要解读国内首届WebRTC大会背后的真相,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,更多详见www.rtc.help -------------------------- ...
随机推荐
- 使用flock命令查看nas存储是否支持文件锁
上锁 文件锁有两种 shared lock 共享锁 exclusive lock 排他锁 当文件被上了共享锁之后,其他进程可以继续为此文件加共享锁,但此文件不能被加排他锁,此文件会有一个共享锁计数,加 ...
- 学习java的第八天
一.今日收获 1.学习完全学习手册上2.3转义字符与2.4运算符两节 二.今日难题 1.没有什么难理解的问题 三.明日目标 1.哔哩哔哩教学视频 2.Java学习手册
- Java项目发现==顺手改成equals之后,会发生什么?
最近发生一件很尴尬的事情,在维护一个 Java 项目的时候,发现有使用 == 来比较两个对象的属性, 于是顺手就把 == 改成了 equals.悲剧发生...... == 和 equals 的区别 = ...
- Erda 系列 Meetup「成都站」携手SOFAStack 和你聊聊云原生基础设施建设那点事儿
技术控快上车啦秋天的第一场活动一起来收获技术干货吧! 主题: 云原生基础设施建设的现在及未来时间: 2021 年 9 月 11 日 (周六) 13:30-17:00活动地点: 四川省成都市蚂蚁 C 空 ...
- acquire
An acquired taste is an appreciation for something unlikely to be enjoyed by a person who has not ha ...
- 【Linux】【Services】【SaaS】 kubeadm安装kubernetes
1. 简介 2. 环境 2.1. OS: CentOS Linux release 7.5.1804 (Core) 2.2. Ansible: 2.6.2-1.el7 2.3. docker: 2. ...
- Linux:sqlldr命令
第一步:写一个 ctl格式的控制文件 CTL 控制文件的内容 : load data --1. 控制文件标识 infile 'xxx.txt' --2. 要导入的数据文件名 insert into t ...
- MySQL批量数据脚本示例
一.建表 # 新建库 create database bigData; use bigData; #1 建表dept CREATE TABLE dept( id INT UNSIGNED PRIMAR ...
- python中numpy库ndarray多维数组的的运算:np.abs(x)、np.sqrt(x)、np.modf(x)等
numpy库提供非常便捷的数组运算,方便数据的处理. 1.数组与标量之间可直接进行运算 In [45]: aOut[45]:array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ ...
- arcgis api for js回调函数如何等待同步
arcgis js开发往往会遇到同步异步的问题,有可能在上一步使用了arcgis js模块回调函数,下一步需要用上一步回调函数的结果,但是因为JavaScript是异步执行的,它并不会等待上一步的回调 ...