ChatMessageContainer.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. <template>
  2. <FlexCol position="relative" width="100%" height="100%">
  3. <slot name="header" />
  4. <!--聊天内容-->
  5. <FlexCol flex="1" flexBasis="100%" :padding="20">
  6. <FlexRow
  7. v-if="historyItemsPagerManager && historyItemsPagerManager.hasMoreOlder.value"
  8. position="absolute"
  9. center
  10. :inset="{t:0,l:0,r:0}"
  11. >
  12. <Button
  13. size="small"
  14. :loading="historyItemsPagerManager.loadingMore.value"
  15. @click="() => historyItemsPagerManager!.loadOlder()"
  16. >
  17. 加载更多
  18. </Button>
  19. </FlexRow>
  20. <ActivityIndicator v-if="historyItemsPagerManager?.loadingInit.value" />
  21. <scroll-view
  22. ref="scrollRectRef"
  23. scroll-y
  24. :style="{ flex: 1, height, minHeight: height, maxHeight: height }"
  25. :scroll-top="scrollY"
  26. >
  27. <FlexCol gap="gap.sm">
  28. <FlexRow
  29. v-if="sessionManager.currentSessionId.value === CHAT_SESSION_LOCAL_ID"
  30. align="center"
  31. gap="gap.sm"
  32. :padding="[10,0]"
  33. >
  34. <Icon icon="warning" />
  35. 您处于临时会话,离开后消息将丢失,请注意保存
  36. </FlexRow>
  37. <ChatMessage
  38. v-for="message in chatManager.messages.value"
  39. :key="message.id"
  40. :message="message"
  41. :isGlobalLoading="chatManager.isLoading.value"
  42. @delete="deleteMessage(message.id)"
  43. @action="chatManager.send($event)"
  44. @mulitSelect="emit('intoSelectMode', [message.id])"
  45. />
  46. </FlexCol>
  47. </scroll-view>
  48. </FlexCol>
  49. <!--聊天输入框-->
  50. <slot name="footer" />
  51. <slot />
  52. </FlexCol>
  53. </template>
  54. <script setup lang="ts">
  55. import { onMounted, ref } from 'vue';
  56. import ChatMessage from './ChatMessage.vue';
  57. import type { ChatInterfaceManager, ChatManager } from '../core/Chat';
  58. import type { ChatHistoryItemsPagerManager } from '../composables/useChatHistoryItemsPager';
  59. import { CHAT_SESSION_LOCAL_ID, type ChatSessionManager } from '../composables/useChatSession';
  60. import FlexCol from '@/components/layout/FlexCol.vue';
  61. import FlexRow from '@/components/layout/FlexRow.vue';
  62. import Button from '@/components/basic/Button.vue';
  63. import ActivityIndicator from '@/components/basic/ActivityIndicator.vue';
  64. import Icon from '@/components/basic/Icon.vue';
  65. export interface ChatMessageContainerExpose {
  66. scrollToBottom: () => void;
  67. stopMessageEditing: () => void;
  68. }
  69. const props = withDefaults(defineProps<{
  70. chatManager: ChatManager;
  71. sessionManager: ChatSessionManager;
  72. historyItemsPagerManager?: ChatHistoryItemsPagerManager;
  73. chatInterfaceManager: ChatInterfaceManager;
  74. height?: string;
  75. }>(), {
  76. height: '40vh',
  77. });
  78. const emit = defineEmits<{
  79. (e: 'intoSelectMode', messageIds: number[]): void;
  80. }>();
  81. const scrollY = ref(0);
  82. function deleteMessage(messageId: number) {
  83. props.sessionManager.onDeleteMessage(messageId);
  84. }
  85. function scrollToBottom() {
  86. scrollY.value = 10000 + Math.random() * 1000;
  87. }
  88. onMounted(() => {
  89. props.chatInterfaceManager.scrollToBottom = scrollToBottom;
  90. });
  91. defineExpose({
  92. scrollToBottom,
  93. });
  94. </script>
  95. <style lang="scss">
  96. </style>