Files
im-uniapp/pages/conversation/chating/components/MessageItem/VoiceMessageRender.vue
2025-09-05 15:24:42 +08:00

105 lines
2.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="voice-message" @click="playVoice">
<image
:src="isPlaying ? audioIcon : recordIcon"
:class="['audio-icon', { 'flipped': isSender }]"
mode="aspectFit"
/>
<text class="duration">{{ durationText }}</text>
</view>
</template>
<script>
export default {
props: {
source: {
type: Object,
required: true
},
isSender: {
type: Boolean,
default: false
}
},
computed: {
durationText() {
const d = this.source && this.source.soundElem && this.source.soundElem.duration;
return d ? `${d}''` : '';
}
},
data() {
return {
innerAudioContext: null,
isPlaying: false,
audioIcon: '/static/images/chating_footer_audio.png',
recordIcon: '/static/images/chating_footer_recording.png'
};
},
methods: {
getFixedSourceUrl(url) {
// 如果 url 以 http://49.232.154.205/api/object/ 开头,则替换为带端口的
// 或者 url 以 http://47.117.71.33/api/object/ 开头也替换为http://49.232.154.205:10006/api/object/
if (typeof url === 'string' && url.startsWith('http://49.232.154.205/api/object/')) {
return url.replace('http://49.232.154.205/api/object/', 'http://49.232.154.205:10006/api/object/');
}
else if (typeof url === 'string' && url.startsWith('http://47.117.71.33/api/object/')) {
return url.replace('http://47.117.71.33/api/object/', 'http://49.232.154.205:10006/api/object/');
}
return url;
},
playVoice() {
if (this.innerAudioContext) {
this.innerAudioContext.stop();
this.innerAudioContext.destroy();
this.innerAudioContext = null;
}
this.innerAudioContext = uni.createInnerAudioContext();
const rawUrl = this.source && this.source.soundElem && this.source.soundElem.sourceUrl || '';
this.innerAudioContext.src = this.getFixedSourceUrl(rawUrl);
this.isPlaying = true;
this.innerAudioContext.play();
this.innerAudioContext.onEnded(() => {
this.innerAudioContext.destroy();
this.innerAudioContext = null;
this.isPlaying = false;
});
this.innerAudioContext.onStop(() => {
this.isPlaying = false;
});
this.innerAudioContext.onError(() => {
this.isPlaying = false;
});
}
},
beforeDestroy() {
if (this.innerAudioContext) {
this.innerAudioContext.destroy();
this.innerAudioContext = null;
}
}
};
</script>
<style scoped>
.voice-message {
display: flex;
align-items: center;
cursor: pointer;
background: #f5f6fa;
border-radius: 18px;
padding: 8px 16px;
margin: 4px 0;
}
.audio-icon {
width: 28px;
height: 28px;
}
.flipped {
transform: rotate(180deg);
}
.duration {
margin-left: 8px;
color: #666;
font-size: 15px;
}
</style>