m-text.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <template>
  2. <view class="flex_c row">
  3. <view class="flex_r text-box" :class="{ text_box: isMy }" @tap.stop="onClick">
  4. <view
  5. class="text_32 text"
  6. :class="isMy ? 'text_r' : 'text_l'"
  7. :hover-class="isMy ? 'hover_classr' : 'hover_classl'"
  8. :hover-stay-time="60"
  9. :style="{ whiteSpace: 'pre-wrap' }"
  10. v-html="renderTextMessage"
  11. ></view>
  12. </view>
  13. <view class="text_26 flex_r" :class="{ row_: isMy }" v-if="value.type === 'text_quote'">
  14. <view v-if="value.payload.quoteSource.type === 'image' || value.payload.quoteSource.type === 'image_transmit'">
  15. <m-image :value="value.payload.quoteSource"></m-image>
  16. </view>
  17. <view class="" v-else-if="value.payload.quoteSource.type === 'audio' || value.payload.quoteSource.type === 'audio_quote'">
  18. <m-audio :value="value.payload.quoteSource"></m-audio>
  19. </view>
  20. <view class="" v-else-if="value.payload.quoteSource.type === 'text' || value.payload.quoteSource.type === 'text_quote'">
  21. <m-text :value="value.payload.quoteSource"></m-text>
  22. </view>
  23. <view class="" v-else>
  24. <m-other :value="value.payload.quoteSource"></m-other>
  25. </view>
  26. </view>
  27. </view>
  28. </template>
  29. <script>
  30. import mText from './quoteType/m-text.vue';
  31. import mImage from './quoteType/m-image.vue';
  32. import mAudio from './quoteType/m-audio.vue';
  33. import mOther from './quoteType/m-other.vue';
  34. import { EmojiDecoder, emojiMap } from '@/utils/EmojiDecoder.js';
  35. const emojiUrl = 'https://imgcache.qq.com/open/qcloud/tim/assets/emoji/';
  36. const decoder = new EmojiDecoder(emojiUrl, emojiMap);
  37. export default {
  38. components: {
  39. mText,
  40. mImage,
  41. mAudio,
  42. mOther
  43. },
  44. props: {
  45. isMy: {
  46. type: [Boolean, Number],
  47. default: false
  48. },
  49. value: {
  50. type: Object,
  51. default: {}
  52. }
  53. },
  54. data() {
  55. return {};
  56. },
  57. created() {
  58. console.log('asdasdasdsdfdf')
  59. },
  60. computed: {
  61. //渲染文本消息,如果包含表情,替换为图片
  62. //todo:本不需要该方法,可以在标签里完成,但小程序有兼容性问题,被迫这样实现
  63. renderTextMessage() {
  64. const { text = '' } = this.value.payload;
  65. if (!text) return '<span>' + '[未知内容]' + '</span>';
  66. return '<span>' + decoder.decode(text) + '</span>';
  67. }
  68. },
  69. methods: {
  70. onClick() {
  71. this.$emit('onClick');
  72. }
  73. }
  74. };
  75. </script>
  76. <style scoped lang="scss">
  77. .row {
  78. }
  79. .row_ {
  80. flex-direction: row-reverse;
  81. }
  82. .text_box {
  83. flex-direction: row-reverse;
  84. }
  85. .text {
  86. position: relative;
  87. z-index: 99;
  88. box-sizing: border-box;
  89. padding: 16rpx 26rpx;
  90. border-radius: 8rpx;
  91. background-color: #fff;
  92. word-break: break-all;
  93. vertical-align: center;
  94. }
  95. .text_r {
  96. position: relative;
  97. background-color: #95ec6a;
  98. }
  99. .text_l {
  100. position: relative;
  101. }
  102. .text_r::after {
  103. position: absolute;
  104. z-index: -1;
  105. content: '';
  106. top: 26rpx;
  107. right: -8rpx;
  108. width: 18rpx;
  109. height: 18rpx;
  110. border-radius: 2px;
  111. transform: rotate(45deg);
  112. background-color: #95ec6a;
  113. }
  114. .text_l::after {
  115. position: absolute;
  116. z-index: -1;
  117. content: '';
  118. top: 26rpx;
  119. left: -8rpx;
  120. width: 18rpx;
  121. height: 18rpx;
  122. border-radius: 2px;
  123. transform: rotate(45deg);
  124. background-color: #fff;
  125. }
  126. .hover_classr {
  127. background-color: #89d961;
  128. }
  129. .hover_classl {
  130. background-color: #e2e2e2;
  131. }
  132. .hover_classr::after {
  133. position: absolute;
  134. z-index: -1;
  135. content: '';
  136. top: 26rpx;
  137. right: -8rpx;
  138. width: 18rpx;
  139. height: 18rpx;
  140. border-radius: 2px;
  141. transform: rotate(45deg);
  142. background-color: #89d961;
  143. }
  144. .hover_classl::after {
  145. position: absolute;
  146. z-index: -1;
  147. content: '';
  148. top: 26rpx;
  149. left: -8rpx;
  150. width: 18rpx;
  151. height: 18rpx;
  152. border-radius: 2px;
  153. transform: rotate(45deg);
  154. background-color: #e2e2e2;
  155. }
  156. </style>