消息列表组件化,统一私聊和群聊样式

This commit is contained in:
2022-02-22 16:48:49 +08:00
parent ab35229331
commit 01627f6794
11 changed files with 171 additions and 117 deletions

View File

@@ -31,6 +31,9 @@
<view class="preview" v-if="msg.objectName=='RC:GrpNtf'"> <view class="preview" v-if="msg.objectName=='RC:GrpNtf'">
[{{ msg.message }}] [{{ msg.message }}]
</view> </view>
<view class="preview" v-if="msg.objectName=='RC:RcNtf'">
<text v-if="conversationType == 3">{{ user.name }}</text> 撤回了一条消息
</view>
</block> </block>
</view> </view>
</template> </template>

View File

@@ -16,9 +16,9 @@
</template> </template>
<script> <script>
import sentText from '../components/sentText' import sentText from './sentText'
import sentVoice from '../components/sentVoice' import sentVoice from './sentVoice'
import sentPopups from '../components/sentPopups' import sentPopups from './sentPopups'
export default { export default {
props: { props: {

View File

@@ -45,18 +45,35 @@
}, },
methods: { methods: {
// //
backMessage() { backMessage() {
console.log('撤回消息'); if (this.$store.getters.sender.userId != this.message.senderUserId) {
const pushContent = '推送内容' uni.showToast({
icon: 'none',
title: '不能撤回别人的消息'
})
return
}
// TODO
// this.message.sentTime
const pushContent = this.$store.getters.sender.name + '撤回了一条消息'
RongIMLib.recallMessage(this.message.messageId, pushContent, RongIMLib.recallMessage(this.message.messageId, pushContent,
({ ({
code, code,
message message
}) => { }) => {
console.error(code); if (code === 0) {
// uni.showToast({
if (code === 0) { icon: 'none',
console.error(message); title: '消息撤回成功'
})
RongIMLib.getMessage(this.message.messageId, res => {
uni.$emit('onRecallMessage', res.message)
})
} else {
uni.showToast({
icon: 'none',
title: '撤回失败' + code
})
} }
} }
) )

View File

@@ -0,0 +1,110 @@
<template>
<view class="">
<view class="notify" v-if="message.objectName === 'RC:GrpNtf'">{{ message.content.message }}</view>
<view class="notify" v-else-if="message.objectName === 'RC:RcNtf'">
{{ contact(message.senderUserId).name }} 撤回了一条消息
</view>
<view v-else :class="['cell-item', message.messageDirection == 1 ? 'right' : 'left']">
<u-avatar class="avatar" @click="toUser(message)" :size="avatarSize" shape="square"
:src="contact(message.senderUserId).portraitUrl" />
<view class="msg">
<show-text v-if="message.objectName === 'RC:TxtMsg'" :message="message" :isGroup="isGroup" />
<show-voice v-else-if="message.objectName === 'RC:HQVCMsg'" :message="message" :isGroup="isGroup" />
<show-image v-else-if="message.objectName === 'RC:ImgMsg'" :message="message" :isGroup="isGroup" />
<show-call v-else-if="message.objectName === 'RC:InfoNtf'" :message="message" :isGroup="isGroup" />
<view v-else class="">
[未处理的消息类型 {{ message.objectName }}]
</view>
</view>
<!-- <view class="time">{{ item.sentTime|timeCustomCN }}</view> 时间判断最好是隔一段时间没有消息才展示一个 -->
</view>
</view>
</template>
<script>
import showVoice from './show/showVoice'
import showImage from './show/showImage'
import showText from './show/showText'
import showCall from './show/showCall'
import utils from '@/utils/index.js'
export default {
components: {
showCall,
showVoice,
showImage,
showText
},
props: {
message: {
type: Object,
default: function() {
return {}
}
},
isGroup: {
type: Boolean,
default: false
}
},
data() {
return {
avatarRpx: 84
}
},
computed: {
avatarSize() {
return utils.rpx2px(this.avatarRpx)
},
contact() {
return function(targetId) {
return this.$store.getters.contactInfo(targetId)
}
}
},
methods: {
toUser(item) {
if (item.messageDirection == 1) {
uni.navigateTo({
url: '/pages/im/friends/mine?targetId=' + item.senderUserId
})
} else {
uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + item.senderUserId
})
}
}
}
}
</script>
<style lang="scss" scoped>
.notify {
text-align: center;
font-size: 24rpx;
color: #666;
}
.cell-item {
display: flex;
width: 710rpx;
justify-content: flex-start;
&.left {
flex-direction: row;
}
&.right {
flex-direction: row-reverse;
.state {
flex-direction: row;
justify-content: flex-end;
}
}
.msg {
margin: 0 20rpx;
}
}
</style>

View File

@@ -4,17 +4,8 @@
<view class="body"> <view class="body">
<view class="scroll"> <view class="scroll">
<view class="cell" v-for="(item, index) in messages" :key="index"> <view class="cell" v-for="(message, index) in messages" :key="index">
<view class="time" v-if="item.senderUserId === '__system__'">{{ item.content.message }}</view> <show-message-cell :message="message" isGroup />
<view v-else :class="['cell-item', item.messageDirection == 1 ? 'right' : 'left']">
<u-avatar class="avatar" @click="toUser(item)" :size="avatarSize" shape="square"
:src="contact(item.senderUserId).portraitUrl" />
<view class="msg">
<show-voice v-if="item.objectName === 'RC:HQVCMsg'" :message="item" isGroup />
<show-image v-if="item.objectName === 'RC:ImgMsg'" :message="item" isGroup />
<show-text v-if="item.objectName === 'RC:TxtMsg'" :message="item" isGroup />
</view>
</view>
</view> </view>
</view> </view>
</view> </view>
@@ -22,26 +13,19 @@
</template> </template>
<script> <script>
import {
timeCustomCN
} from '@/utils/filters.js'
import { import {
getGroupBase getGroupBase
} from '@/apis/interfaces/im.js' } from '@/apis/interfaces/im.js'
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import im from '@/utils/im/index.js' import im from '@/utils/im/index.js'
import showVoice from '../components/showVoice'
import showImage from '../components/showImage'
import showText from '../components/showText'
import sentMessageBar from '../components/sentMessageBar' import sentMessageBar from '../components/sentMessageBar'
import showMessageCell from '../components/showMessageCell'
import utils from '@/utils/index.js' import utils from '@/utils/index.js'
export default { export default {
components: { components: {
showVoice, sentMessageBar,
showImage, showMessageCell
showText,
sentMessageBar
}, },
data() { data() {
return { return {
@@ -55,9 +39,6 @@
} }
}, },
computed: { computed: {
avatarSize() {
return utils.rpx2px(this.avatarRpx)
},
latestMessage() { latestMessage() {
if (this.messages.length) { if (this.messages.length) {
return this.messages[0] return this.messages[0]
@@ -66,11 +47,6 @@
sentTime: 0 sentTime: 0
} }
} }
},
contact() {
return function(targetId) {
return this.$store.getters.contactInfo(targetId)
}
} }
}, },
onLoad(e) { onLoad(e) {
@@ -103,8 +79,20 @@
}) })
// 清理聊天记录 // 清理聊天记录
uni.$once('cleanGroupMessage', this.getMessageList) uni.$once('cleanGroupMessage', this.getMessageList)
uni.$on('onRecallMessage', (res) => {
if (res.targetId == this.targetId) {
this.messages = this.messages.map(item => {
if (res.messageId == item.messageId) {
return res
} else {
return item
}
})
}
})
}, },
onUnload() { onUnload() {
uni.$off('onRecallMessage')
uni.$off('onReceiptRequest') uni.$off('onReceiptRequest')
uni.$off('onReceiptResponse') uni.$off('onReceiptResponse')
}, },
@@ -117,17 +105,6 @@
onScroll(e) { onScroll(e) {
this.$refs.messageBar.onHidePopus() this.$refs.messageBar.onHidePopus()
}, },
toUser(item) {
if (item.messageDirection == 1) {
uni.navigateTo({
url: '/pages/im/friends/mine?targetId=' + item.senderUserId
})
} else {
uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + item.senderUserId
})
}
},
getNewMessage() { getNewMessage() {
im.getMessageList( im.getMessageList(
this.conversationType, this.conversationType,
@@ -149,6 +126,7 @@
20, 20,
true, true,
(messages) => { (messages) => {
console.log('获取消息列表', messages);
RongIMLib.sendReadReceiptResponse(3, this.targetId, messages, (res) => { RongIMLib.sendReadReceiptResponse(3, this.targetId, messages, (res) => {
console.error('发送群聊已读回执成功', res); console.error('发送群聊已读回执成功', res);
}) })
@@ -193,38 +171,7 @@
.cell { .cell {
padding: 10rpx 20rpx; padding: 10rpx 20rpx;
.time {
text-align: center;
font-size: 24rpx;
color: #666;
}
.cell-item {
display: flex;
width: 710rpx;
justify-content: flex-start;
&.left {
flex-direction: row;
}
&.right {
flex-direction: row-reverse;
.state {
flex-direction: row;
justify-content: flex-end;
}
}
.msg {
margin: 0 20rpx;
}
}
.cell-footer {
height: 20rpx;
}
} }
} }
} }

View File

@@ -4,45 +4,28 @@
<!-- chat --> <!-- chat -->
<view class="body"> <view class="body">
<view class="scroll"> <view class="scroll">
<view class="cell" v-for="(item, index) in messages" :key="index"> <view class="cell" v-for="(message, index) in messages" :key="index">
<view class="time">{{ item.sentTime|timeCustomCN }}</view> <show-message-cell :message="message" />
<view :class="['cell-item', item.messageDirection == 1 ? 'right' : 'left']">
<u-avatar class="avatar" :size="avatarSize" shape="square"
@click="showUser(item.senderUserId, item.messageDirection)"
:src="contact(item.senderUserId).portraitUrl" />
<view class="msg">
<show-voice v-if="item.objectName === 'RC:HQVCMsg'" :message="item" />
<show-image v-if="item.objectName === 'RC:ImgMsg'" :message="item" />
<show-text v-if="item.objectName === 'RC:TxtMsg'" :message="item" />
<show-call v-if="item.objectName === 'RC:InfoNtf'" :message="item" />
</view>
</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import im from '@/utils/im/index.js' import im from '@/utils/im/index.js'
import showVoice from '../components/showVoice'
import showImage from '../components/showImage'
import showText from '../components/showText'
import showCall from '../components/showCall'
import sentMessageBar from '../components/sentMessageBar' import sentMessageBar from '../components/sentMessageBar'
import showMessageCell from '../components/showMessageCell'
import utils from '@/utils/index.js' import utils from '@/utils/index.js'
export default { export default {
components: { components: {
sentMessageBar, sentMessageBar,
showVoice, showMessageCell
showImage,
showText,
showCall
}, },
data() { data() {
return { return {
avatarRpx: 84,
targetId: '', targetId: '',
messages: [], messages: [],
conversationType: 1, conversationType: 1,
@@ -54,9 +37,6 @@
} }
}, },
computed: { computed: {
avatarSize() {
return utils.rpx2px(this.avatarRpx)
},
latestMessage() { latestMessage() {
if (this.messages.length) { if (this.messages.length) {
return this.messages[0] return this.messages[0]
@@ -128,13 +108,6 @@
this.scrollBottom() this.scrollBottom()
}) })
}, },
// 展示好友信息, type 1 是自己, 2 是对方
showUser(targetId, type) {
uni.navigateTo({
url: type === 1 ? '/pages/im/friends/mine?targetId=' + targetId :
'/pages/im/friends/info?targetId=' + targetId
})
},
// 滚动到底部 // 滚动到底部
scrollBottom(type) { scrollBottom(type) {
if (this.latestMessage) { if (this.latestMessage) {

View File

@@ -93,8 +93,11 @@ const imLibListeners = () => {
uni.$emit('onReadReceiptReceived', data) uni.$emit('onReadReceiptReceived', data)
}) })
// 监听消息撤回操作 // 监听消息撤回操作
IMLib.addRecallMessageListener((res) => { IMLib.addRecallMessageListener((res) => {
console.error("消息撤回: ", res); IMLib.getMessage(res.data.messageId, (res) => {
console.error("消息撤回: ", res.message);
uni.$emit('onRecallMessage', res.message)
})
}) })
// 监听需要群聊消息回执 // 监听需要群聊消息回执
IMLib.addReceiptRequestListener(({ IMLib.addReceiptRequestListener(({

View File

@@ -17,7 +17,8 @@ const getMessageList = (conversationType, targetId, timeStamp, count, isForward,
'RC:ReferenceMsg', 'RC:ReferenceMsg',
'RC:CombineMsg', 'RC:CombineMsg',
'RC:GrpNtf', 'RC:GrpNtf',
'RC:InfoNtf' 'RC:InfoNtf',
'RC:RcNtf'
] ]
RongIMLib.getHistoryMessagesByTimestamp( RongIMLib.getHistoryMessagesByTimestamp(