...
 
Commits (11)
    https://gitcode.net/dcloud/uni-im/-/commit/55b80ed05184005e005ddf54b6a5fd4b1e7ccc77 修复 代码错误导致云对象报错的问题 2024-05-08T14:25:58+08:00 DCloud_MQ maquan@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/937e18bf7781941768e0f7cd34ff0a35c58e6df6 修复 代码错误导致云端扩展框架缓存无效的问题 2024-05-08T14:43:02+08:00 DCloud_MQ maquan@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/0ff902d687cec2e37071f721cd32d3450f2f5e1c 3.0.3 changelog 2024-05-08T14:46:13+08:00 DCloud_JSON linju@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/2f990b7f7f763af6334c46e1a23656da69fd7ba5 优化 消息列表滚动到底时,自动隐藏“有新消息”提示 2024-05-08T14:56:00+08:00 DCloud_MQ maquan@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/89a778eea7c57de900a5700721b2c0b367455def Update package.json 2024-05-08T15:06:19+08:00 DCloud_JSON linju@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/075e41b5ed397311910d0e9d35bf970dc2776bb1 优化 微调“有新消息”提示的样式 2024-05-08T16:01:57+08:00 DCloud_MQ maquan@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/e1b28dd3b2ada6582e172b2eaa93431979777a66 优化 微调“有新消息”提示的样式 2024-05-08T16:18:09+08:00 DCloud_MQ maquan@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/cd02a5f0b4b8f4b8cc8e8e2052e142e9add47fed 更新 优化多个会话切换的草稿功能,提升性能 2024-05-08T19:58:08+08:00 DCloud_JSON linju@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/1b28d936c5272f9efc71bbb5337cf0453e42cea6 Update uni-im-msg-list.vue 2024-05-08T21:00:27+08:00 DCloud_JSON linju@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/3c73c32fbf5021f9c6cf6d01a972575c300e74dc 更新:对于含有图片的消息数据,新增了图片的宽高值,使图片加载前可以固定容器高度,从而避免列表抖动。 2024-05-09T20:37:13+08:00 DCloud_JSON linju@dcloud.io https://gitcode.net/dcloud/uni-im/-/commit/7dd5069d9e5ee640b22239e4641563783d4122cc 3.0.4 2024-05-09T20:54:16+08:00 DCloud_JSON linju@dcloud.io
