replies.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <template>
  2. <div
  3. class="replies"
  4. :class="[isH5 ? 'replies-H5' : '', isMenuOpen ? 'replies-menu-open' : '']"
  5. v-if="show"
  6. ref="dialog"
  7. >
  8. <div class="header">
  9. <div class="header-back">
  10. <i v-if="isH5" class="icon icon-back" @click="toggleShow"></i>
  11. </div>
  12. <div class="header-title">
  13. <span>{{ $t('TUIChat.回复详情') }}</span>
  14. </div>
  15. <div class="header-close">
  16. <i v-if="!isH5" class="icon icon-close" @click="toggleShow"></i>
  17. </div>
  18. </div>
  19. <div class="body">
  20. <div class="body-message">
  21. <RepliesItem :message="message" :isH5="isH5" :isRoot="true" />
  22. </div>
  23. <div class="body-list">
  24. <ul>
  25. <li v-for="(item, index) in replies" :key="index" class="body-list-item">
  26. <RepliesItem :message="item" :isH5="isH5" :isRoot="false" />
  27. </li>
  28. </ul>
  29. </div>
  30. </div>
  31. </div>
  32. </template>
  33. <script lang="ts">
  34. import { defineComponent, reactive, watchEffect, toRefs, watch, ref } from 'vue';
  35. import { onClickOutside } from '@vueuse/core';
  36. import { caculateTimeago } from '../../../utils';
  37. import { Message } from '../../interface';
  38. import TIM from '../../../../../TUICore/tim';
  39. import RepliesItem from './replies-item.vue';
  40. import { JSONToObject } from '../../utils/utils';
  41. import { imUserFriendBatchFriend } from "../../../../../api";
  42. const ReadReceiptDialog = defineComponent({
  43. type: 'custom',
  44. components: {
  45. RepliesItem,
  46. },
  47. props: {
  48. message: {
  49. type: Object,
  50. default: () => ({}),
  51. },
  52. isH5: {
  53. type: Boolean,
  54. default: false,
  55. },
  56. show: {
  57. type: Boolean,
  58. default: () => false,
  59. },
  60. url: {
  61. type: String,
  62. default: '',
  63. },
  64. messageList: {
  65. type: Array,
  66. default: () => [],
  67. },
  68. },
  69. setup(props: any, ctx: any) {
  70. const data = reactive({
  71. message: {} as Message,
  72. isGroup: false,
  73. show: false,
  74. isH5: false,
  75. url: '',
  76. showListNow: 0,
  77. isMenuOpen: true,
  78. replies: [],
  79. messageList: [],
  80. TIM,
  81. });
  82. const dialog: any = ref();
  83. watchEffect(() => {
  84. data.message = props.message;
  85. data.show = props.show;
  86. data.isH5 = props.isH5;
  87. data.url = props.url;
  88. data.messageList = props.messageList;
  89. });
  90. watch(
  91. () => {
  92. data.message, data.messageList;
  93. },
  94. () => {
  95. data.message = props.message;
  96. data.messageList = props.messageList;
  97. handleReplies(data.message);
  98. },
  99. { deep: true }
  100. );
  101. const toggleShow = () => {
  102. data.show = !data.show;
  103. if (!data.show) {
  104. ctx.emit('closeDialog', 'replies');
  105. close();
  106. }
  107. };
  108. onClickOutside(dialog, () => {
  109. data.show = false;
  110. ctx.emit('closeDialog', 'replies');
  111. close();
  112. });
  113. const handleReplies = async (message: Message) => {
  114. try {
  115. const { cloudCustomData } = message;
  116. if (!cloudCustomData) return;
  117. const cloudCustomObject = JSONToObject(cloudCustomData);
  118. data.replies = cloudCustomObject?.messageReplies?.replies;
  119. data?.replies?.forEach(async (item: any) => {
  120. const { messageID, messageSender } = item;
  121. const message = data.messageList.find((item: Message) =>
  122. (item.ID === messageID || item.from === messageSender)
  123. );
  124. item.avatar = message ? (message as Message)?.avatar : '';
  125. try {
  126. const res = await imUserFriendBatchFriend({ imUserIds: [messageSender] })
  127. item.messageSenderName = res.data[0]?.friendNickname || res.data[0]?.imUserId
  128. } catch {
  129. //
  130. }
  131. });
  132. } catch (err) {
  133. console.log(err);
  134. }
  135. };
  136. const close = () => {
  137. data.message = {};
  138. };
  139. const handleDialogPosition = () => {
  140. data.isMenuOpen = !!document?.getElementsByClassName('home-menu')?.length;
  141. };
  142. return {
  143. ...toRefs(data),
  144. dialog,
  145. toggleShow,
  146. close,
  147. caculateTimeago,
  148. handleDialogPosition,
  149. };
  150. },
  151. });
  152. export default ReadReceiptDialog;
  153. </script>
  154. <style lang="scss" scoped src="./style/index.scss"></style>