index.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <div
  3. v-if="Boolean(quoteMessage) && props.displayType !== 'audio'"
  4. :class="{
  5. 'input-quote-container': true,
  6. 'input-quote-container-uni': isUniFrameWork,
  7. 'input-quote-container-h5': isH5,
  8. }"
  9. >
  10. <div class="input-quote-content">
  11. <div class="max-one-line">
  12. {{ quoteMessage.nick || quoteMessage.from }}: {{ quoteContentText }}
  13. </div>
  14. <Icon
  15. class="input-quote-close-icon"
  16. :file="closeIcon"
  17. width="11px"
  18. height="11px"
  19. @onClick="cancelQuote"
  20. />
  21. </div>
  22. </div>
  23. </template>
  24. <script setup lang="ts">
  25. import { ref, computed, onMounted, onUnmounted } from '../../../../adapter-vue';
  26. import TUIChatEngine, {
  27. TUIStore,
  28. StoreName,
  29. TUITranslateService,
  30. IMessageModel,
  31. } from '@tencentcloud/chat-uikit-engine';
  32. import Icon from '../../../common/Icon.vue';
  33. import closeIcon from '../../../../assets/icon/icon-close.svg';
  34. import { isH5, isUniFrameWork } from '../../../../utils/env';
  35. import { transformTextWithKeysToEmojiNames } from '../../emoji-config';
  36. import { InputDisplayType } from '../../../../interface';
  37. interface IProps {
  38. displayType?: InputDisplayType;
  39. }
  40. const props = withDefaults(defineProps<IProps>(), {
  41. displayType: 'editor',
  42. });
  43. const TYPES = TUIChatEngine.TYPES;
  44. const quoteMessage = ref<IMessageModel>();
  45. onMounted(() => {
  46. TUIStore.watch(StoreName.CHAT, {
  47. quoteMessage: onQuoteMessageUpdated,
  48. });
  49. });
  50. onUnmounted(() => {
  51. TUIStore.unwatch(StoreName.CHAT, {
  52. quoteMessage: onQuoteMessageUpdated,
  53. });
  54. });
  55. const quoteContentText = computed(() => {
  56. let _quoteContentText;
  57. switch (quoteMessage.value?.type) {
  58. case TYPES.MSG_TEXT:
  59. _quoteContentText = transformTextWithKeysToEmojiNames(quoteMessage.value.payload?.text);
  60. break;
  61. case TYPES.MSG_IMAGE:
  62. _quoteContentText = TUITranslateService.t('TUIChat.图片');
  63. break;
  64. case TYPES.MSG_AUDIO:
  65. _quoteContentText = TUITranslateService.t('TUIChat.语音');
  66. break;
  67. case TYPES.MSG_VIDEO:
  68. _quoteContentText = TUITranslateService.t('TUIChat.视频');
  69. break;
  70. case TYPES.MSG_FILE:
  71. _quoteContentText = TUITranslateService.t('TUIChat.文件');
  72. break;
  73. case TYPES.MSG_CUSTOM:
  74. _quoteContentText = TUITranslateService.t('TUIChat.自定义');
  75. break;
  76. case TYPES.MSG_FACE:
  77. _quoteContentText = TUITranslateService.t('TUIChat.表情');
  78. break;
  79. case TYPES.MSG_MERGER:
  80. _quoteContentText = TUITranslateService.t('TUIChat.聊天记录');
  81. break;
  82. default:
  83. _quoteContentText = TUITranslateService.t('TUIChat.消息');
  84. break;
  85. }
  86. return _quoteContentText;
  87. });
  88. function cancelQuote() {
  89. TUIStore.update(StoreName.CHAT, 'quoteMessage', { message: undefined, type: 'quote' });
  90. }
  91. function onQuoteMessageUpdated(options?: { message: IMessageModel; type: string }) {
  92. if (options?.message && options?.type === 'quote') {
  93. quoteMessage.value = options.message;
  94. } else {
  95. quoteMessage.value = undefined;
  96. }
  97. }
  98. </script>
  99. <style lang="scss" scoped>
  100. %common-container-style {
  101. margin: 5px 100px 5px 8px;
  102. display: flex;
  103. flex: 0 1 auto;
  104. .input-quote-content {
  105. display: flex;
  106. flex: 0 1 auto;
  107. background-color: #fafafa;
  108. border-radius: 8px;
  109. padding: 12px;
  110. font-size: 12px;
  111. align-items: center;
  112. line-height: 16px;
  113. max-width: 100%;
  114. box-sizing: border-box;
  115. min-width: 0;
  116. .max-one-line {
  117. flex: 0 1 auto;
  118. overflow: hidden;
  119. text-overflow: ellipsis;
  120. white-space: nowrap;
  121. }
  122. }
  123. .input-quote-close-icon {
  124. margin-left: 5px;
  125. padding: 5px;
  126. }
  127. }
  128. .input-quote-container {
  129. @extend %common-container-style;
  130. }
  131. .input-quote-container-uni {
  132. @extend %common-container-style;
  133. margin: 5px 60px 0 30px;
  134. }
  135. .input-quote-container-h5 {
  136. @extend %common-container-style;
  137. margin: 5px 0 0;
  138. }
  139. </style>