wujingjing
2024-11-12 91fbe6ea41b0451a17aa1f6654faa9806b7f1817
src/components/chat/hooks/useScrollToBottom.ts
@@ -1,37 +1,45 @@
import type { ComputedRef, Ref } from 'vue';
import { nextTick, onActivated, ref, watch } from 'vue';
import { nextTick, onActivated, onUnmounted, ref, watch } from 'vue';
import type { ChatMessage } from '../model/types';
import emitter from '/@/utils/mitt';
import { debounce } from '/@/utils/util';
export type UseScrollToBottomOption = {
   chatListDom: Ref<HTMLDivElement>;
   displayMessageList: ComputedRef<ChatMessage[]>;
};
export const useScrollToBottom = (option:UseScrollToBottomOption) => {
    const {chatListDom,displayMessageList} = option;
export const useScrollToBottom = (option: UseScrollToBottomOption) => {
   const { chatListDom } = option;
    const scrollToBottom = () => {
        if (!chatListDom.value) return;
        chatListDom.value.lastElementChild?.scrollIntoView();
    };
    const forbidScroll = ref(false);
   watch(
      displayMessageList,
      () => {
         if (forbidScroll.value) return;
         nextTick(() => scrollToBottom());
      },
      {
         deep: true,
      }
   );
   const scrollToBottom = () => {
      nextTick(() => {
         if (chatListDom.value.scrollHeight > chatListDom.value.clientHeight) {
            chatListDom.value.scrollTop = chatListDom.value.scrollHeight - chatListDom.value.clientHeight;
         }
      });
   };
   const scrollToTop = () => {
      nextTick(() => {
         chatListDom.value.scrollTop = 0;
      });
   };
   const debounceAmisScroll = debounce(({ instance }) => {
      scrollToBottom();
   }, 500);
   // emitter.on('amis.page.ready', debounceAmisScroll);
   // onUnmounted(() => {
   //    emitter.off('amis.page.ready');
   // });
   onActivated(() => {
      if (forbidScroll.value) return;
      nextTick(() => scrollToBottom());
      scrollToBottom();
   });
   return {
        forbidScroll
    };
      scrollToBottom,
      scrollToTop,
   };
};