MediaMessageRender.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <template>
  2. <view class="media_message_container" @click="clickMediaItem">
  3. <!-- <view :style="{height:wrapperHeight}" class="media_message_container"> -->
  4. <u--image :showLoading="true" width="150" :height="maxHeight" mode="widthFix" :src="getImgUrl" @click="clickMediaItem">
  5. <template v-slot:loading>
  6. <u-loading-icon color="red"></u-loading-icon>
  7. </template>
  8. </u--image>
  9. <image v-if="isVideo" class="play_icon" src="../../../../../static/images/chating_message_video_play.png" alt="" srcset="" />
  10. <text v-if="isVideo" class="video_duration">{{ getDuration }}</text>
  11. </view>
  12. </template>
  13. <script>
  14. import { mapGetters } from 'vuex';
  15. import { checkFileIsExist } from '../../../../../util/common';
  16. import { secFormat } from '../../../../../util/imCommon';
  17. import { myPreview } from '../../../../../util/preview';
  18. import { MessageType } from 'openim-uniapp-polyfill';
  19. export default {
  20. name: '',
  21. props: {
  22. message: Object
  23. },
  24. data() {
  25. return {};
  26. },
  27. computed: {
  28. ...mapGetters(['storeCacheMap']),
  29. isVideo() {
  30. return this.message.contentType === MessageType.VideoMessage;
  31. },
  32. getImgUrl() {
  33. if (this.isVideo) {
  34. return this.message.videoElem.snapshotUrl;
  35. }
  36. return this.message.pictureElem.snapshotPicture?.url ?? this.message.pictureElem.sourcePath;
  37. },
  38. getDuration() {
  39. if (!this.isVideo) {
  40. return 0;
  41. }
  42. return secFormat(this.message.videoElem.duration);
  43. },
  44. maxHeight() {
  45. const imageHeight = this.isVideo ? this.message.videoElem.snapshotHeight : this.message.pictureElem.sourcePicture.height;
  46. const imageWidth = this.isVideo ? this.message.videoElem.snapshotWidth : this.message.pictureElem.sourcePicture.width;
  47. const aspectRatio = imageHeight / imageWidth;
  48. return 120 * aspectRatio;
  49. }
  50. },
  51. methods: {
  52. async clickMediaItem() {
  53. if (this.isVideo) {
  54. const path = this.storeCacheMap[this.message.clientMsgID]?.path;
  55. const localPath = await checkFileIsExist({
  56. key: this.message.clientMsgID,
  57. path
  58. });
  59. const previewVideoUrl = localPath || this.message.videoElem.videoUrl;
  60. uni.navigateTo({
  61. url: `/pages_im/pages/conversation/previewVideo/index?clientMsgID=${this.message.clientMsgID}&previewVideoUrl=${previewVideoUrl}&snapshotUrl=${this.message.videoElem.snapshotUrl}`
  62. });
  63. } else {
  64. const list = this.$store.getters.storePreviewImageList;
  65. const idx = list.findIndex((item) => item === this.message.pictureElem.sourcePicture.url);
  66. myPreview(idx, list);
  67. }
  68. }
  69. }
  70. };
  71. </script>
  72. <style lang="scss" scoped>
  73. .media_message_container {
  74. position: relative;
  75. border-radius: 16rpx;
  76. overflow: hidden;
  77. .play_icon {
  78. width: 48px;
  79. height: 48px;
  80. position: absolute;
  81. top: 50%;
  82. left: 50%;
  83. transform: translate(-50%, -50%);
  84. }
  85. .video_duration {
  86. position: absolute;
  87. bottom: 12rpx;
  88. right: 24rpx;
  89. color: #fff;
  90. }
  91. }
  92. </style>