useChatUI.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { useState, useEffect } from 'react';
  2. import Taro from '@tarojs/taro';
  3. import { View } from "@tarojs/components";
  4. import { useAppStore } from '@/store/appStore';
  5. import { useTextChat } from '@/store/textChatStore';
  6. /**
  7. * 聊天UI状态管理 Hook
  8. * 负责处理UI相关的状态,如欢迎页显示、背景设置、输入框高度等
  9. */
  10. export const useChatUI = (
  11. agent: any,
  12. historyListLength: number,
  13. messageListLength: number
  14. ): {
  15. showWelcome: boolean;
  16. haveBg: boolean;
  17. inputContainerHeight: number;
  18. inputContainerBottomOffset: number;
  19. setShowWelcome: (show: boolean) => void;
  20. getBgContent: () => string;
  21. createNavLeftRenderer: (PersonalCard: any, IconArrowLeftWhite24: any, IconArrowLeft: any) => () => JSX.Element;
  22. } => {
  23. const [showWelcome, setShowWelcome] = useState(!historyListLength);
  24. const [inputContainerHeight, setInputContainerHeight] = useState(0);
  25. // const scrollTop = useTextChat((state)=> state.scrollTop)
  26. const bottomSafeHeight = useAppStore((state) => state.bottomSafeHeight);
  27. // 判断是否有背景
  28. const haveBg = !!agent?.enabledChatBg && !!agent.avatarUrl?.length;
  29. // 计算输入框底部偏移量
  30. // 针对没有 safeArea?.bottom 的手机,需要额外增加 12 高度
  31. const inputContainerBottomOffset = bottomSafeHeight <= 0 ? 12 : 0;
  32. // 获取背景内容
  33. const getBgContent = () => {
  34. if (!agent?.avatarUrl || !agent?.enabledChatBg) {
  35. return "";
  36. }
  37. return agent?.avatarUrl;
  38. };
  39. // 渲染导航栏左侧内容的工厂函数
  40. const createNavLeftRenderer = (PersonalCard: any, IconArrowLeftWhite24: any, IconArrowLeft: any) => {
  41. return () => {
  42. return (
  43. <View
  44. className="flex items-center gap-8"
  45. onClick={() => Taro.navigateBack()}
  46. >
  47. {haveBg ? <IconArrowLeftWhite24 /> : <IconArrowLeft />}
  48. <PersonalCard agent={agent} haveBg={haveBg} />
  49. {/* {scrollTop} */}
  50. </View>
  51. );
  52. };
  53. };
  54. // 是否显示欢迎UI
  55. useEffect(() => {
  56. setShowWelcome(!messageListLength && !historyListLength);
  57. }, [historyListLength, messageListLength]);
  58. // 设置导航栏颜色
  59. useEffect(() => {
  60. if (haveBg) {
  61. Taro.setNavigationBarColor({
  62. frontColor: "#ffffff",
  63. backgroundColor: "transparent",
  64. });
  65. }
  66. return () => {
  67. Taro.setNavigationBarColor({
  68. frontColor: "#000000",
  69. backgroundColor: "transparent",
  70. });
  71. };
  72. }, [haveBg]);
  73. // 计算输入框容器高度
  74. useEffect(() => {
  75. const query = Taro.createSelectorQuery();
  76. query
  77. .select("#inputContainer")
  78. .boundingClientRect((rect: any) => {
  79. if (rect) {
  80. setInputContainerHeight(rect.height - bottomSafeHeight);
  81. }
  82. })
  83. .exec();
  84. }, [agent, bottomSafeHeight]);
  85. return {
  86. // 状态
  87. showWelcome,
  88. haveBg,
  89. inputContainerHeight,
  90. inputContainerBottomOffset,
  91. // 设置方法
  92. setShowWelcome,
  93. // 工具方法
  94. getBgContent,
  95. createNavLeftRenderer,
  96. };
  97. };