|
@@ -1,33 +1,27 @@
|
|
|
<template>
|
|
|
- <div
|
|
|
- class="message-audio"
|
|
|
- :class="[data.message.flow === 'out' && 'reserve']"
|
|
|
- @click.stop="play"
|
|
|
- :style="`width: ${data?.second * 10 + 40}Px`"
|
|
|
- >
|
|
|
- <i
|
|
|
- class="icon icon-voice"
|
|
|
- :class="[data.message.flow === 'out' && 'icon-reserve']"
|
|
|
- ></i>
|
|
|
- <label>{{ data.second }}s</label>
|
|
|
- <audio ref="audio" :src="data.url"></audio>
|
|
|
+ <div class="message-audio" :class="[data.message.flow === 'out' && 'reserve']" @click.stop="play" :style="`width: ${data?.second * 10 + 40}Px`">
|
|
|
+ <i class="icon icon-voice" :class="[data.message.flow === 'out' && 'icon-reserve', data.message.isPlay ? 'icon-voice-active' : '']"></i>
|
|
|
+ <!-- 消息时间不到1s,默认显示1s -->
|
|
|
+ <label>{{ data.second ? data.second : 1 }}s</label>
|
|
|
+ <audio ref="audio" :src="data.url" @pause="onStopAnimation" @ended="onStopAnimation"></audio>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts">
|
|
|
-import { defineComponent, watch, reactive, toRefs, ref } from 'vue';
|
|
|
+import { defineComponent, watch, reactive, toRefs, ref } from "vue";
|
|
|
|
|
|
export default defineComponent({
|
|
|
props: {
|
|
|
data: {
|
|
|
type: Object,
|
|
|
- default: () => ({})
|
|
|
- }
|
|
|
+ default: () => ({}),
|
|
|
+ },
|
|
|
},
|
|
|
setup(props: any, ctx: any) {
|
|
|
const data = reactive({
|
|
|
- data: {},
|
|
|
- show: false
|
|
|
+ data: {} as any,
|
|
|
+ show: false,
|
|
|
+ isPlay: false, // 是否在播放
|
|
|
});
|
|
|
|
|
|
const audio = ref(null);
|
|
@@ -41,35 +35,48 @@ export default defineComponent({
|
|
|
);
|
|
|
|
|
|
const play = () => {
|
|
|
- const audios = document.getElementsByTagName('audio');
|
|
|
+ const audios = document.getElementsByTagName("audio");
|
|
|
for (const audio of audios) {
|
|
|
if (!audio.paused) {
|
|
|
+ const parentNode: any = audio.parentNode;
|
|
|
+ parentNode.querySelector(".icon-voice").classList.remove("icon-voice-active");
|
|
|
audio.pause();
|
|
|
audio.load();
|
|
|
}
|
|
|
}
|
|
|
const audioPlayer: any = audio.value;
|
|
|
+ const parentNode: any = audioPlayer.parentNode;
|
|
|
if (audioPlayer.paused) {
|
|
|
audioPlayer.play();
|
|
|
data.show = true;
|
|
|
+ parentNode.querySelector(".icon-voice").classList.add("icon-voice-active");
|
|
|
} else {
|
|
|
audioPlayer.pause();
|
|
|
audioPlayer.load();
|
|
|
data.show = false;
|
|
|
+ parentNode.querySelector(".icon-voice").classList.remove("icon-voice-active");
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const onStopAnimation = (e: any) => {
|
|
|
+ const parentNode = e.target.parentNode;
|
|
|
+ if (parentNode) {
|
|
|
+ parentNode.querySelector(".icon-voice").classList.remove("icon-voice-active");
|
|
|
}
|
|
|
};
|
|
|
|
|
|
return {
|
|
|
...toRefs(data),
|
|
|
audio,
|
|
|
- play
|
|
|
+ play,
|
|
|
+ onStopAnimation,
|
|
|
};
|
|
|
- }
|
|
|
+ },
|
|
|
});
|
|
|
</script>
|
|
|
<style lang="scss" scoped>
|
|
|
-@import url('../../../styles/common.scss');
|
|
|
-@import url('../../../styles/icon.scss');
|
|
|
+@import url("../../../styles/common.scss");
|
|
|
+@import url("../../../styles/icon.scss");
|
|
|
.message-audio {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
@@ -78,7 +85,7 @@ export default defineComponent({
|
|
|
max-width: 100%;
|
|
|
overflow: hidden;
|
|
|
.icon {
|
|
|
- margin: 0 4Px;
|
|
|
+ margin: 0 4px;
|
|
|
}
|
|
|
audio {
|
|
|
width: 0;
|