Commit a8c81fa2 by HoMeTown

feat: 滚动到底部

parent 898f1d23
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>矩形</title>
<defs>
<rect id="path-1" x="0" y="0" width="19.2" height="19.2"></rect>
</defs>
<g id="晓得---PC端页面-草稿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="晓得-PC端---重新生成&amp;返回底部划过" transform="translate(-982.000000, -905.000000)">
<g id="不可点击" transform="translate(982.000000, 905.000000)">
<rect id="矩形" fill="#31B8FD" opacity="0.603362311" x="0" y="0" width="32" height="32" rx="16"></rect>
<g id="编组-9" transform="translate(16.000000, 16.000000) rotate(-225.000000) translate(-16.000000, -16.000000) translate(6.400000, 6.400000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<path d="M14.8527478,2.13333333 C16.0309553,2.13333333 16.9860811,3.0884592 16.9860811,4.26666667 L16.9860811,13.3333333 C16.9860811,14.2169889 16.2697367,14.9333333 15.3860811,14.9333333 C14.5024255,14.9333333 13.7860811,14.2169889 13.7860811,13.3333333 L13.7851414,7.65333333 L5.82551228,15.6134784 C5.20067342,16.2383173 4.18760945,16.2383173 3.56277058,15.6134784 C2.93793172,14.9886395 2.93793172,13.9755756 3.56277058,13.3507367 L11.5791414,5.33333333 L5.78608113,5.33333333 C4.90242553,5.33333333 4.18608113,4.61698893 4.18608113,3.73333333 C4.18608113,2.84967773 4.90242553,2.13333333 5.78608113,2.13333333 L14.8527478,2.13333333 Z" id="形状结合" fill="#FFFFFF" mask="url(#mask-2)"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
import React from 'react'
import { Button, Checkbox, Link, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader } from '@nextui-org/react'
import { useAuth } from '@/auth/AuthContext'
import type { Answer } from '@/types/chat'
interface LoginModalProps {
isOpen: boolean
answer: Answer
onClose: () => void
}
......
import React, { useCallback, useEffect, useState } from 'react'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { useParams } from 'react-router-dom'
import { Spinner } from '@nextui-org/react'
import { Button, Spinner } from '@nextui-org/react'
import { motion } from 'framer-motion'
import { useScroll } from 'ahooks'
import styles from './Chat.module.less'
import { ChatSlogan } from './components/ChatSlogan'
import { ChatMaskBar } from './components/ChatMaskBar'
......@@ -17,6 +18,7 @@ import { fetchCheckTokenApi, fetchStreamResponse } from '@/api/chat'
import { clearShouldSendQuestion, fetchConversations } from '@/store/conversationSlice'
import type { RootState } from '@/store' // 假设你的 store 文件导出了 RootState 类型
import { useAppDispatch, useAppSelector } from '@/store/hook'
import ScrollBtoIcon from '@/assets/svg/scrollBto.svg?react'
export const Chat: React.FC = () => {
let ignore = false
......@@ -26,6 +28,8 @@ export const Chat: React.FC = () => {
const [allItems, setAllItems] = useState<ChatRecord[]>([])
const dispatch = useAppDispatch()
const shouldSendQuestion = useAppSelector((state: RootState) => state.conversation.shouldSendQuestion)
const scrollableRef = useRef<HTMLDivElement | any>(null)
const position = useScroll(scrollableRef)
const handleSubmitQuestion = async (question: string) => {
// 添加用户提问的问题
......@@ -113,6 +117,10 @@ export const Chat: React.FC = () => {
}
}, [])
const scrollToBottom = () => {
scrollableRef.current.scrollTop = scrollableRef.current.scrollHeight
}
useEffect(() => {
if (id) {
if (!ignore) {
......@@ -133,6 +141,7 @@ export const Chat: React.FC = () => {
{isLoading && <div className="w-full h-full flex justify-center"><Spinner /></div>}
{!isLoading && (
<motion.div
ref={scrollableRef}
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
transition={{
......@@ -153,7 +162,23 @@ export const Chat: React.FC = () => {
</motion.div>
)}
</div>
<div className="box-border px-[0] mx-auto iptContainer w-full max-w-[1000px] flex-shrink-0 sm:px-0 pb-[18px]">
<div className="relative box-border px-[0] mx-auto iptContainer w-full max-w-[1000px] flex-shrink-0 sm:px-0 pb-[18px]">
<div className="absolute left-1/2 ml-[-20px] top-[-65px]">
<motion.div
initial="hidden"
animate={(position?.top as number) < -20 ? 'visible' : 'hidden'}
variants={{
hidden: { opacity: 0, y: 20, pointerEvents: 'none' as const },
visible: { opacity: 1, y: 0, pointerEvents: 'auto' as const },
}}
transition={{ duration: 0.3, ease: 'easeInOut' }}
>
<Button onClick={scrollToBottom} radius="full" isIconOnly color="primary">
<ScrollBtoIcon />
</Button>
</motion.div>
</div>
<ChatEditor onSubmit={handleSubmitQuestion} placeholders={RECOMMEND_QUESTIONS_OTHER} />
<div className="w-full text-center mt-[20px] text-[#3333334d] text-[12px]">
内容由AI模型生成,其准确性和完整性无法保证,仅供参考
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment