Files
im/pages/conversation/chating/components/MessageItem/index.vue
T

403 lines
10 KiB
Vue
Raw Normal View History

2025-11-07 09:56:20 +08:00
<template>
2026-02-09 07:29:02 +08:00
<view v-if="isNoticeMessage" class="notice_message_container" :id="`auchor${source.clientMsgID}`">
2025-12-24 04:12:56 +08:00
<text>{{ getNoticeContent }}</text>
</view>
2026-02-09 07:29:02 +08:00
<view v-else-if="source.contentType == 1519" class="notice_message_container" :id="`auchor${source.clientMsgID}`">
2026-01-09 20:22:25 +08:00
<text @click="toAnnouncement">{{ announcementElem.opUser.nickname }}更新了群公告</text>
</view>
2025-12-24 04:12:56 +08:00
<view v-else class="message_wrapper">
<template v-if="selectFlag">
<uni-icons class="selectedIcon" size="30" color="#07c160" type="checkbox-filled" v-if="selectClientMsgIDItems.indexOf(source.clientMsgID)>-1"></uni-icons>
<uni-icons class="selectedIcon" size="30" color="#ccc" type="circle" v-else></uni-icons>
</template>
<view :id="`auchor${source.clientMsgID}`" class="message_item"
:class="{ message_item_self: isSender, message_item_active: isActive }">
<my-avatar size="42" :desc="source.senderNickname" :src="source.senderFaceUrl" @click="viewDetail" />
<view class="message_container">
<view class="message_sender" :style="{ 'flex-direction': !isSender ? 'row-reverse' : 'row' }">
<text>{{ formattedMessageTime }}</text>
<text style="margin-left: 2rpx; margin-right: 2rpx">{{ "" }}</text>
<text v-if="!isSingle">{{ source.senderNickname }}</text>
2025-11-07 09:56:20 +08:00
</view>
2025-12-24 04:12:56 +08:00
<view class="message_send_state_box">
<view style="height: 100%;display: flex;justify-items: center;align-items: center;">
<view class="message_send_state">
<u-loading-icon v-if="showSending && !isPreview" />
<image v-if="isFailedMessage && !isPreview" class="state_img" src="@/static/images/chating_message_failed.png" />
</view>
</view>
<view class="message_content_wrap message_content_wrap_shadow" :id="`message_content_wrap_${source.clientMsgID}`" @longtap.stop.prevent="longtapEvent($event)">
2026-01-09 20:22:25 +08:00
<component v-if="component" :is="component"
2025-12-24 04:12:56 +08:00
@messageEvent="onMessageEvent"
:isSender="isSender"
:message="source"
:conversationID="conversationID"
></component>
</view>
2025-11-07 09:56:20 +08:00
</view>
</view>
</view>
2026-01-09 20:22:25 +08:00
<view class="selected_overlay" v-if="selectFlag"></view>
2025-11-07 09:56:20 +08:00
</view>
</template>
<script>
2025-12-02 03:05:52 +08:00
import {mapGetters} from "vuex";
import {MessageStatus,MessageType,SessionType,} from "openim-uniapp-polyfill";
2025-11-07 09:56:20 +08:00
import MyAvatar from "@/components/MyAvatar/index.vue";
2025-12-08 18:10:51 +08:00
import TextMessageRender from "./TextMessageRender";
2025-12-11 22:33:31 +08:00
import PictureMessageRender from "./PictureMessageRender";
import VoiceMessageRender from "./VoiceMessageRender";
import VideoMessageRender from "./VideoMessageRender";
import FileMessageRender from "./FileMessageRender";
import AtTextMessageRender from "./AtTextMessageRender";
import MergeMessageRender from "./MergeMessageRender";
import CardMessageRender from "./CardMessageRender";
import LocationMessageRender from "./LocationMessageRender";
import CustomMessageRender from "./CustomMessageRender";
import TypingMessageRender from "./TypingMessageRender";
import QuoteMessageRender from "./QuoteMessageRender";
import FaceMessageRender from "./FaceMessageRender";
import MarkdownMessageRender from "./MarkdownMessageRender";
import StreamMessageRender from "./StreamMessageRender";
import OANotificationRender from "./OANotificationRender";
2026-01-01 04:15:30 +08:00
import NotificationRender from "./NotificationRender";
2025-12-11 22:33:31 +08:00
2025-12-08 18:10:51 +08:00
import ErrorMessageRender from "./ErrorMessageRender";
2025-12-02 03:05:52 +08:00
import {noticeMessageTypes} from "@/constant";
import {tipMessaggeFormat,formatMessageTime} from "@/util/imCommon";
2025-12-11 22:33:31 +08:00
import { ca } from "date-fns/locale";
2025-11-07 09:56:20 +08:00
export default {
components: {
MyAvatar,
TextMessageRender,
2025-12-11 22:33:31 +08:00
PictureMessageRender,
VoiceMessageRender,
VideoMessageRender,
FileMessageRender,
AtTextMessageRender,
MergeMessageRender,
CardMessageRender,
LocationMessageRender,
CustomMessageRender,
TypingMessageRender,
QuoteMessageRender,
FaceMessageRender,
MarkdownMessageRender,
StreamMessageRender,
OANotificationRender,
2026-01-01 04:15:30 +08:00
NotificationRender,
2025-12-08 18:10:51 +08:00
ErrorMessageRender
2025-11-07 09:56:20 +08:00
},
props: {
source: Object,
isSender: {
type: Boolean,
default: false,
},
2025-12-11 22:33:31 +08:00
conversationID:String,
2025-11-07 09:56:20 +08:00
isPreview: Boolean,
isActive: Boolean,
2025-12-24 04:12:56 +08:00
selectFlag:{
type:Boolean,
default:false
},
selectItems:{
type:Array,
default(){
return [];
}
}
2025-11-07 09:56:20 +08:00
},
data() {
2025-12-02 03:05:52 +08:00
return {
toolTipX: 0,
toolTipY: 0,
toolTipFlag: false,
popPostion:"default",
toolTipData: [],
2026-01-09 20:22:25 +08:00
component:"",
announcementElem:{opUser:{nickname:""}}
2025-12-02 03:05:52 +08:00
};
2025-11-07 09:56:20 +08:00
},
computed: {
...mapGetters([
"storeCurrentConversation",
"storeSelfInfo",
]),
isSingle() {
return (
this.storeCurrentConversation.conversationType === SessionType.Single
);
},
formattedMessageTime() {
return formatMessageTime(this.source.sendTime);
},
2025-12-24 04:12:56 +08:00
isNoticeMessage(){
return noticeMessageTypes.includes(this.source.contentType);
},
2025-11-07 09:56:20 +08:00
getNoticeContent() {
2025-12-24 04:12:56 +08:00
if(this.isNoticeMessage){
return tipMessaggeFormat(
2025-11-07 09:56:20 +08:00
this.source,
this.$store.getters.storeCurrentUserID
);
2025-12-24 04:12:56 +08:00
}
return "";
2025-11-07 09:56:20 +08:00
},
isSuccessMessage() {
return this.source.status === MessageStatus.Succeed;
},
isFailedMessage() {
return this.source.status === MessageStatus.Failed;
},
showSending() {
return this.source.status === MessageStatus.Sending && !this.sendingDelay;
},
2025-12-24 04:12:56 +08:00
selectClientMsgIDItems(){
let arr = [];
this.selectItems.forEach((v,k)=>{
arr.push(v.clientMsgID);
});
return arr;
}
2025-11-07 09:56:20 +08:00
},
mounted() {
2026-01-09 20:22:25 +08:00
if(this.source.contentType == MessageType.GroupAnnouncementUpdated){
this.announcementElem = JSON.parse(this.source.notificationElem.detail)
}else{
const MsgType2Components = {
['type_'+MessageType.TextMessage] : "TextMessageRender",
['type_'+MessageType.PictureMessage] : "PictureMessageRender",
['type_'+MessageType.VoiceMessage] : "VoiceMessageRender",
['type_'+MessageType.VideoMessage] : "VideoMessageRender",
['type_'+MessageType.FileMessage] : "FileMessageRender",
['type_'+MessageType.AtTextMessage] : "AtTextMessageRender",
['type_'+MessageType.MergeMessage] : "MergeMessageRender",
['type_'+MessageType.CardMessage] : "CardMessageRender",
['type_'+MessageType.LocationMessage] : "LocationMessageRender",
['type_'+MessageType.CustomMessage] : "CustomMessageRender",
['type_'+MessageType.TypingMessage] : "TypingMessageRender",
['type_'+MessageType.QuoteMessage] : "QuoteMessageRender",
['type_'+MessageType.FaceMessage] : "FaceMessageRender",
['type_'+MessageType.MarkdownMessage] : "MarkdownMessageRender",
['type_'+MessageType.StreamMessage] : "StreamMessageRender",
['type_'+MessageType.OANotification] : "OANotificationRender",
'type_2001' : "NotificationRender"
};
this.component = MsgType2Components['type_'+this.source.contentType] || "ErrorMessageRender";
}
2025-12-11 22:33:31 +08:00
this.$emit('userEvent',{type:"messageItemRender"},this.source.clientMsgID);
2025-11-07 09:56:20 +08:00
this.setSendingDelay();
},
methods: {
viewDetail(){
2026-01-15 22:50:35 +08:00
this.$emit('userEvent',{type:"avatarClick"},this.source);
2025-11-07 09:56:20 +08:00
},
2026-01-09 20:22:25 +08:00
toAnnouncement(){
uni.navigateTo({
url:"/pages/conversation/groupSettings/announcement"
})
},
2025-11-07 09:56:20 +08:00
setSendingDelay() {
if (this.source.status === MessageStatus.Sending) {
setTimeout(() => {
this.sendingDelay = false;
}, 2000);
}
},
2025-12-05 16:10:52 +08:00
longtapEvent(e){
this.$emit('userEvent',{type:"longtapMsgContent"},this.source);
2025-12-02 03:05:52 +08:00
},
2026-01-09 20:22:25 +08:00
onMessageEvent(e,data){
this.$emit('userEvent',e,data);
2025-12-17 08:47:58 +08:00
},
2025-11-07 09:56:20 +08:00
},
};
</script>
<style scoped lang="scss">
2025-12-24 04:12:56 +08:00
.message_wrapper{
display: flex;
flex-direction: row;
align-items: flex-start;
width: 100%;
2026-01-09 20:22:25 +08:00
position: relative;
.selected_overlay{
position: absolute;
left:0;
top:0;
bottom: 0;
right: 0;
z-index: 10;
}
2025-12-24 04:12:56 +08:00
}
2025-11-07 09:56:20 +08:00
.message_item {
display: flex;
flex-direction: row;
2025-12-24 04:12:56 +08:00
flex:1;
2025-11-07 09:56:20 +08:00
padding: 16rpx 44rpx;
// padding-top: 48rpx;
position: relative;
.check_wrap {
@include centerBox();
box-sizing: border-box;
width: 40rpx;
min-width: 40rpx;
height: 40rpx;
min-height: 40rpx;
border: 2px solid #979797;
border-radius: 50%;
margin-top: 16rpx;
margin-right: 24rpx;
&_active {
background-color: #1d6bed;
border: none;
}
&_disabled {
background-color: #c8c9cc;
}
}
.message_container {
display: flex;
flex-direction: column;
align-items: flex-start;
margin-left: 20rpx;
2025-12-05 16:10:52 +08:00
// text-align: flex-start;
2025-11-07 09:56:20 +08:00
max-width: 80%;
position: relative;
.message_sender {
@include nomalEllipsis();
display: flex;
max-width: 480rpx;
// font-size: 24rpx;
font-size: 0.85rem;
color: #666;
margin-bottom: 6rpx;
}
2025-12-02 03:05:52 +08:00
.message_content_wrap_shadow {
2026-02-09 07:29:02 +08:00
box-shadow: 0px 0px 0px rgba(0,0,0,0.1);
2025-12-02 03:05:52 +08:00
}
2025-11-07 09:56:20 +08:00
.message_content_wrap {
@include vCenterBox();
2025-12-05 16:10:52 +08:00
text-align: flex-start;
2025-11-07 09:56:20 +08:00
// font-size: 14px;
color: $uni-text-color;
width: fit-content;
2025-12-02 03:05:52 +08:00
word-wrap: break-word;
word-break: break-word;
2025-11-07 09:56:20 +08:00
.bg_container {
padding: 16rpx 24rpx;
2025-12-05 16:10:52 +08:00
border-radius: 12rpx;
2025-12-02 03:05:52 +08:00
background-color: #fff;
2025-11-07 09:56:20 +08:00
}
}
}
.message_send_state_box {
display: flex;
flex-direction: row-reverse;
}
.message_send_state {
@include centerBox();
margin-left: 12rpx;
// margin-top: 48rpx;
width: 48rpx;
height: 48rpx;
.read_limit_count {
// font-size: 24rpx;
font-size: 0.85rem;
color: #999;
}
2025-12-08 18:10:51 +08:00
.state_img {
2025-11-07 09:56:20 +08:00
width: 16px;
height: 16px;
}
}
::v-deep.emoji_display {
width: 24px;
height: 18px;
vertical-align: sub;
}
&_self {
flex-direction: row-reverse;
.check_wrap {
margin-right: 0;
margin-left: 24rpx;
}
.message_container {
margin-left: 0;
margin-right: 20rpx;
// text-align: end;
align-items: flex-end;
2025-12-02 03:05:52 +08:00
.message_content_wrap_shadow {
2026-02-09 07:29:02 +08:00
box-shadow: 0px 0px 0px #95e261;
2025-12-02 03:05:52 +08:00
}
2025-11-07 09:56:20 +08:00
.message_content_wrap {
flex-direction: row-reverse;
2025-12-08 18:10:51 +08:00
2025-11-07 09:56:20 +08:00
.bg_container {
2025-12-17 08:47:58 +08:00
border-radius: 6rpx;
2025-12-02 03:05:52 +08:00
background-color: #94ec68 !important;
2025-11-07 09:56:20 +08:00
}
}
}
.message_send_state_box {
flex-direction: row;
}
.message_send_state {
margin-left: 0rpx;
margin-right: 12rpx;
}
}
&_active {
background-color: #fdf5e9;
}
}
2025-12-08 18:10:51 +08:00
2025-11-07 09:56:20 +08:00
.notice_message_container {
@include ellipsisWithLine(2);
text-align: center;
2026-02-09 07:29:02 +08:00
padding: 24rpx 48rpx;
word-break: break-word;
2025-11-07 09:56:20 +08:00
// font-size: 24rpx;
font-size: 0.85rem;
2026-02-09 07:29:02 +08:00
text-align: center;
2025-11-07 09:56:20 +08:00
color: #999;
2026-02-09 07:29:02 +08:00
width: 100%;
box-sizing: border-box;
2025-11-07 09:56:20 +08:00
position: relative;
}
.fade-leave,
.fade-enter-to {
opacity: 1;
}
.fade-leave-active,
.fade-enter-active {
transition: all 0.5s;
}
.fade-leave-to,
.fade-enter {
opacity: 0;
}
</style>