|
|
|
@ -13,11 +13,11 @@ |
|
|
|
<div class="im-chat-box"> |
|
|
|
<ul> |
|
|
|
<li v-for="(msgInfo, idx) in chat.messages" :key="idx"> |
|
|
|
<chat-message-item v-if="idx >= showMinIdx" |
|
|
|
@call="onCall(msgInfo.type)" |
|
|
|
:mine="msgInfo.sendId == mine.id" |
|
|
|
:headImage="headImage(msgInfo)" :showName="showName(msgInfo)" :msgInfo="msgInfo" |
|
|
|
:groupMembers="groupMembers" @delete="deleteMessage" @recall="recallMessage"> |
|
|
|
<chat-message-item v-if="idx >= showMinIdx" @call="onCall(msgInfo.type)" |
|
|
|
:mine="msgInfo.sendId == mine.id" :headImage="headImage(msgInfo)" |
|
|
|
:showName="showName(msgInfo)" :msgInfo="msgInfo" |
|
|
|
:groupMembers="groupMembers" @delete="deleteMessage" |
|
|
|
@recall="recallMessage"> |
|
|
|
</chat-message-item> |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
@ -36,8 +36,8 @@ |
|
|
|
</file-upload> |
|
|
|
</div> |
|
|
|
<div title="发送文件"> |
|
|
|
<file-upload :action="'/file/upload'" :maxSize="10 * 1024 * 1024" @before="onFileBefore" |
|
|
|
@success="onFileSuccess" @fail="onFileFail"> |
|
|
|
<file-upload :action="'/file/upload'" :maxSize="10 * 1024 * 1024" |
|
|
|
@before="onFileBefore" @success="onFileSuccess" @fail="onFileFail"> |
|
|
|
<i class="el-icon-wallet"></i> |
|
|
|
</file-upload> |
|
|
|
</div> |
|
|
|
@ -49,6 +49,9 @@ |
|
|
|
<div title="语音通话" v-show="chat.type == 'PRIVATE'" class="el-icon-phone-outline" |
|
|
|
@click="showPrivateVideo('voice')"> |
|
|
|
</div> |
|
|
|
<div title="语音通话" v-show="chat.type == 'GROUP'" class="el-icon-phone-outline" |
|
|
|
@click="onGroupVideo()"> |
|
|
|
</div> |
|
|
|
<div title="视频通话" v-show="chat.type == 'PRIVATE'" class="el-icon-video-camera" |
|
|
|
@click="showPrivateVideo('video')"> |
|
|
|
</div> |
|
|
|
@ -57,9 +60,10 @@ |
|
|
|
<div class="send-content-area"> |
|
|
|
<div contenteditable="true" v-show="!sendImageUrl" ref="editBox" class="send-text-area" |
|
|
|
:disabled="lockMessage" @paste.prevent="onEditorPaste" |
|
|
|
@compositionstart="onEditorCompositionStart" @compositionend="onEditorCompositionEnd" |
|
|
|
@input="onEditorInput" :placeholder="placeholder" @blur="onEditBoxBlur()" |
|
|
|
@keydown.down="onKeyDown" @keydown.up="onKeyUp" @keydown.enter.prevent="onKeyEnter">x |
|
|
|
@compositionstart="onEditorCompositionStart" |
|
|
|
@compositionend="onEditorCompositionEnd" @input="onEditorInput" |
|
|
|
:placeholder="placeholder" @blur="onEditBoxBlur()" @keydown.down="onKeyDown" |
|
|
|
@keydown.up="onKeyUp" @keydown.enter.prevent="onKeyEnter">x |
|
|
|
</div> |
|
|
|
|
|
|
|
<div v-show="sendImageUrl" class="send-image-area"> |
|
|
|
@ -85,22 +89,27 @@ |
|
|
|
<chat-at-box ref="atBox" :ownerId="group.ownerId" :members="groupMembers" :search-text="atSearchText" |
|
|
|
@select="onAtSelect"></chat-at-box> |
|
|
|
<chat-voice :visible="showVoice" @close="closeVoiceBox" @send="onSendVoice"></chat-voice> |
|
|
|
<chat-history :visible="showHistory" :chat="chat" :friend="friend" :group="group" :groupMembers="groupMembers" |
|
|
|
@close="closeHistoryBox"></chat-history> |
|
|
|
<group-member-selector ref="rtcSel" :groupId="group.id" @complete="onInviteOk"></group-member-selector> |
|
|
|
<rtc-group-join ref="rtcJoin" :groupId="group.id"></rtc-group-join> |
|
|
|
<chat-history :visible="showHistory" :chat="chat" :friend="friend" :group="group" |
|
|
|
:groupMembers="groupMembers" @close="closeHistoryBox"></chat-history> |
|
|
|
</el-container> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import ChatGroupSide from "./ChatGroupSide.vue"; |
|
|
|
import ChatMessageItem from "./ChatMessageItem.vue"; |
|
|
|
import FileUpload from "../common/FileUpload.vue"; |
|
|
|
import Emotion from "../common/Emotion.vue"; |
|
|
|
import ChatVoice from "./ChatVoice.vue"; |
|
|
|
import ChatHistory from "./ChatHistory.vue"; |
|
|
|
import ChatAtBox from "./ChatAtBox.vue" |
|
|
|
|
|
|
|
export default { |
|
|
|
import ChatGroupSide from "./ChatGroupSide.vue"; |
|
|
|
import ChatMessageItem from "./ChatMessageItem.vue"; |
|
|
|
import FileUpload from "../common/FileUpload.vue"; |
|
|
|
import Emotion from "../common/Emotion.vue"; |
|
|
|
import ChatVoice from "./ChatVoice.vue"; |
|
|
|
import ChatHistory from "./ChatHistory.vue"; |
|
|
|
import ChatAtBox from "./ChatAtBox.vue" |
|
|
|
import GroupMemberSelector from "../group/GroupMemberSelector.vue" |
|
|
|
import RtcGroupJoin from "../rtc/RtcGroupJoin.vue" |
|
|
|
|
|
|
|
|
|
|
|
export default { |
|
|
|
name: "chatPrivate", |
|
|
|
components: { |
|
|
|
ChatMessageItem, |
|
|
|
@ -109,7 +118,9 @@ export default { |
|
|
|
Emotion, |
|
|
|
ChatVoice, |
|
|
|
ChatHistory, |
|
|
|
ChatAtBox |
|
|
|
ChatAtBox, |
|
|
|
GroupMemberSelector, |
|
|
|
RtcGroupJoin |
|
|
|
}, |
|
|
|
props: { |
|
|
|
chat: { |
|
|
|
@ -137,18 +148,18 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
moveChatToTop(){ |
|
|
|
moveChatToTop() { |
|
|
|
let chatIdx = this.$store.getters.findChatIdx(this.chat); |
|
|
|
this.$store.commit("moveTop",chatIdx); |
|
|
|
this.$store.commit("moveTop", chatIdx); |
|
|
|
}, |
|
|
|
closeRefBox() { |
|
|
|
this.$refs.emoBox.close(); |
|
|
|
this.$refs.atBox.close(); |
|
|
|
}, |
|
|
|
onCall(type){ |
|
|
|
if(type == this.$enums.MESSAGE_TYPE.RT_VOICE){ |
|
|
|
onCall(type) { |
|
|
|
if (type == this.$enums.MESSAGE_TYPE.RT_VOICE) { |
|
|
|
this.showPrivateVideo('voice'); |
|
|
|
}else if(type == this.$enums.MESSAGE_TYPE.RT_VIDEO){ |
|
|
|
} else if (type == this.$enums.MESSAGE_TYPE.RT_VIDEO) { |
|
|
|
this.showPrivateVideo('video'); |
|
|
|
} |
|
|
|
}, |
|
|
|
@ -256,13 +267,13 @@ export default { |
|
|
|
return sendText; |
|
|
|
}, |
|
|
|
html2Escape(strHtml) { |
|
|
|
return strHtml.replace(/[<>&"]/g, function (c) { |
|
|
|
return strHtml.replace(/[<>&"]/g, function(c) { |
|
|
|
return { |
|
|
|
'<': '<', |
|
|
|
'>': '>', |
|
|
|
'&': '&', |
|
|
|
'"': '"' |
|
|
|
}[c]; |
|
|
|
} [c]; |
|
|
|
}); |
|
|
|
}, |
|
|
|
createAtUserIds() { |
|
|
|
@ -276,7 +287,7 @@ export default { |
|
|
|
}, |
|
|
|
onEditorPaste(e) { |
|
|
|
let txt = e.clipboardData.getData('Text') |
|
|
|
if (typeof (txt) == 'string') { |
|
|
|
if (typeof(txt) == 'string') { |
|
|
|
let range = window.getSelection().getRangeAt(0) |
|
|
|
let textNode = document.createTextNode(txt); |
|
|
|
range.insertNode(textNode) |
|
|
|
@ -457,7 +468,48 @@ export default { |
|
|
|
offer: "", |
|
|
|
state: this.$enums.RTC_STATE.WAIT_CALL |
|
|
|
} |
|
|
|
this.$store.commit("setRtcInfo",rtcInfo); |
|
|
|
this.$store.commit("setRtcInfo", rtcInfo); |
|
|
|
}, |
|
|
|
onGroupVideo() { |
|
|
|
this.$http({ |
|
|
|
url: "/webrtc/group/info?groupId=" + this.group.id, |
|
|
|
method: 'GET' |
|
|
|
}).then((rtcInfo) => { |
|
|
|
if (rtcInfo.isChating) { |
|
|
|
// 已在通话中,可以直接加入通话 |
|
|
|
this.$refs.rtcJoin.open(rtcInfo); |
|
|
|
} else { |
|
|
|
// 邀请成员发起通话 |
|
|
|
let ids = [this.mine.id]; |
|
|
|
let maxChannel = this.$store.state.configStore.webrtc.maxChannel; |
|
|
|
this.$refs.rtcSel.open(maxChannel, ids, ids); |
|
|
|
|
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
}, |
|
|
|
onInviteOk(members) { |
|
|
|
if(members.length < 2){ |
|
|
|
return; |
|
|
|
} |
|
|
|
let userInfos = []; |
|
|
|
members.forEach(m => { |
|
|
|
userInfos.push({ |
|
|
|
id: m.userId, |
|
|
|
nickName: m.aliasName, |
|
|
|
headImage: m.headImage, |
|
|
|
isCamera: false, |
|
|
|
isMicroPhone: true |
|
|
|
}) |
|
|
|
}) |
|
|
|
let rtcInfo = { |
|
|
|
isHost: true, |
|
|
|
groupId: this.group.id, |
|
|
|
inviterId: this.mine.id, |
|
|
|
userInfos: userInfos |
|
|
|
} |
|
|
|
// 通过home.vue打开多人视频窗口 |
|
|
|
this.$eventBus.$emit("openGroupVideo", rtcInfo); |
|
|
|
}, |
|
|
|
showHistoryBox() { |
|
|
|
this.showHistory = true; |
|
|
|
@ -615,7 +667,7 @@ export default { |
|
|
|
this.$http({ |
|
|
|
url: url, |
|
|
|
method: 'put' |
|
|
|
}).then(() => { }) |
|
|
|
}).then(() => {}) |
|
|
|
}, |
|
|
|
loadReaded(fId) { |
|
|
|
this.$http({ |
|
|
|
@ -688,13 +740,13 @@ export default { |
|
|
|
div.scrollTop = div.scrollHeight; |
|
|
|
}); |
|
|
|
}, |
|
|
|
refreshPlaceHolder(){ |
|
|
|
refreshPlaceHolder() { |
|
|
|
console.log("placeholder") |
|
|
|
if(this.isReceipt){ |
|
|
|
if (this.isReceipt) { |
|
|
|
this.placeholder = "【回执消息】" |
|
|
|
}else if(this.$refs.editBox && this.$refs.editBox.innerHTML){ |
|
|
|
} else if (this.$refs.editBox && this.$refs.editBox.innerHTML) { |
|
|
|
this.placeholder = "" |
|
|
|
}else{ |
|
|
|
} else { |
|
|
|
this.placeholder = "聊点什么吧~"; |
|
|
|
} |
|
|
|
|
|
|
|
@ -769,11 +821,11 @@ export default { |
|
|
|
let div = document.getElementById("chatScrollBox"); |
|
|
|
div.addEventListener('scroll', this.onScroll) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<style lang="scss"> |
|
|
|
.chat-box { |
|
|
|
.chat-box { |
|
|
|
position: relative; |
|
|
|
width: 100%; |
|
|
|
background: #f8f8f8; |
|
|
|
@ -786,6 +838,7 @@ export default { |
|
|
|
font-size: 20px; |
|
|
|
font-weight: 600; |
|
|
|
border-bottom: 1px #ddd solid; |
|
|
|
|
|
|
|
.btn-side { |
|
|
|
position: absolute; |
|
|
|
right: 20px; |
|
|
|
@ -799,6 +852,7 @@ export default { |
|
|
|
.im-chat-main { |
|
|
|
padding: 0; |
|
|
|
background-color: #f8f8f8; |
|
|
|
|
|
|
|
.im-chat-box { |
|
|
|
>ul { |
|
|
|
padding: 0 20px; |
|
|
|
@ -825,6 +879,7 @@ export default { |
|
|
|
border-top: #ccc solid 1px; |
|
|
|
padding: 2px; |
|
|
|
background-color: #E8F2FF; |
|
|
|
|
|
|
|
>div { |
|
|
|
font-size: 22px; |
|
|
|
cursor: pointer; |
|
|
|
@ -934,4 +989,5 @@ export default { |
|
|
|
border: #dddddd solid 1px; |
|
|
|
animation: rtl-drawer-in .3s 1ms; |
|
|
|
} |
|
|
|
}</style> |
|
|
|
} |
|
|
|
</style> |