index.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <template>
  2. <Overlay
  3. :visible="isShowForwardPanel"
  4. :useMask="false"
  5. >
  6. <Transfer
  7. :title="TUITranslateService.t('TUIChat.转发')"
  8. :isSearch="false"
  9. :isCustomItem="false"
  10. :list="customConversationList"
  11. :isHiddenBackIcon="isUniFrameWork"
  12. @cancel="closeForwardPanel"
  13. @submit="finishSelected"
  14. />
  15. </Overlay>
  16. </template>
  17. <script lang="ts" setup>
  18. import { onMounted, onUnmounted, ref } from '../../../adapter-vue';
  19. import TUIChatEngine, {
  20. TUIStore,
  21. StoreName,
  22. TUIChatService,
  23. TUITranslateService,
  24. } from '@tencentcloud/chat-uikit-engine';
  25. import Overlay from '../../common/Overlay/index.vue';
  26. import Transfer from '../../common/Transfer/index.vue';
  27. import { Toast, TOAST_TYPE } from '../../../components/common/Toast';
  28. import { isUniFrameWork } from '../../../utils/env';
  29. import { isEnabledMessageReadReceiptGlobal } from '../utils/utils';
  30. import OfflinePushInfoManager, { IOfflinePushInfoCreateParams } from '../offlinePushInfoManager/index';
  31. interface IEmits {
  32. (e: 'toggleMultipleSelectMode', visible?: boolean): void;
  33. }
  34. const emits = defineEmits<IEmits>();
  35. let selectedToForwardMessageIDList: string[] = [];
  36. let isMergeForward = false;
  37. const isShowForwardPanel = ref(false);
  38. const customConversationList = ref();
  39. onMounted(() => {
  40. TUIStore.watch(StoreName.CUSTOM, {
  41. singleForwardMessageID: onSingleForwardMessageIDUpdated,
  42. multipleForwardMessageID: onMultipleForwardMessageIDUpdated,
  43. });
  44. });
  45. onUnmounted(() => {
  46. TUIStore.unwatch(StoreName.CUSTOM, {
  47. singleForwardMessageID: onSingleForwardMessageIDUpdated,
  48. multipleForwardMessageID: onMultipleForwardMessageIDUpdated,
  49. });
  50. // tuistore data must be cleared when closing the forward panel
  51. clearStoreData();
  52. });
  53. function onSingleForwardMessageIDUpdated(messageID: string | undefined) {
  54. if (typeof messageID !== 'undefined') {
  55. isMergeForward = false;
  56. selectedToForwardMessageIDList = [messageID];
  57. openForwardPanel();
  58. }
  59. }
  60. function onMultipleForwardMessageIDUpdated(params: { isMergeForward: boolean; messageIDList: string[] } | undefined) {
  61. if (!params) {
  62. return;
  63. }
  64. isMergeForward = false;
  65. const {
  66. isMergeForward: _isMergeForward,
  67. messageIDList: selectedMessageIDList,
  68. } = params || {};
  69. if (selectedMessageIDList?.length > 0) {
  70. isMergeForward = _isMergeForward;
  71. selectedToForwardMessageIDList = selectedMessageIDList;
  72. openForwardPanel();
  73. } else {
  74. Toast({
  75. message: TUITranslateService.t('TUIChat.未选择消息'),
  76. type: TOAST_TYPE.ERROR,
  77. });
  78. }
  79. }
  80. function clearStoreData() {
  81. TUIStore.update(StoreName.CUSTOM, 'singleForwardMessageID', undefined);
  82. TUIStore.update(StoreName.CUSTOM, 'multipleForwardMessageID', undefined);
  83. }
  84. function closeForwardPanel(): void {
  85. // tuistore data must be cleared when closing the forward panel
  86. clearStoreData();
  87. isShowForwardPanel.value = false;
  88. }
  89. function openForwardPanel(): void {
  90. getTransforRenderDataList();
  91. isShowForwardPanel.value = true;
  92. }
  93. function finishSelected(selectedConvIDWrapperList: Array<{ userID: string }>): void {
  94. if (selectedConvIDWrapperList?.length === 0) return;
  95. // to reuse Transfer, so we have to get conversationModel by userID instead of ConversationID
  96. const selectedConversationList = selectedConvIDWrapperList.map(IDWrapper => TUIStore.getConversationModel(IDWrapper.userID));
  97. const unsentMessageQueue = selectedToForwardMessageIDList
  98. .map(messageID => TUIStore.getMessageModel(messageID))
  99. .sort((a, b) => a.time - b.time);
  100. const forwardPromises = selectedConversationList.map((conversation) => {
  101. const offlinePushInfoCreateParams: IOfflinePushInfoCreateParams = {
  102. conversation,
  103. messageType: TUIChatEngine.TYPES.MSG_MERGER,
  104. };
  105. return TUIChatService.sendForwardMessage(
  106. [conversation],
  107. unsentMessageQueue,
  108. {
  109. needMerge: isMergeForward,
  110. offlinePushInfo: OfflinePushInfoManager.create(offlinePushInfoCreateParams),
  111. params: {
  112. needReadReceipt: isEnabledMessageReadReceiptGlobal(),
  113. },
  114. },
  115. );
  116. });
  117. Promise.allSettled(forwardPromises).then((results) => {
  118. for (const result of results) {
  119. const { status } = result;
  120. if (status === 'rejected') {
  121. const errorMessage = result.reason.code === 80001 ? TUITranslateService.t('TUIChat.内容包含敏感词汇') : result.reason.message as string;
  122. Toast({
  123. message: errorMessage,
  124. type: TOAST_TYPE.ERROR,
  125. });
  126. break;
  127. }
  128. }
  129. });
  130. closeForwardPanel();
  131. emits('toggleMultipleSelectMode', false);
  132. }
  133. function getTransforRenderDataList() {
  134. const conversationList = TUIStore.getData(StoreName.CONV, 'conversationList');
  135. customConversationList.value = conversationList.map((conversation) => {
  136. return {
  137. // To achieve reusability of Transfer, userID is used here instead of ConversationID
  138. userID: conversation.conversationID,
  139. nick: conversation.getShowName(),
  140. avatar: conversation.getAvatar(),
  141. };
  142. });
  143. }
  144. </script>