graceIMMsg.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <template name="graceIMMsg">
  2. <view class='grace-im'>
  3. <block v-for="(item, index) in msgs" :key="index">
  4. <block v-if="item.group == group">
  5. <!-- 文本消息 -->
  6. <view class="grace-im-msg"
  7. :class="[userid == item.uindex ? 'grace-im-msg-right' : 'grace-im-msg-left']"
  8. v-if="item.contentType == 'txt'">
  9. <view class="face"><image :src="item.uface" mode="widthFix"></image></view>
  10. <view class="grace-im-content-in">
  11. <view class="grace-im-name">{{item.uname}}</view>
  12. <view><view class="content">{{item.content}}</view></view>
  13. <view class="timer"><text>{{item.date}}</text></view>
  14. </view>
  15. </view>
  16. <!-- 图片消息 -->
  17. <view class="grace-im-msg"
  18. :class="[userid == item.uindex ? 'grace-im-msg-right' : 'grace-im-msg-left']"
  19. v-if="item.contentType == 'img'">
  20. <view class="face"><image :src="item.uface" mode="widthFix"></image></view>
  21. <view class="grace-im-content-in">
  22. <view class="grace-im-name">{{item.uname}}</view>
  23. <view>
  24. <view class="content img">
  25. <image :src="item.content" :data-img="item.content" @tap="showImgs" mode="widthFix"></image>
  26. </view>
  27. </view>
  28. <view class="timer"><text>{{item.date}}</text></view>
  29. </view>
  30. </view>
  31. <!-- 语音消息 -->
  32. <view class="grace-im-msg"
  33. :class="[userid == item.uindex ? 'grace-im-msg-right' : 'grace-im-msg-left']"
  34. v-if="item.contentType == 'voice'">
  35. <view class="face"><image :src="item.uface" mode="widthFix"></image></view>
  36. <view class="grace-im-content-in">
  37. <view class="grace-im-name">{{item.uname}}</view>
  38. <view>
  39. <view :class="['content', 'grace-im-voice-msg', index == playIndex ? 'grace-im-playing' : '']"
  40. :data-voice="item.content"
  41. :data-index='index' @tap='playVoice' :style="{'min-width':'50px', 'width':(item.length*3)+'px'}">
  42. <text class="graceIMFont icon-audio"></text>{{item.length}}"
  43. </view>
  44. </view>
  45. <view class="timer"><text>{{item.date}}</text></view>
  46. </view>
  47. </view>
  48. <!-- 系统消息 -->
  49. <view class="grace-im-msg" v-if="item.ctype == 'system'">
  50. <view class="grace-im-system-msg">{{item.msg}}</view>
  51. </view>
  52. <view></view>
  53. </block>
  54. </block>
  55. <view style="height:100px;"></view>
  56. </view>
  57. </template>
  58. <script>
  59. export default {
  60. name: "graceIMMsg",
  61. props: {
  62. msgs : {
  63. type : Array,
  64. default : function(){
  65. return []
  66. },
  67. },
  68. userid: {
  69. type: String,
  70. default:'',
  71. },
  72. scrollTop : {
  73. type: Number,
  74. default: 99999,
  75. },
  76. group :{
  77. type : String,
  78. default : ""
  79. }
  80. },
  81. data() {
  82. return {
  83. player : null,
  84. playIndex : -1
  85. }
  86. },
  87. created: function(){
  88. var _self = this;
  89. // #ifndef H5
  90. this.player = uni.getBackgroundAudioManager();
  91. this.player.onPlay(() => {});
  92. this.player.onEnded(function(){
  93. var cIndex = _self.playIndex;
  94. if(cIndex < 0){return false;}
  95. _self.playIndex = -1;
  96. for (var i = cIndex + 1; i < _self.msgs.length; i++) {
  97. if (_self.msgs[i].contentType == 'voice') {
  98. _self.playNow(_self.msgs[i].content, i);
  99. break;
  100. return;
  101. }
  102. }
  103. });
  104. // #endif
  105. },
  106. methods: {
  107. // 播放语音
  108. playVoice: function (e) {
  109. // #ifdef H5
  110. uni.showToast({title:"请使用 APP 或 小程序聆听语音", icon:"none"});
  111. return ;
  112. // #endif
  113. var voicelUrl = e.currentTarget.dataset.voice;
  114. var index = e.currentTarget.dataset.index;
  115. if (this.playIndex == -1){return this.playNow(voicelUrl, index);}
  116. var _self = this;
  117. if (this.playIndex == index) {
  118. wx.getBackgroundAudioPlayerState({
  119. success(res) {
  120. const status = res.status
  121. switch (status) {
  122. case 0:
  123. _self.player.play();
  124. break;
  125. case 1:
  126. _self.player.pause();
  127. break;
  128. default:
  129. _self.player.play();
  130. }
  131. }
  132. });
  133. } else {
  134. this.player.stop();
  135. this.playNow(voicelUrl, index);
  136. }
  137. },
  138. // 语音播放基础函数
  139. playNow: function (voicelUrl, index){
  140. this.playIndex = index;
  141. this.player.src = voicelUrl;
  142. this.player.title = "graceUI";
  143. return true;
  144. },
  145. // 图片预览
  146. showImgs : function(e){
  147. var imgs = [];
  148. var imgsCurrent = e.currentTarget.dataset.img;
  149. for (var i = 0; i < this.msgs.length; i++) {
  150. if (this.msgs[i].contentType == 'img') {
  151. imgs.push(this.msgs[i].content);
  152. }
  153. }
  154. wx.previewImage({urls : imgs, current : imgsCurrent});
  155. }
  156. }
  157. }
  158. </script>
  159. <style scoped>
  160. .grace-im{padding:0 10px;}
  161. .grace-im-system-msg{background:#C1C1C1; width:auto; color:#FFF; font-size:12px; line-height:1.5em; padding:5px 10px; margin:0 auto; display:inline-block; border-radius:3px;}
  162. .grace-im-msg{margin:15px 0; flex-wrap:nowrap; display:flex;}
  163. .grace-im-msg .face{width:44px; height:44px; overflow:hidden; flex-shrink:0;}
  164. .grace-im-msg .face image{width:44px; height:44px; border-radius:4px;}
  165. .grace-im-name{line-height:15px; height:15px; font-size:11px; color:#3688FF; text-indent:10px;}
  166. .grace-im-content-in{margin:0 5px; width:100%; overflow:hidden;}
  167. .grace-im-content-in > view{width:100%; overflow:hidden;}
  168. .grace-im-content-in .content{padding:8px 15px; margin-top:6px; background:#FFF; line-height:1.5em; border-radius:3px; word-break:break-all; display:inline-block; position:relative;}
  169. .grace-im-content-in .content::after{content:""; position:absolute; height:10px; width:10px; background:#FFFFFF; top:12px; transform: translate(0,-50%) rotate(45deg); z-index:2;}
  170. .grace-im-content-in .timer{margin-top:5px; line-height:15px;}
  171. .grace-im-content-in .timer text{font-size:10px; margin-left:10px; color:#8788A3;}
  172. .grace-im-msg-left .content{margin-left:10px;}
  173. .grace-im-msg-left .content::after{left:-4px;}
  174. .grace-im-msg-right .content{margin-right:10px;}
  175. .grace-im-msg-right .content::after{right:-4px; background:#00B26A;}
  176. .grace-im-msg-right{flex-direction:row-reverse;}
  177. .grace-im-msg-right .grace-im-name{display:none;}
  178. .grace-im-msg-right .content{float:right; background:#00B26A; color:#FFFFFF; margin-top:0;}
  179. .grace-im-msg-right .timer{text-align:right;}
  180. .grace-im-msg-right .timer text{text-align:right; margin-right:10px;}
  181. .grace-im-content-in .img{padding:0 !important; font-size:0; background:#FFF;}
  182. .grace-im-content-in .img::after{width:0 !important; height:0 !important;}
  183. .grace-im-content-in .img image{width:400upx; border-radius:5px;}
  184. .grace-im-voice-msg{font-size:10px; line-height:22px !important;}
  185. .grace-im-voice-msg text{font-size:20px;}
  186. .grace-im-playing{background:#007AFF !important; color:#FFF;}
  187. .grace-im-playing text{color:#FFF;}
  188. .grace-im-playing::after{background:#007AFF !important;}
  189. @font-face {
  190. font-family: "graceIMFont";
  191. src:url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAARIAAsAAAAABpAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY+dknyY21hcAAAAYAAAABKAAABcOkou6pnbHlmAAABzAAAAJgAAACcsQjN8WhlYWQAAAJkAAAALwAAADYTkbRlaGhlYQAAApQAAAAcAAAAJAfeA4NobXR4AAACsAAAAAgAAAAICAAAAGxvY2EAAAK4AAAABgAAAAYATgAAbWF4cAAAAsAAAAAgAAAAIAEQADxuYW1lAAAC4AAAAUUAAAJtPlT+fXBvc3QAAAQoAAAAHgAAAC/RhmVweJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGBxeMLxgYG7438AQw9zA0AAUZgTJAQDdeQvneJztkLENgDAQA8/KQ4EYgSo1s1Cxf80WycfAFrF0lnz66oEFKMmZBOhGjFxpZV/Y7IPqmxj+obW/c4cbrczs7uNb/tUL6i3WCXEAAHicY2BhYPj/mVmKmZeBj0GaQZ1Bn4GBkY+RXdyO0URNH0jLMTIbKBmLmwmAOGIC7CKm4mYmYLaIOoShxHSL0dNNJyA4OIBZl8XN8xsTk25VFbMuc+ppXX9/Fh1muzpFReaQcFbGhuQtnroBpx+fBCpkdt/8b7FOA6N3HbMOS86/l2ysrLrBt8KAHOfljMqxyszBwQAGoSFheJxjYGRgYADih0telMfz23xl4GZhAIEblhYmCPr/ZxYGZl4gl4OBCSQKAC7VCZ8AeJxjYGRgYG7438AQw8IAAkCSkQEVMAEARwgCawQAAAAEAAAAAAAAAABOAAAAAQAAAAIAMAAEAAAAAAACAAAACgAKAAAA/wAAAAAAAHicZY9NTsMwEIVf+gekEqqoYIfkBWIBKP0Rq25YVGr3XXTfpk6bKokjx63UA3AejsAJOALcgDvwSCebNpbH37x5Y08A3OAHHo7fLfeRPVwyO3INF7gXrlN/EG6QX4SbaONVuEX9TdjHM6bCbXRheYPXuGL2hHdhDx18CNdwjU/hOvUv4Qb5W7iJO/wKt9Dx6sI+5l5XuI1HL/bHVi+cXqnlQcWhySKTOb+CmV7vkoWt0uqca1vEJlODoF9JU51pW91T7NdD5yIVWZOqCas6SYzKrdnq0AUb5/JRrxeJHoQm5Vhj/rbGAo5xBYUlDowxQhhkiMro6DtVZvSvsUPCXntWPc3ndFsU1P9zhQEC9M9cU7qy0nk6T4E9XxtSdXQrbsuelDSRXs1JErJCXta2VELqATZlV44RelzRiT8oZ0j/AAlabsgAAAB4nGNgYoAALgbsgImRiZGZgTWxNCUzn4EBAAzjAi0AAA=='); /* iOS 4.1- */
  192. }
  193. .graceIMFont {font-family:"graceIMFont" !important; font-size:16px;}
  194. .icon-audio:before {content:"\e800";}
  195. </style>