QuoteMessageRender.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <template>
  2. <view class="message_quote_wrap">
  3. <view class="message_quote_text">
  4. <rich-text :nodes="nodes" class="quote_content_text"></rich-text>
  5. <view style="margin-left: 6rpx" class="message_quote_media">
  6. <image
  7. class="message_quote_image"
  8. v-if="isReplyFile"
  9. src="@/pages_im/static/images/chating_message_file.png"
  10. alt="file"/>
  11. <image
  12. class="message_quote_image"
  13. v-if="isReplyImage"
  14. :src="getQuoteMessage.pictureElem.sourcePicture.url"
  15. alt="img"
  16. @click="clickImageItem"/>
  17. <my-avatar
  18. v-if="isReplyCard"
  19. :src="getQuoteMessage.cardElem.faceURL"
  20. :desc="getQuoteMessage.cardElem.nickname"
  21. size="26" @click="clickCardUser"/>
  22. <image
  23. class="message_quote_image"
  24. v-if="isReplyVideo"
  25. :src="getQuoteMessage.videoElem.snapshotUrl"
  26. alt="video"/>
  27. <image
  28. v-if="isReplyVideo"
  29. class="play_icon"
  30. src="@/pages_im/static/images/chating_message_video_play.png"
  31. alt=""
  32. srcset=""
  33. @click.stop="clickMediaItem"/>
  34. </view>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. import { mapGetters } from "vuex";
  40. // import { checkFileIsExist } from "../../../../../util/common";
  41. import { parseMessageByType } from "../../../../../util/imCommon";
  42. import { MessageType } from "@/pages_im/constant/imConstants";
  43. import MyAvatar from "../../../../../components/MyAvatar/index.vue";
  44. import { myPreview } from "../../../../../util/preview";
  45. import Parser from '@/uni_modules/uview-plus/components/u-parse/parser.js';
  46. const extraTypes = [
  47. MessageType.FileMessage,
  48. MessageType.LocationMessage,
  49. MessageType.PictureMessage,
  50. MessageType.VideoMessage,
  51. MessageType.CardMessage,
  52. ];
  53. export default {
  54. name: "",
  55. components: {
  56. MyAvatar,
  57. },
  58. props: {
  59. message: Object,
  60. },
  61. data() {
  62. return {};
  63. },
  64. computed: {
  65. ...mapGetters([
  66. "storeCacheMap",
  67. "storeCurrentUserID"
  68. ]),
  69. hasExtra() {
  70. return extraTypes.includes(this.message.quoteElem.quoteMessage.contentType);
  71. },
  72. isAtMessage() {
  73. return this.message.contentType === MessageType.AtTextMessage;
  74. },
  75. getQuoteMessage() {
  76. return this.isAtMessage
  77. ? this.message.atTextElem.quoteMessage
  78. : this.message.quoteElem.quoteMessage;
  79. },
  80. isReplyImage() {
  81. return this.getQuoteMessage.contentType === MessageType.PictureMessage;
  82. },
  83. isReplyVideo() {
  84. return this.getQuoteMessage.contentType === MessageType.VideoMessage;
  85. },
  86. isReplyFile() {
  87. return this.getQuoteMessage.contentType === MessageType.FileMessage;
  88. },
  89. isReplyCard() {
  90. return this.getQuoteMessage.contentType === MessageType.CardMessage;
  91. },
  92. isLocationMessage() {
  93. return this.getQuoteMessage.contentType === MessageType.LocationMessage;
  94. },
  95. isRevokedMessage() {
  96. return this.getQuoteMessage.contentType === MessageType.RevokeMessage;
  97. },
  98. getMessageContent() {
  99. if (this.isReplyImage || this.isReplyVideo) {
  100. return "";
  101. }
  102. if (this.isRevokedMessage) {
  103. return "引用内容已被撤回";
  104. }
  105. return parseMessageByType(this.getQuoteMessage, this.storeCurrentUserID);
  106. },
  107. getSenderNickname() {
  108. return `${this.getQuoteMessage.senderNickname}: ${this.getMessageContent}`;
  109. },
  110. nodes() {
  111. if (!this.getSenderNickname) return [];
  112. const parser = new Parser({});
  113. return parser.parse(this.getSenderNickname);
  114. },
  115. },
  116. methods: {
  117. clickImageItem() {
  118. this.$emit('enterSubPage');
  119. myPreview(0, [this.getQuoteMessage.pictureElem.sourcePicture.url])
  120. },
  121. async clickMediaItem() {
  122. if (this.isReplyVideo) {
  123. const message = this.getQuoteMessage
  124. const path = this.storeCacheMap[message.clientMsgID]?.path;
  125. const localPath = await this.checkFileIsExist({
  126. key: message.clientMsgID,
  127. path
  128. })
  129. const previewVideoUrl = localPath || message.videoElem.videoUrl
  130. this.$emit('enterSubPage');
  131. uni.navigateTo({
  132. url: `/pages_im/pages/conversation/previewVideo/index?clientMsgID=${message.clientMsgID}&previewVideoUrl=${previewVideoUrl}&snapshotUrl=${message.videoElem.snapshotUrl}`,
  133. });
  134. }
  135. },
  136. clickCardUser() {
  137. this.$emit('enterSubPage');
  138. uni.navigateTo({
  139. url: `/pages_im/pages/common/userCard/index?sourceID=${this.getQuoteMessage.cardElem.userID}`,
  140. });
  141. },
  142. checkFileIsExist({ key, path }){
  143. return new Promise((resolve) => {
  144. if (!path) {
  145. resolve("");
  146. return;
  147. }
  148. plus.io.resolveLocalFileSystemURL(
  149. path,
  150. (res) => {
  151. resolve(path);
  152. },
  153. (err) => {
  154. console.log(err);
  155. getStore().dispatch("user/deleteCacheData", key);
  156. resolve("");
  157. },
  158. );
  159. });
  160. }
  161. },
  162. };
  163. </script>
  164. <style lang="scss" scoped>
  165. .message_quote_wrap {
  166. display: flex;
  167. flex-direction: row;
  168. justify-content: flex-end;
  169. margin-top: 8rpx;
  170. .message_quote_text {
  171. display: flex;
  172. flex-direction: row;
  173. align-items: center;
  174. justify-content: space-between;
  175. /* width: fit-content; nvue not support, flex-direction: row in parent helps */
  176. padding: 16rpx 16rpx;
  177. border-radius: 6rpx;
  178. color: #666;
  179. font-size: 24rpx;
  180. background-color: #f0f0f0;
  181. }
  182. .quote_content_text {
  183. color: #666;
  184. font-size: 24rpx;
  185. lines: 3;
  186. text-overflow: ellipsis;
  187. overflow: hidden;
  188. flex: 1;
  189. /* max-width: 350rpx; */
  190. }
  191. .message_quote_media {
  192. position: relative;
  193. width: 26px;
  194. height: 26px;
  195. image {
  196. width: 26px;
  197. height: 26px;
  198. }
  199. .play_icon {
  200. width: 13px !important;
  201. height: 13px !important;
  202. position: absolute;
  203. top: 6.5px;
  204. left: 6.5px;
  205. }
  206. }
  207. }
  208. </style>