Commit 7733c889 by HoMeTown

feat: 修改chat input 为 editor

parent 6384ebb2
import React, { useEffect, useRef, useState } from 'react'
import { AnimatePresence, motion } from 'framer-motion'
interface EditorProps {
onChange?: (value: string) => void
onFocus?: () => void
onSubmit?: (value: string) => void
placeholders: string[]
}
const Editor: React.FC<EditorProps> = ({ onChange, onFocus, onSubmit, placeholders }) => {
const [content, setContent] = useState('')
const editorRef = useRef<HTMLDivElement>(null)
const [currentPlaceholder, setCurrentPlaceholder] = useState(0)
const intervalRef = useRef<NodeJS.Timeout | null>(null)
const startAnimation = () => {
intervalRef.current = setInterval(() => {
setCurrentPlaceholder(prev => (prev + 1) % placeholders.length)
}, 3000)
}
const handleVisibilityChange = () => {
if (document.visibilityState !== 'visible' && intervalRef.current) {
clearInterval(intervalRef.current) // Clear the interval when the tab is not visible
intervalRef.current = null
}
else if (document.visibilityState === 'visible') {
startAnimation() // Restart the interval when the tab becomes visible
}
}
const handleInput = () => {
if (editorRef.current) {
const newContent = editorRef.current.textContent || ''
setContent(newContent)
onChange?.(newContent)
}
}
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault()
if (content.trim()) {
onSubmit?.(content.trim())
setContent('')
if (editorRef.current) {
editorRef.current.textContent = ''
}
}
}
else if (e.key === 'Backspace' && !content) {
e.preventDefault() // 防止删除最后一个字符后继续删除
}
}
useEffect(() => {
startAnimation()
document.addEventListener('visibilitychange', handleVisibilityChange)
if (editorRef.current) {
editorRef.current.style.height = 'auto'
editorRef.current.style.height = `${editorRef.current.scrollHeight}px`
}
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current)
}
document.removeEventListener('visibilitychange', handleVisibilityChange)
}
}, [content])
return (
<div className="w-full h-auto relative mx-auto bg-white rounded-[36px] overflow-hidden transition duration-200 py-[012px] px-[32px]">
<div
ref={editorRef}
contentEditable
className="w-full min-h-[40px] max-h-[200px] p-2 rounded overflow-y-auto outline-none"
onInput={handleInput}
onFocus={onFocus}
onKeyDown={handleKeyDown}
suppressContentEditableWarning={true}
style={{
resize: 'none',
}}
/>
<div className="absolute inset-0 flex items-center rounded-full pointer-events-none">
<AnimatePresence mode="wait">
{!content && (
<motion.p
initial={{
y: 5,
opacity: 0,
}}
key={`current-placeholder-${currentPlaceholder}`}
animate={{
y: 0,
opacity: 1,
}}
exit={{
y: -15,
opacity: 0,
}}
transition={{
duration: 0.3,
ease: 'linear',
}}
className="dark:text-zinc-500 text-[12px] sm:text-base font-normal text-[#3333334d] pl-4 sm:pl-12 text-left w-[calc(100%-2rem)] truncate"
>
{placeholders[currentPlaceholder]}
</motion.p>
)}
</AnimatePresence>
</div>
</div>
)
}
export default Editor
...@@ -7,7 +7,7 @@ import { Slogan } from './components/Slogan/Slogan' ...@@ -7,7 +7,7 @@ import { Slogan } from './components/Slogan/Slogan'
import HomeIcon1 from '@/assets/homeIcon1.png' import HomeIcon1 from '@/assets/homeIcon1.png'
import HomeIcon2 from '@/assets/homeIcon2.png' import HomeIcon2 from '@/assets/homeIcon2.png'
import { GradientBackground } from '@/components/GradientBackground' import { GradientBackground } from '@/components/GradientBackground'
import { PlaceholdersInput } from '@/components/PlaceholdersInput' import ChatEditor from '@/components/ChatEditor'
export const Home: React.FC = () => { export const Home: React.FC = () => {
const placeholders = [ const placeholders = [
...@@ -17,14 +17,14 @@ export const Home: React.FC = () => { ...@@ -17,14 +17,14 @@ export const Home: React.FC = () => {
'直接开始问吧!', '直接开始问吧!',
'保险公司偿付能力在哪里可以看?', '保险公司偿付能力在哪里可以看?',
] ]
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { // const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault() // e.preventDefault()
// console.log(e.target.value) // // console.log(e.target.value)
} // }
const onSubmit = (e: React.FormEvent<HTMLFormElement>) => { // const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault() // e.preventDefault()
// console.log('submitted') // // console.log('submitted')
} // }
return ( return (
<div className={styles.homePage}> <div className={styles.homePage}>
<GradientBackground /> <GradientBackground />
...@@ -50,15 +50,13 @@ export const Home: React.FC = () => { ...@@ -50,15 +50,13 @@ export const Home: React.FC = () => {
/> />
</div> </div>
<div className="box-border px-[0] mx-auto iptContainer w-full h-[122px] max-w-[1000px] flex-shrink-0 sm:px-0 sm:h-[132px]"> <div className="box-border px-[0] mx-auto iptContainer w-full max-w-[1000px] flex-shrink-0 sm:px-0">
<PlaceholdersInput {/* <PlaceholdersInput
placeholders={placeholders} placeholders={placeholders}
onChange={handleChange} onChange={handleChange}
onSubmit={onSubmit} onSubmit={onSubmit}
/> /> */}
{/* <div className="w-full h-[72px] bg-white rounded-[36px]"> <ChatEditor placeholders={placeholders} />
123
</div> */}
<div className="w-full text-center mt-[20px] text-[#3333334d] text-[12px]"> <div className="w-full text-center mt-[20px] text-[#3333334d] text-[12px]">
内容由AI模型生成,其准确性和完整性无法保证,仅供参考 内容由AI模型生成,其准确性和完整性无法保证,仅供参考
</div> </div>
......
...@@ -19,7 +19,7 @@ const BotEye: React.FC = () => { ...@@ -19,7 +19,7 @@ const BotEye: React.FC = () => {
useEffect(() => { useEffect(() => {
const blinkInterval = setInterval(() => { const blinkInterval = setInterval(() => {
blink() blink()
}, 4000) // 每2秒眨一次眼 }, 4000)
return () => clearInterval(blinkInterval) return () => clearInterval(blinkInterval)
}, []) }, [])
......
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