AudioMessageRender.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <template>
  2. <view
  3. @click="playAudio"
  4. class="audio_message_container bg_container"
  5. :class="{ audio_message_container_self: isSender }"
  6. >
  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">{{ message.soundElem.duration }}''</text>
  13. </view>
  14. </template>
  15. <script>
  16. import { secFormat } from "../../../../../util/imCommon";
  17. export default {
  18. name: "AudioMessageRender",
  19. props: {
  20. isSender: Boolean,
  21. message: Object,
  22. },
  23. data() {
  24. return {
  25. playing: false,
  26. paused: false,
  27. innerAudioContext: uni.createInnerAudioContext(),
  28. };
  29. },
  30. mounted() {
  31. this.setPlayListener();
  32. },
  33. beforeDestroy() {
  34. this.innerAudioContext.destroy();
  35. },
  36. methods: {
  37. setPlayListener() {
  38. const onPlayHandler = () => {
  39. this.playing = true;
  40. this.paused = false;
  41. };
  42. const onPauseOrStorHandler = () => {
  43. this.playing = false;
  44. this.paused = true;
  45. };
  46. this.innerAudioContext.onPlay(onPlayHandler);
  47. this.innerAudioContext.onPause(onPauseOrStorHandler);
  48. // this.innerAudioContext.onStop(onPauseOrStorHandler)
  49. this.innerAudioContext.onEnded(onPauseOrStorHandler);
  50. },
  51. playAudio() {
  52. this.setPlayListener();
  53. if (this.paused) {
  54. this.innerAudioContext.play();
  55. return;
  56. }
  57. if (this.playing) {
  58. this.innerAudioContext.pause();
  59. return;
  60. }
  61. this.innerAudioContext.src = this.message.soundElem.sourceUrl;
  62. this.innerAudioContext.play();
  63. },
  64. },
  65. };
  66. </script>
  67. <style lang="scss" scoped>
  68. .audio_message_container {
  69. @include vCenterBox();
  70. .audio_duration {
  71. font-size: 28rpx;
  72. }
  73. .cricleplay {
  74. display: flex;
  75. align-items: center;
  76. margin-right: 12rpx;
  77. .small {
  78. width: 5px;
  79. height: 5px;
  80. border-style: solid;
  81. border-color: #3870e4;
  82. border-top-color: transparent;
  83. border-left-color: transparent;
  84. border-bottom-color: transparent;
  85. border-radius: 50%;
  86. box-sizing: border-box;
  87. vertical-align: middle;
  88. display: inline-block;
  89. }
  90. .middle {
  91. width: 10px;
  92. height: 10px;
  93. border-style: solid;
  94. border-color: #3870e4;
  95. border-top-color: transparent;
  96. border-left-color: transparent;
  97. border-bottom-color: transparent;
  98. border-radius: 50%;
  99. box-sizing: border-box;
  100. vertical-align: middle;
  101. display: inline-block;
  102. margin-left: -5px;
  103. animation: show2 2s ease-in-out infinite;
  104. opacity: 1;
  105. }
  106. @keyframes show2 {
  107. 0% {
  108. opacity: 0;
  109. }
  110. 30% {
  111. opacity: 1;
  112. }
  113. 100% {
  114. opacity: 0;
  115. }
  116. }
  117. .large {
  118. width: 20px;
  119. height: 20px;
  120. border-style: solid;
  121. border-color: #3870e4;
  122. border-top-color: transparent;
  123. border-left-color: transparent;
  124. border-bottom-color: transparent;
  125. border-radius: 50%;
  126. box-sizing: border-box;
  127. vertical-align: middle;
  128. display: inline-block;
  129. margin-left: -15px;
  130. animation: show3 2s ease-in-out infinite;
  131. opacity: 1;
  132. }
  133. @keyframes show3 {
  134. 0% {
  135. opacity: 0;
  136. }
  137. 60% {
  138. opacity: 1;
  139. }
  140. 100% {
  141. opacity: 0;
  142. }
  143. }
  144. .stopanimate {
  145. -moz-animation-name: none;
  146. -webkit-animation-name: none;
  147. -ms-animation-name: none;
  148. animation-name: none;
  149. }
  150. }
  151. &_self {
  152. flex-direction: row-reverse;
  153. .cricleplay {
  154. margin-right: 0;
  155. margin-left: 12rpx;
  156. flex-direction: row-reverse;
  157. .small,
  158. .middle,
  159. .large {
  160. border-left-color: #3870e4;
  161. border-right-color: transparent;
  162. }
  163. .middle {
  164. margin-left: 0;
  165. margin-right: -5px;
  166. }
  167. .large {
  168. margin-left: 0;
  169. margin-right: -15px;
  170. }
  171. }
  172. }
  173. }
  174. .bg_container {
  175. padding: 16rpx 24rpx;
  176. border-radius: 0rpx 12rpx 12rpx 12rpx;
  177. background-color: #f0f0f0;
  178. }
  179. </style>