## 3.0.4(2024-05-09)
- 优化 对于含有图片的消息数据,新增了图片的宽高值,使图片加载前可以固定容器高度,从而避免列表抖动
- 优化 多个会话切换的草稿功能,提升性能消息输入的性能
- 优化 消息列表滚动到底时,自动隐藏“有新消息”提示
- 优化 微调“有新消息”提示的样式
## 3.0.3(2024-05-08)
- 修复 代码错误导致云端扩展框架缓存无效的问题
## 3.0.2(2024-05-08)
- 修复 解决部分云厂商的uniCloud环境不支持写缓存文件引起的问题
## 3.0.1(2024-05-08)
......
<template>
<image @load="load" :src="url" :mode="mode" :style="{width,height}" @click="handleClick"></image>
<image @load="load" :src="url" :mode="mode" :style='{"width":viewWidth,"height":viewHeight}' @click="handleClick"></image>
</template>
<script>
......@@ -16,15 +16,50 @@ import uniIm from '@/uni_modules/uni-im/sdk/index.js';
default: ''
},
maxWidth: {
type: [String,Boolean],
type: [String,Number],
default: false
},
maxHeight: {
type: [String,Number],
default: ''
},
width: {
type: [String,Number],
default: ''
},
height: {
type: [String,Number],
default: ''
}
},
data() {
return {
width:"1px",
height:"1px",
url: ''
url: '',
viewWidth: '',
viewHeight: ''
}
},
mounted() {
// console.log('beforeCreate')
if( this.width && this.height){
// 根据maxWidth 和 maxWidth,在保持宽高比例不变的情况下 计算viewWidth 和 viewHeight
const maxWidth = this.toPx(this.maxWidth)
const maxHeight = this.toPx(this.maxHeight)
let width = this.toPx(this.width)
let height = this.toPx(this.height)
// 如果宽超过最大宽度,高度按比例缩小
if(width > maxWidth){
height = height * maxWidth / width
width = maxWidth
}
// 如果高超过最大高度,宽度按比例缩小
if(height > maxHeight){
width = width * maxHeight / height
height = maxHeight
}
this.viewWidth = width + 'px'
this.viewHeight = height + 'px'
}
},
watch: {
......@@ -37,7 +72,7 @@ import uniIm from '@/uni_modules/uni-im/sdk/index.js';
this.url += '?imageMogr2/thumbnail/400x400>'
}else if(src.indexOf('http') === 0){
// 因为还可能是 base64 blob 的本地图片,所以这里判断是不是http开头的
this.url += '?x-oss-process=image/resize,w_100/quality,q_80'
this.url += '?x-oss-process=image/resize,w_200/quality,q_80'
}
}
},
......@@ -47,24 +82,29 @@ import uniIm from '@/uni_modules/uni-im/sdk/index.js';
methods: {
load(e){
// console.log('img load',e)
this.width = e.detail.width
// 如果以rpx为单位,转换为px
let maxWidth = parseInt(this.maxWidth)
if(this.maxWidth && this.maxWidth.indexOf('rpx') > -1){
maxWidth = parseInt(this.maxWidth) * uniIm.systemInfo.windowWidth / 750
}
// console.log('maxWidth',maxWidth)
if(maxWidth && this.width > maxWidth){
this.width = maxWidth + 'px'
this.height = maxWidth * e.detail.height / e.detail.width + 'px'
// console.error('超了',this.width,this.height)
}else{
this.width = e.detail.width + 'px'
this.height = e.detail.height + 'px'
// TODO:渲染后再设置宽高,为兼容旧版系统,图片消息中没有带宽高的情况
if(!this.width || !this.height){
let width = e.detail.width
let maxWidth = this.toPx(this.maxWidth)
if(maxWidth && width > maxWidth){
this.viewWidth = maxWidth + 'px'
this.viewHeight = maxWidth * e.detail.height / e.detail.width + 'px'
// console.error('超了',this.width,this.height)
}else{
this.viewWidth = e.detail.width + 'px'
this.viewHeight = e.detail.height + 'px'
}
}
},
handleClick(){
this.$emit('click')
},
// 如果是rpx单位,转换为px
toPx(val){
if(typeof val === 'string' && val.indexOf('rpx') > -1){
return parseInt(val) * uniIm.systemInfo.windowWidth / 750
}
return parseInt(val)
}
}
}
......
......@@ -32,7 +32,7 @@
</template>
<template v-slot:floating-block>
<view v-if="hasNewMsg" class="new-msg-bar" @click="showLast">
<uni-icons type="arrow-down" size="16"></uni-icons>
<uni-icons type="pulldown" size="18" color="#007fff"></uni-icons>
<text>有新消息</text>
</view>
</template>
......@@ -372,6 +372,7 @@
},
async onScrollToLower() {
this.scrollTracker.reachBottom()
this.hasNewMsg = false
},
async canHoldScrollDo(fn){
return new Promise((resolve) => {
......@@ -740,13 +741,14 @@
position: absolute;
display: flex;
flex-direction: row;
right: 25px;
align-items: flex-start;
right: 40px;
bottom: 10px;
font-size: 12px;
background-color: white;
border: 1px solid silver;
color: #007fff;
padding: 5px 8px 5px 5px;
border-radius: 5px;
border-radius: 15px 15px 15px 15px;
/* #ifdef H5 */
pointer-events: auto;
cursor: pointer;
......
<template>
<view>
<!-- 注意:根节点都view不能去掉,否则鼠标右键出不来菜单 -->
<uni-im-img max-width="100px" :src="msg.body.url" mode="widthFix" @click="previewImage" class="img" />
<uni-im-img max-width="200px" :src="msg.body.url" :width="msg.body.width" :height="msg.body.height" mode="widthFix" @click="previewImage" class="img" />
</view>
</template>
......
......@@ -14,10 +14,10 @@
</text>
<uni-im-icons class="text isRead" v-if="isFromSelf && 'isRead' in item" :code="item.isRead?'e609':'e741'"
size="14px" :color="item.isRead?'#25882a':'#bbb'"></uni-im-icons>
</template>
<text class="text" v-else-if="item.type == 'text'" :decode="true" space="ensp">{{item.text}}</text>
<uni-im-img v-else-if="item.name == 'img'" max-width="100px" @click="previewImage(item.attrs.src)"
:src="item.attrs.src" mode="widthFix" class="img" />
</template>
<text class="text" v-else-if="item.type == 'text'" :decode="true" space="ensp">{{item.text}}</text>
<uni-im-img v-else-if="item.name == 'img'" max-width="200px" @click="previewImage(item.attrs.src)"
:src="item.attrs.src" :width="item.attrs.width" :height="item.attrs.height" mode="widthFix" class="img" />
<uni-link class="link" v-else-if="item.name == 'a'" :href="item.attrs.href" color="#007fff"
:text="item.children[0].text"></uni-link>
</template>
......
{
"id": "uni-im",
"displayName": "uni-im",
"version": "3.0.2",
"version": "3.0.4",
"description": "uni-im是云端一体的、全平台的、免费的、开源即时通讯系统",
"keywords": [
"im,即时通讯,客服,聊天"
......
......@@ -253,7 +253,9 @@
aboutUserKeyword: '',
memberListScrollTop: 0,
chooseMoreMsg: false,
checkedMsgList: []
checkedMsgList: [],
// 聊天输入框内容
chatInputContent: '',
};
},
props: {
......@@ -319,24 +321,6 @@
})
},
//聊天数据
//当前会话的聊天框文字内容
chatInputContent: {
get() {
// console.log('this.conversation',this.conversation);
return this.conversation?.chatInputContent || '';
},
set(chatInputContent) {
// #ifdef APP-NVUE
if(this.nvueSetChatInputContent){
clearTimeout(this.nvueSetChatInputContent)
}
this.nvueSetChatInputContent = setTimeout(()=>this.conversation.chatInputContent = chatInputContent,1000)
// #endif
// #ifndef APP-NVUE
this.conversation.chatInputContent = chatInputContent
// #endif
}
},
canSend() {
if(typeof this.chatInputContent === 'string'){
return this.chatInputContent.trim() != ''
......@@ -577,14 +561,14 @@
},
onUnload() {
// console.log('onUnload');
// 关闭监听消息推送事件
uniIm.offMsg(this.onImMsg);
// #ifndef H5
uni.offKeyboardHeightChange(this.onKeyboardHeightChange)
// #endif
//页面销毁之前销毁 全局变量 正在聊天的用户的id
uniIm.currentConversationId = false
// console.log('beforeDestroy');
......@@ -660,9 +644,15 @@
async load(param) {
this.answerMsg = false
// conversation_id = "single_eff0518ad35e16a8a025cc8af03e0388"
if(this.conversation.id){
// 设置(含清空)上一个会话的chatInputContent 实现多个会话之间的草稿功能
this.conversation.chatInputContent = this.chatInputContent
}
// console.log('conversation_id',conversation_id);
this.conversation = await uniIm.conversation.get(param)
// 初始化会话的chatInputContent
this.chatInputContent = this.conversation.chatInputContent
// this.conversation.call_list = []
// console.log('this.conversation',this.conversation)
......@@ -863,13 +853,12 @@
// console.log('this.uploadFileAndSendMsg res',res);
tempFiles.forEach(async tempFile => {
// console.log('tempFile~',tempFile);
let {
const {
path:url,
name,
size
} = tempFile;
let {fileType} = tempFile
const {fileType} = tempFile
if (!['image', 'video'].includes(fileType)) {
fileType = 'file'
}
......@@ -888,13 +877,18 @@
});
}
let data = {};
data[fileType] = {
const data = {};
const fileInfo = {
url,
size,
name
};
if(fileType == 'image'){
const {width,height} = await uni.getImageInfo({src:url});
fileInfo.width = width
fileInfo.height = height
}
data[fileType] = fileInfo
let msg = await this.beforeSendMsg(data,false)
// console.log('~~~beforeSendMsg',msg);
try{
......@@ -907,7 +901,7 @@
await this.updateMsg(msg)
this.sendMsg(msg)
}catch(e){
console.error(777,e)
console.error('uploadFile error:',e)
}
});
......@@ -1045,13 +1039,11 @@
}
if (typeof this.chatInputContent == 'object'){
// 富文本(图文混排、@某人)消息
// 把字符串中带url的链接转为html的a标签的形式。1.将字符串,按是否为标签,切割为数组
const htmlStr = this.chatInputContent.html.split(/(<[^>]+>)/)
// 2.找到不以<开头的字符串内的url并替换为 html的a
.map(str=>str.startsWith('<') ? str : uniIm.utils.replaceUrlToLink(str))
.join(' ')
.join('')
// 先插到消息列表
let msg = await this.beforeSendMsg({
"rich-text":uniIm.utils.parseHtml(htmlStr)
......@@ -1062,26 +1054,36 @@
msg.body.forEach(async item=>{
if(item.type === 'text'){
item.text = item.text.trim();
}else if(item.name === 'img' && item.attrs.src.indexOf('data:image/png;base64,') === 0){
}else if(item.name === 'img'){
promiseArr.push(new Promise((resolve,reject)=>{
uniCloud.uploadFile({
filePath: item.attrs.src,
cloudPath: Date.now() + uniCloud.getCurrentUserInfo().uid + '.' + name.split('.').pop(),
}).then(res=>{
item.attrs.src = res.fileID
// console.log('上传成功',res);
resolve()
}).catch(e=>{
console.error(777,e,item.attrs.src);
reject()
})
uni.getImageInfo({
src:item.attrs.src,
success:res=>{
item.attrs.width = res.width
item.attrs.height = res.height
resolve()
},
fail:reject
});
}))
if(item.attrs.src.indexOf('data:image/png;base64,') === 0){
promiseArr.push(new Promise((resolve,reject)=>{
uniCloud.uploadFile({
filePath: item.attrs.src,
cloudPath: Date.now() + uniCloud.getCurrentUserInfo().uid + '.' + name.split('.').pop(),
}).then(res=>{
item.attrs.src = res.fileID
// console.log('上传成功',res);
resolve()
}).catch(e=>{
reject()
})
}))
}
}
})
await Promise.all(promiseArr)
// console.log('msg',msg);
// 传完更新
await this.updateMsg(msg)
// 执行发送
......@@ -1118,10 +1120,7 @@
msg.body = msg.body.trim();
// 阻止发送空消息
if (!msg.body.length) {
this.$nextTick(() => {
this.chatInputContent = '';
this.textareaHeight = 26;
});
this.resetChatInput()
return uni.showToast({
title: '不能发送空消息',
icon: 'none'
......@@ -1162,12 +1161,6 @@
})
}
}
this.$nextTick(e => {
this.chatInputContent = '';
this.textareaHeight = 26;
this.answerMsg = false
});
//如果是回复某一条消息,需要带上相关id
if (this.answerMsg !== false) {
......@@ -1176,6 +1169,8 @@
// 消息列表追加此消息。此时消息状态值为0,表示发送中
let resMsg = this.conversation.msgList.push(msg)
this.resetChatInput()
this.$nextTick(() => {
this.showLast()
......@@ -1197,6 +1192,12 @@
return msg;
}
},
resetChatInput() {
this.chatInputContent = ''
this.textareaHeight = 26
// 关闭引用的消息
this.answerMsg = false
},
getCallUid(param){
let aboutNicknameList = []
if( this.isWidescreen){
......
......@@ -200,7 +200,8 @@ let _registeredExtensionPointsPromise
* @returns {any[]} 该扩展点上挂接的所有扩展程序各自的返回值拼装在一个数组里。
*/
async function invokeExts(extensionPointName, ...args) {
isFsWritable = (this.getCloudInfo().provider === 'aliyun')
const [{ provider }] = uniCloud.getCloudInfos()
isFsWritable = (provider === 'aliyun')
// 尝试从生成的缓存文件中加载
let registeredExtensionPoints
......