消息列表优化
This commit is contained in:
92
pages/im/components/sentText.nvue
Normal file
92
pages/im/components/sentText.nvue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<view class="text">
|
||||
<input class="input" type="text" v-model="inputTxt" confirm-type="send" @confirm="sent" cursor-spacing="10" />
|
||||
<button class="button" size="mini" :disabled="disabled" @click="sent">发送</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import im from '@/utils/im/index.js'
|
||||
import * as RongIMLib from "@/uni_modules/RongCloud-IMWrapper/js_sdk/index"
|
||||
|
||||
export default {
|
||||
props: {
|
||||
conversationType: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
targetId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
inputTxt: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabled() {
|
||||
return this.inputTxt.length === 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
RongIMLib.getTextMessageDraft(this.conversationType, this.targetId, ({
|
||||
draft
|
||||
}) => {
|
||||
draft ? this.inputTxt = draft : ''
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
RongIMLib.saveTextMessageDraft(this.conversationType, this.targetId, this.inputTxt, (res) => {
|
||||
console.log('销毁组件之前,保存草稿信息,但是没有执行', res);
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 发送文本消息
|
||||
sent() {
|
||||
if (!this.disabled) {
|
||||
RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId)
|
||||
im.sentText(this.conversationType, this.targetId, this.inputTxt, () => {
|
||||
setTimeout(() => {
|
||||
this.$emit('success')
|
||||
}, 500)
|
||||
this.inputTxt = ''
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.text {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.input {
|
||||
background: #F3F6FB;
|
||||
height: 70rpx;
|
||||
width: 460rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 15rpx;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.button {
|
||||
border: none;
|
||||
background: #34CE98;
|
||||
color: white;
|
||||
width: 120rpx;
|
||||
line-height: 70rpx;
|
||||
text-align: center;
|
||||
border-radius: 10rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.button[disabled] {
|
||||
background-color: #555555;
|
||||
}
|
||||
</style>
|
||||
136
pages/im/components/sentVoice.nvue
Normal file
136
pages/im/components/sentVoice.nvue
Normal file
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="voice" hover-class="chat-hover" @touchstart="startRecord" @touchend="stopRecord">
|
||||
<text class="button">按住说话</text>
|
||||
</view>
|
||||
<!-- 录音中提示 -->
|
||||
<view class="audio-transcribe" v-if="showRecordTip">
|
||||
<image class="audio-transcribe-src" src="@/static/icon/record-icon.png" mode="widthFix"></image>
|
||||
<text class="audio-transcribe-text">录音中 {{recordTime}} s</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import im from '@/utils/im/index.js'
|
||||
import permision from "@/js_sdk/wa-permission/permission.js"
|
||||
|
||||
export default {
|
||||
props: {
|
||||
conversationType: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
targetId: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showRecordTip: false,
|
||||
recordTime: 60,
|
||||
interval: 0,
|
||||
maxRecordTime: 60,
|
||||
recorderManager: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.recorderManager = uni.getRecorderManager()
|
||||
},
|
||||
methods: {
|
||||
// 检查安卓录制权限
|
||||
async getAndroidPermission() {
|
||||
return await permision.requestAndroidPermission('android.permission.RECORD_AUDIO')
|
||||
},
|
||||
// 录制语音消息
|
||||
startRecord() {
|
||||
this.getAndroidPermission().then(code => {
|
||||
switch (code) {
|
||||
case 1:
|
||||
this.showRecordTip = true
|
||||
this.recorderManager.start()
|
||||
this.interval = setInterval(() => {
|
||||
this.recordTime -= 1
|
||||
if (this.recordTime === 0) {
|
||||
this.stopRecord()
|
||||
}
|
||||
}, 1000)
|
||||
break;
|
||||
case 0:
|
||||
uni.showToast({
|
||||
title: '暂无麦克风权限,请前往应用设置开启麦克风',
|
||||
icon: 'none'
|
||||
})
|
||||
break;
|
||||
case -1:
|
||||
uni.showToast({
|
||||
title: '应用权限错误',
|
||||
icon: 'none'
|
||||
})
|
||||
break;
|
||||
}
|
||||
})
|
||||
},
|
||||
// 结束录音
|
||||
stopRecord(e) {
|
||||
if (!this.showRecordTip) return
|
||||
this.recorderManager.stop()
|
||||
clearInterval(this.interval)
|
||||
// 监听录音结束
|
||||
this.recorderManager.onStop(res => {
|
||||
im.sentVoice(this.conversationType, this.targetId, res.tempFilePath, (this.maxRecordTime - this
|
||||
.recordTime), () => {
|
||||
setTimeout(() => {
|
||||
this.$emit('success')
|
||||
}, 500)
|
||||
})
|
||||
this.recordTime = this.maxRecordTime
|
||||
this.showRecordTip = false
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.voice {
|
||||
background: #F3F6FB;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 460rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
||||
.button {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.audio-transcribe {
|
||||
background: rgba(0, 0, 0, .6);
|
||||
position: fixed;
|
||||
height: 200rpx;
|
||||
width: 300rpx;
|
||||
border-radius: 10rpx;
|
||||
z-index: 99;
|
||||
top: 550rpx;
|
||||
left: 225rpx;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.audio-transcribe-src {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
.audio-transcribe-text {
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
49
pages/im/components/showImage.nvue
Normal file
49
pages/im/components/showImage.nvue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<view class="im--img" :class="guest ? 'right': 'left'">
|
||||
<image class="src" :src="msg" @click="openImg" mode="widthFix"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'showImage',
|
||||
props: {
|
||||
msg: {
|
||||
type: String,
|
||||
default: 'https://images.pexels.com/photos/9024609/pexels-photo-9024609.jpeg'
|
||||
},
|
||||
guest: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openImg() {
|
||||
uni.previewImage({
|
||||
urls: [this.msg],
|
||||
current: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.im--img {
|
||||
padding: 19rpx;
|
||||
}
|
||||
|
||||
.im--img.left {
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.im--img.right {
|
||||
border-radius: 20rpx 0 20rpx 20rpx;
|
||||
background: #34CE98;
|
||||
}
|
||||
|
||||
.src {
|
||||
width: 240rpx;
|
||||
}
|
||||
</style>
|
||||
46
pages/im/components/showText.nvue
Normal file
46
pages/im/components/showText.nvue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<view class="im--box">
|
||||
<text class="im--text" :class="guest ? 'right': 'left'">{{msg}}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'showText',
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
props: {
|
||||
msg: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
guest: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.im--text {
|
||||
max-width: 400rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.im--text.left {
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.im--text.right {
|
||||
border-radius: 20rpx 0 20rpx 20rpx;
|
||||
background: #34CE98;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
98
pages/im/components/showVoice.nvue
Normal file
98
pages/im/components/showVoice.nvue
Normal file
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="im--audio" :class="guest ? 'right': 'left'" @click="onPlayMsg">
|
||||
<image v-if="!guest" class="audio-mp3" src="@/static/icon/audio_green.png" mode="widthFix"></image>
|
||||
<text class="audio-text">"{{msg.duration}}"</text>
|
||||
<image v-if="guest" class="audio-mp3" src="@/static/icon/audio_white.png" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'showVoice',
|
||||
props: {
|
||||
msg: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
local: '',
|
||||
remote: '',
|
||||
objectName: '',
|
||||
duration: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
guest: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 播放语音消息
|
||||
onPlayMsg() {
|
||||
uni.downloadFile({
|
||||
url: this.msg.remote,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
let innerAudioContext = uni.createInnerAudioContext()
|
||||
innerAudioContext.src = res.tempFilePath
|
||||
if (this.audioContextPaused) {
|
||||
innerAudioContext.play()
|
||||
this.audioContextPaused = false
|
||||
return
|
||||
}
|
||||
innerAudioContext.stop()
|
||||
innerAudioContext.onStop(resStop => {
|
||||
this.audioContextPaused = true
|
||||
})
|
||||
innerAudioContext.onError(err => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.im--audio {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 79rpx;
|
||||
width: 170rpx;
|
||||
padding: 0 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
,
|
||||
.im--audio.left {
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.im--audio.right {
|
||||
border-radius: 20rpx 0 20rpx 20rpx;
|
||||
background: #34CE98;
|
||||
}
|
||||
|
||||
.audio-mp3 {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
|
||||
.audio-text {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.im--audio.left .audio-text {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.im--audio.right .audio-text {
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user