123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- import { View, ScrollView } from "@tarojs/components";
- import NavBarNormal from "@/components/nav-bar-normal/index";
- import PageCustom from "@/components/page-custom/index";
- import Taro, { useUnload } from "@tarojs/taro";
- import { useCurrentCharacter } from "@/store/characterStore";
- import ChatMessage from "@/components/chat-message";
- import style from "./index.module.less";
- // import { useAppStore } from "@/store/appStore";
- import InputBar from "./components/input-bar";
- import { useEffect, useState, useRef } from "react";
- import { useTextChat } from "@/store/textChat";
- import { EAI_MODEL } from "@/consts/enum";
- import type { TMessage, TRobotMessage } from "@/store/textChat";
- import ChatWelcome from './components/chat-welcome'
- import IconArrowLeft from "@/components/icon/icon-arrow-left";
- import PersonalCard from './components/personal-card'
- // 类型谓词函数
- function isRobotMessage(message: TMessage | TRobotMessage): message is TRobotMessage {
- return 'robot' in message && 'reasoningContent' in message;
- }
- export default function Index() {
- const [deepThink, setDeepThink] = useState(EAI_MODEL.DeepseekChat);
- const [showWelcome, setShowWelcome] = useState(true);
- const [keyboardHeight, setKeyboardHeight] = useState(0);
- const [contentHeight, setContentHeight] = useState(0);
- const [scrollViewHeight, setScrollViewHeight] = useState(0);
- const scrollViewRef = useRef<any>(null);
- // const headerHeight = useAppStore((state) => state.headerHeight);
- const character = useCurrentCharacter();
- const messageList = useTextChat((state) => state.list);
- const { destroy } = useTextChat();
- const scrollTop = useTextChat((state) => state.scrollTop);
- const { pushRobotMessage } = useTextChat();
-
- // 计算 marginTopOffset 偏移的距离
- const marginTopOffset = (() => {
- if (keyboardHeight <= 0) return 0;
- // 如果内容超过滚动容器,取键盘弹起高度
- if(contentHeight > scrollViewHeight){
- return -(keyboardHeight)
- }
- // 如果内容+键盘弹起高度超过滚动容器, 则取其差值
- if( contentHeight + keyboardHeight > scrollViewHeight){
- // 内容+键盘弹起高度 - 滚动容器高度
- return -(contentHeight + keyboardHeight - scrollViewHeight)
- }
- })();
- useUnload(() => {
- destroy();
- });
- useEffect(() => {
- // 监听键盘高度变化
- Taro.onKeyboardHeightChange((res) => {
- if(res.height <= 0){
- return setKeyboardHeight(0);
- }
- setShowWelcome(false)
- setKeyboardHeight(res.height - 24);
- });
- return () => {
- // 清理监听器
- Taro.offKeyboardHeightChange();
- };
- }, []);
- // 监听内容高度和 ScrollView 高度变化
- useEffect(() => {
- if (scrollViewRef.current) {
- const query = Taro.createSelectorQuery();
- // 获取聊天内容高度
- query.select('#messageList').boundingClientRect((rect: any) => {
- if (rect) {
- setContentHeight(rect.height);
- }
- }).exec();
- // 获取滚动容器高度
- query.select('#scrollView').boundingClientRect((rect: any) => {
- if (rect) {
- setScrollViewHeight(rect.height);
- }
- }).exec();
- }
- }, [messageList]);
- const switchDeepThink = () => {
- if (deepThink === EAI_MODEL.DeepseekChat) {
- setDeepThink(EAI_MODEL.DeepseekReasoner);
- return;
- }
- setDeepThink(EAI_MODEL.DeepseekChat);
- };
- useEffect(() => {
- // 主动打招呼
- if (character) {
- const greetingText = `Hi~我是${character.name},和我聊聊吧~`;
- pushRobotMessage({
- content: greetingText,
- reasoningContent: "",
- robot: {
- avatar: character.avatar ?? "",
- name: character.name ?? "",
- profileId: character.profileId ?? "",
- },
- });
- }
- }, []);
-
- const renderNavLeft = ()=> {
- return (
- <View className="flex items-center gap-8">
- <IconArrowLeft />
- <View className={showWelcome ? 'hidden' : 'block'}>
- <PersonalCard size="mini" />
- </View>
- </View>
- )
- }
- return (
- <PageCustom>
- <NavBarNormal scrollFadeIn leftColumn={renderNavLeft}></NavBarNormal>
- <View className="flex flex-col w-full h-screen">
- <ScrollView
- ref={scrollViewRef}
- scrollY
- id="scrollView"
- style={{
- flex: 1,
- height: "1px", // 高度自适应
- }}
- scrollTop={scrollTop}
- scrollWithAnimation
- >
- {showWelcome && <ChatWelcome/>}
- <View id="messageList" className="flex flex-col gap-8 px-18 pb-140">
- {messageList.map((message) => {
- const robotMessage = isRobotMessage(message) ? message : null;
- return (
- <ChatMessage
- key={message.messageId}
- textReasoning={robotMessage?.reasoningContent}
- character={robotMessage?.robot}
- text={message.content}
- ></ChatMessage>
- );
- })}
- </View>
- </ScrollView>
- <View className="h-140 w-10"></View>
- <View
- className="fixed left-0 right-0 bottom-0 min-h-130 z-50"
- style={{
- bottom: `${keyboardHeight}px`
- }}
- >
- <View
- onClick={switchDeepThink}
- className={
- deepThink === EAI_MODEL.DeepseekReasoner
- ? style.deepMindMarkActive
- : style.deepMindMark
- }
- >
- 深度思考(R1)
- </View>
- <InputBar aiModel={deepThink} character={null}></InputBar>
- </View>
- </View>
- </PageCustom>
- );
- }
|