<template>
|
<view class="uni-panel-msg-item">
|
<view v-if="msgData.time" class="msg-whichday">
|
<text class="msg-whichday-text">{{msgData.time}}</text>
|
</view>
|
<view class="clearfix" style="position: relative;padding-bottom: 10px;">
|
<view v-if="msgData.self" class="uni-panel-msg-my">
|
<view class="uni-panel-msg-my-left">
|
<!-- #ifdef MP-WEIXIN -->
|
<circleProgressBar v-if="msgData.sendingMsg" class="uni-panel-msg-progress" :size="60"
|
:border_width="10" border_back_color='#ccc' background='#ffffff80'
|
:pro="msgData.percentSend/100"></circleProgressBar>
|
<!-- #endif-->
|
<view v-if="msgData.failedMsg" class="uni-panel-msg-wrong"><text
|
class="uni-panel-msg-wrong-ico fs-wrong"></text></view>
|
<view class="rightBubble"
|
:style="(msgData.isMedia && msgData.mediaType=='video')?'background-color: transparent':''">
|
<view class="uni-panel-msg-content ">
|
<view v-if="msgData.isMedia && msgData.mediaType=='audio'" class="voice" @click="playVoice">
|
<view style="margin-right: 8px;">{{msgData.mediaLen? msgData.mediaLen + "''" :""}}
|
</view>
|
<view style="font-size: 18px;"
|
:class="[{'play-my':playMsgid==msgData.ID },'fu-shengyin2','play-icon']"></view>
|
</view>
|
<view v-else-if="msgData.isMedia && msgData.mediaType=='video'"
|
style="border: 1px solid #ccc;border-radius: 5px;">
|
<jvideo :isTransit="msgData.sendingMsg" :poster="msgData.mediaPoster"
|
:url="msgData.mediaSrc" :width="msgData.mediaWidth+ 'px'"
|
:height="msgData.mediaHeight+ 'px'" :len="msgData.mediaLen || 0" @play="playVideo">
|
</jvideo>
|
</view>
|
<rich-text v-for="(item,index) in contentUrl" :key="index" preview="true" @click="previewImage"
|
:data-nodes="[item]" :nodes="[item]"></rich-text>
|
</view>
|
<text v-if="(!msgData.isMedia || msgData.mediaType !='video')" class="bottomLevel"></text>
|
<text v-if="(!msgData.isMedia || msgData.mediaType !='video')" class="topLevel"></text>
|
</view>
|
</view>
|
<view class="uni-panel-msg-my-right">
|
<image class="uni-panel-msg-user-image" :src="msgData.imgurl" mode="widthFix"
|
@error="imageUserError"></image>
|
</view>
|
</view>
|
<view v-if="!msgData.self" class="uni-panel-msg-other">
|
<view class="uni-panel-msg-other-left">
|
<image class="uni-panel-msg-user-image" :src="msgData.imgurl" mode="widthFix"
|
@error="imageUserError"></image>
|
</view>
|
<view class="uni-panel-msg-other-right">
|
<view class="uni-panel-msg-username">
|
{{msgData.CreatorName}}
|
</view>
|
<view class="leftBubble"
|
:style="(msgData.isMedia && msgData.mediaType=='video')?'background-color: transparent':''">
|
<view class="uni-panel-msg-content ">
|
<view v-if="msgData.isMedia && msgData.mediaType=='audio'" class="voice" @click="playVoice">
|
<view style="font-size: 18px; margin-right: 8px;"
|
:class="[{'play-other':(playMsgid==msgData.ID )},'fu-shengyin','play-icon']"></view>
|
<view>{{msgData.mediaLen? msgData.mediaLen + "''" :""}}</view>
|
</view>
|
<view v-else-if="msgData.isMedia && msgData.mediaType=='video'"
|
style="border: 1px solid #ccc;border-radius: 5px;" >
|
<jvideo :poster="msgData.mediaPoster" :url="msgData.mediaSrc"
|
:width="msgData.mediaWidth+ 'px'" :height="msgData.mediaHeight+ 'px'"
|
:len="msgData.mediaLen || 0" @play="playVideo"></jvideo>
|
<!-- <video show-play-btn="false" class="msg-video" :id="msgData.ID" :style="{'width':msgData.mediaWidth+ 'px','height':msgData.mediaHeight+ 'px'}" :src="msgData.mediaSrc" :poster="msgData.mediaPoster" @play="videoPlay" @fullscreenchange="fullscreenchange" @error="videoErrorCallback" /> -->
|
</view>
|
<rich-text v-for="(item,index) in contentUrl" :key="index" preview="true" @click="previewImage"
|
:data-nodes="[item]" :nodes="[item]"></rich-text>
|
<!-- <rich-text v-else @click="previewImage" :data-nodes="contentUrl" :nodes="contentUrl" ></rich-text> -->
|
</view>
|
<text v-if="(!msgData.isMedia || msgData.mediaType !='video')" class="bottomLevel"></text>
|
<text v-if="(!msgData.isMedia || msgData.mediaType !='video')" class="topLevel"></text>
|
</view>
|
</view>
|
</view>
|
|
</view>
|
</view>
|
</template>
|
|
<script>
|
import TaskInit from "@/common/extend.js"
|
import parseHtml from "@/common/htmlParse.js"
|
import circleProgressBar from '@/components/circle-progress-bar/circle-progress-bar.vue'
|
import jvideo from '@/components/j-video.vue'
|
import {
|
DOMParser
|
} from "xmldom"
|
export default {
|
name: "MsgItem",
|
components: {
|
circleProgressBar,
|
jvideo
|
},
|
emits: ['playVideo', 'playVoice', 'previewImage'],
|
props: {
|
msgData: {
|
type: Object,
|
default () {
|
return {};
|
}
|
},
|
playMsgid: {
|
type: String,
|
default () {
|
return "";
|
}
|
},
|
failedMsg: {
|
type: Boolean,
|
default () {
|
return false;
|
}
|
},
|
},
|
data() {
|
return {}
|
},
|
computed: {
|
//格式化内容
|
contentUrl() {
|
if (this.msgData.isMedia)
|
return []
|
|
let content = this.msgData.Content
|
// console.log("contentUrl",content)
|
if (content) {
|
let arContent = parseHtml(content)
|
if (arContent.length != 1) {
|
return arContent
|
}
|
if (arContent[0].name == "p") {
|
let childrens = arContent[0].children
|
return childrens
|
}
|
return arContent
|
} else
|
return []
|
},
|
//格式化易读日期
|
msgTime() {
|
let date = this.msgData.CreateTime
|
return TaskInit.dateUtils.openinfo_formatter_ttime(date, "notime")
|
}
|
},
|
onReady() {
|
|
},
|
methods: {
|
setData: function(obj) {
|
let that = this;
|
let keys = [];
|
let val, data;
|
|
Object.keys(obj).forEach(function(key) {
|
keys = key.split(".");
|
val = obj[key];
|
data = that.$data;
|
keys.forEach(function(key2, index) {
|
if (index + 1 == keys.length) {
|
that.$set(data, key2, val);
|
} else {
|
if (!data[key2]) {
|
that.$set(data, key2, {});
|
}
|
}
|
data = data[key2];
|
});
|
});
|
},
|
imageUserError() {
|
this.msgData.imgurl = getApp().globalData.defaultuserphoto
|
},
|
/**
|
* 播放语音触发
|
*/
|
playVoice() {
|
this.$emit('playVoice', this.msgData)
|
},
|
/**
|
* 播放视频
|
*/
|
playVideo() {
|
this.$emit('playVideo', this.msgData)
|
},
|
/**
|
* 预览图片触发
|
*/
|
previewImage(e) {
|
let nodes = e.currentTarget.dataset.nodes;
|
// console.log("previewImage", nodes)
|
let srcImg = this.getPreviewNodeImage(nodes)
|
let arrImg = [];
|
if (this.msgData.Content) {
|
let sDesc = this.msgData.Content
|
sDesc = sDesc.replace(/ /g, "")
|
// console.log("previewImg", sDesc)
|
let xmlDoc = new DOMParser().parseFromString(sDesc, "text/xml");
|
let finds = xmlDoc.getElementsByTagName('img'); //获取find节点
|
for (let i = 0; i < finds.length; i++) { //循环节点
|
let finder = finds[i];
|
let src = finder.getAttribute("src")
|
if (src)
|
arrImg.push(src)
|
}
|
if (arrImg.length > 0) {
|
if (srcImg == "") {
|
srcImg = arrImg[0]
|
}
|
console.log("arrImg:", arrImg.length, arrImg)
|
uni.previewImage({
|
current: srcImg,
|
urls: arrImg,
|
})
|
return;
|
}
|
}
|
if (srcImg != "") {
|
uni.previewImage({
|
current: srcImg,
|
urls: [srcImg],
|
})
|
}
|
},
|
getPreviewNodeImage(nodes) {
|
// console.log("previewNodeImage", nodes)
|
//遍历标签拼拿到你的图片的src里面的内容放在我们数组中
|
let srcImg = ""
|
for (var j = 0; j < nodes.length; j++) {
|
if (nodes[j].name == "p") {
|
if (nodes[j].children) {
|
srcImg = this.getPreviewNodeImage(nodes[j].children)
|
if (srcImg != "") {
|
break;
|
}
|
}
|
} else if (nodes[j].name == "img") {
|
srcImg = nodes[j].attrs.src;
|
if (srcImg != "") {
|
break;
|
}
|
}
|
}
|
return srcImg
|
},
|
|
videoErrorCallback(e) {
|
uni.showModal({
|
content: e.target.errMsg,
|
showCancel: false
|
})
|
},
|
videoPlay(e) {
|
console.log("videoPlay", e)
|
|
|
},
|
fullscreenchange(e) {
|
console.log("fullscreenchange", e)
|
|
}
|
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.uni-panel-msg-item {
|
display: flex;
|
width: 100%;
|
background-color: transparent;
|
flex-direction: column !important;
|
padding-top: 8px;
|
padding-bottom: 8px;
|
// min-height: 48px;
|
// overflow: hidden;
|
// overflow-y: auto;
|
|
|
.msg-whichday {
|
|
display: flex;
|
height: 24px;
|
margin: 5px 0px;
|
text-align: center;
|
background-color: transparent;
|
}
|
|
.msg-whichday-text {
|
justify-content: center;
|
align-items: center;
|
padding: 2px 8px;
|
margin: auto;
|
color: #fff;
|
background-color: #ccc;
|
border-radius: 4px;
|
}
|
|
.clearfix {
|
content: " ";
|
box-sizing: border-box;
|
}
|
|
.uni-panel-msg-other {
|
padding: 2px 8px;
|
display: flex;
|
min-height: 36px;
|
}
|
|
.uni-panel-msg-my {
|
padding: 2px 8px;
|
display: flex;
|
justify-content: flex-end;
|
min-height: 36px;
|
}
|
|
.uni-panel-msg-my-left {
|
display: flex;
|
flex-direction: row;
|
width: calc(100% - 100rpx);
|
min-height: 80rpx;
|
align-items: center;
|
justify-content: flex-end;
|
align-items: flex-end;
|
}
|
|
.uni-panel-msg-progress {
|
display: flex;
|
align-items: flex-end;
|
margin-right: 5px;
|
margin-bottom: 5px;
|
}
|
|
.uni-panel-msg-my-right {
|
margin-left: 15rpx;
|
flex-shrink: 0;
|
width: 80rpx;
|
height: 80rpx;
|
}
|
|
.uni-panel-msg-username {
|
width: 100%;
|
height: 45rpx;
|
font-size: 24rpx;
|
color: #999;
|
display: flex;
|
}
|
|
.uni-panel-msg-user-image {
|
width: 80rpx;
|
border-radius: 100%;
|
}
|
|
.uni-panel-msg-other-left {
|
margin-right: 15rpx;
|
flex-shrink: 0;
|
width: 80rpx;
|
height: 80rpx;
|
}
|
|
.uni-panel-msg-other-right {
|
flex-wrap: wrap;
|
display: flex;
|
}
|
|
.uni-panel-msg-wrong {
|
display: flex;
|
font-size: 14px;
|
color: #aa0000;
|
width: 20px;
|
height: 100%;
|
position: relative;
|
}
|
|
.uni-panel-msg-wrong-ico {
|
position: absolute;
|
bottom: 5px;
|
}
|
|
.leftBubble {
|
background-color: #fff;
|
color: #333;
|
max-width: 70%;
|
min-height: 50rpx;
|
border-radius: 10rpx;
|
padding: 15rpx 20rpx;
|
display: flex;
|
align-items: center;
|
font-size: 32rpx;
|
word-break: break-word;
|
position: relative;
|
}
|
|
.rightBubble {
|
background-color: #00aaff;
|
color: #fff;
|
max-width: 70%;
|
min-height: 50rpx;
|
border-radius: 10rpx;
|
padding: 15rpx 20rpx;
|
display: flex;
|
align-items: center;
|
font-size: 32rpx;
|
margin-right: 10px;
|
word-break: break-word;
|
position: relative;
|
}
|
|
.leftBubble .bottomLevel {
|
position: absolute;
|
bottom: calc(100% - 18px);
|
left: -14px;
|
border: 7px solid #ddd;
|
border-bottom: 7px solid transparent;
|
border-left: 7px solid transparent;
|
border-top: 7px solid transparent;
|
}
|
|
.leftBubble .topLevel {
|
position: absolute;
|
bottom: calc(100% - 18px);
|
left: -13px;
|
border: 7px solid #ffffff;
|
border-bottom: 7px solid transparent;
|
border-left: 7px solid transparent;
|
border-top: 7px solid transparent;
|
}
|
|
.rightBubble .bottomLevel {
|
position: absolute;
|
bottom: calc(100% - 27px);
|
right: -14px;
|
border: 7px solid #ddd;
|
border-right: 7px solid transparent;
|
border-bottom: 7px solid transparent;
|
border-top: 7px solid transparent;
|
}
|
|
.rightBubble .topLevel {
|
position: absolute;
|
bottom: calc(100% - 27px);
|
right: -13px;
|
border: 7px solid #00aaff;
|
border-right: 7px solid transparent;
|
border-bottom: 7px solid transparent;
|
border-top: 7px solid transparent;
|
}
|
|
.uni-panel-msg-content {
|
line-height: 50rpx;
|
font-size: 14px;
|
user-select: text;
|
min-height: 50rpx;
|
min-width: 50rpx;
|
align-items: center;
|
word-break: break-word;
|
}
|
|
@keyframes my-play {
|
0% {
|
transform: translateX(80%);
|
}
|
|
100% {
|
transform: translateX(0%); // rotate(180deg)
|
}
|
}
|
|
.play-my::after {
|
width: 50rpx;
|
height: 50rpx;
|
border-radius: 100%;
|
box-sizing: border-box;
|
position: absolute;
|
border-left: solid 10rpx rgba(0, 170, 255, .8);
|
animation: my-play 1s linear infinite;
|
content: " ";
|
}
|
|
@keyframes other-play {
|
0% {
|
transform: translateX(-80%);
|
}
|
|
100% {
|
transform: translateX(0%);
|
}
|
}
|
|
.play-icon {
|
display: flex;
|
align-items: center;
|
}
|
|
.play-other::after {
|
width: 50rpx;
|
height: 50rpx;
|
border-radius: 100%;
|
box-sizing: border-box;
|
position: absolute;
|
content: " ";
|
border-right: solid 10rpx rgba(255, 255, 255, .8);
|
animation: other-play 1s linear infinite;
|
|
}
|
|
.voice {
|
display: flex;
|
flex-direction: row;
|
}
|
|
.msg-video {
|
max-width: 100%;
|
max-height: 450px;
|
}
|
}
|
</style>
|