MassMessageRender.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <template>
  2. <view class="text_message_container bg_container" v-if="isText">
  3. <mp-html :previewImg="false" :showImgMenu="false" :lazyLoad="false" :content="getContent" />
  4. </view>
  5. <view @click="playAudio" class="audio_message_container bg_container"
  6. :class="{ audio_message_container_self: isSender }" v-else>
  7. <view class="cricleplay">
  8. <view class="small"></view>
  9. <view class="middle" :class="{ stopanimate: !playing }"></view>
  10. <view class="large" :class="{ stopanimate: !playing }"></view>
  11. </view>
  12. <text class="audio_duration">{{ data.soundElem.duration }}''</text>
  13. </view>
  14. </template>
  15. <script>
  16. export default {
  17. name: "MassMessageRender",
  18. props: {
  19. isSender: Boolean,
  20. data: Object,
  21. },
  22. data() {
  23. return {
  24. playing: false,
  25. paused: false,
  26. innerAudioContext: uni.createInnerAudioContext(),
  27. };
  28. },
  29. mounted() {
  30. this.setPlayListener();
  31. },
  32. beforeDestroy() {
  33. this.innerAudioContext.destroy();
  34. },
  35. computed: {
  36. isText() {
  37. return this.data.textElem !== null
  38. },
  39. getContent() {
  40. if (this.isText) {
  41. return this.data.textElem.content
  42. }
  43. },
  44. },
  45. methods: {
  46. setPlayListener() {
  47. const onPlayHandler = () => {
  48. this.playing = true;
  49. this.paused = false;
  50. };
  51. const onPauseOrStorHandler = () => {
  52. this.playing = false;
  53. this.paused = true;
  54. };
  55. this.innerAudioContext.onPlay(onPlayHandler);
  56. this.innerAudioContext.onPause(onPauseOrStorHandler);
  57. this.innerAudioContext.onEnded(onPauseOrStorHandler);
  58. },
  59. playAudio() {
  60. this.setPlayListener();
  61. if (this.paused) {
  62. this.innerAudioContext.play();
  63. return;
  64. }
  65. if (this.playing) {
  66. this.innerAudioContext.pause();
  67. return;
  68. }
  69. this.innerAudioContext.src = this.data.soundElem.sourceUrl;
  70. this.innerAudioContext.play();
  71. },
  72. }
  73. };
  74. </script>
  75. <style lang="scss" scoped>
  76. .bg_container {
  77. padding: 18rpx 24rpx;
  78. border-radius: 0rpx 12rpx 12rpx 12rpx;
  79. background-color: #ffffff;
  80. }
  81. .audio_message_container {
  82. display: flex;
  83. flex-direction: row;
  84. align-items: center;
  85. }
  86. .audio_duration {
  87. font-size: 28rpx;
  88. }
  89. .cricleplay {
  90. display: flex;
  91. flex-direction: row;
  92. align-items: center;
  93. margin-right: 12rpx;
  94. }
  95. .cricleplay_small {
  96. width: 5px;
  97. height: 5px;
  98. border-width: 1px; /* Default border width if needed, or specific border widths below */
  99. border-style: solid;
  100. border-color: #3870e4;
  101. border-top-color: transparent;
  102. border-left-color: transparent;
  103. border-bottom-color: transparent;
  104. border-radius: 50%;
  105. }
  106. .cricleplay_middle {
  107. width: 10px;
  108. height: 10px;
  109. border-width: 1px;
  110. border-style: solid;
  111. border-color: #3870e4;
  112. border-top-color: transparent;
  113. border-left-color: transparent;
  114. border-bottom-color: transparent;
  115. border-radius: 50%;
  116. margin-left: -5px;
  117. opacity: 1;
  118. }
  119. .cricleplay_large {
  120. width: 20px;
  121. height: 20px;
  122. border-width: 1px;
  123. border-style: solid;
  124. border-color: #3870e4;
  125. border-top-color: transparent;
  126. border-left-color: transparent;
  127. border-bottom-color: transparent;
  128. border-radius: 50%;
  129. margin-left: -15px;
  130. opacity: 1;
  131. }
  132. .stopanimate {
  133. opacity: 0.5;
  134. }
  135. .audio_message_container_self {
  136. flex-direction: row-reverse;
  137. }
  138. /* Helper classes for self alignment if needed, or just rely on flex-direction: row-reverse */
  139. .cricleplay_self {
  140. margin-right: 0;
  141. margin-left: 12rpx;
  142. flex-direction: row-reverse;
  143. }
  144. .cricleplay_small_self,
  145. .cricleplay_middle_self,
  146. .cricleplay_large_self {
  147. border-left-color: #3870e4;
  148. border-right-color: transparent;
  149. }
  150. .cricleplay_middle_self {
  151. margin-left: 0;
  152. margin-right: -5px;
  153. }
  154. .cricleplay_large_self {
  155. margin-left: 0;
  156. margin-right: -15px;
  157. }
  158. </style>