From 77950e48c76f4a3b29d01831d43039caba29888a Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期二, 18 十一月 2025 14:12:42 +0800
Subject: [PATCH] 修改
---
app/components/base/chat/chat/question.tsx | 129 ++----------------------------------------
1 files changed, 7 insertions(+), 122 deletions(-)
diff --git a/app/components/base/chat/chat/question.tsx b/app/components/base/chat/chat/question.tsx
index 8fc49d1..7052c1f 100644
--- a/app/components/base/chat/chat/question.tsx
+++ b/app/components/base/chat/chat/question.tsx
@@ -4,169 +4,54 @@
} from 'react'
import {
memo,
- useCallback,
- useEffect,
- useRef,
- useState,
} from 'react'
import type { ChatItem } from '../types'
import type { Theme } from '../embedded-chatbot/theme/theme-context'
import { CssTransform } from '../embedded-chatbot/theme/utils'
-import ContentSwitch from './content-switch'
import { User } from '@/app/components/base/icons/src/public/avatar'
import { Markdown } from '@/app/components/base/markdown'
import { FileList } from '@/app/components/base/file-uploader'
-import ActionButton from '../../action-button'
-import { RiClipboardLine, RiEditLine } from '@remixicon/react'
-import Toast from '../../toast'
-import copy from 'copy-to-clipboard'
-import { useTranslation } from 'react-i18next'
-import cn from '@/utils/classnames'
-import Textarea from 'react-textarea-autosize'
-import Button from '../../button'
-import { useChatContext } from './context'
type QuestionProps = {
item: ChatItem
questionIcon?: ReactNode
theme: Theme | null | undefined
- enableEdit?: boolean
- switchSibling?: (siblingMessageId: string) => void
}
-
const Question: FC<QuestionProps> = ({
item,
questionIcon,
theme,
- enableEdit = true,
- switchSibling,
}) => {
- const { t } = useTranslation()
-
const {
content,
message_files,
} = item
- const {
- onRegenerate,
- } = useChatContext()
-
- const [isEditing, setIsEditing] = useState(false)
- const [editedContent, setEditedContent] = useState(content)
- const [contentWidth, setContentWidth] = useState(0)
- const contentRef = useRef<HTMLDivElement>(null)
-
- const handleEdit = useCallback(() => {
- setIsEditing(true)
- setEditedContent(content)
- }, [content])
-
- const handleResend = useCallback(() => {
- setIsEditing(false)
- onRegenerate?.(item, { message: editedContent, files: message_files })
- }, [editedContent, message_files, item, onRegenerate])
-
- const handleCancelEditing = useCallback(() => {
- setIsEditing(false)
- setEditedContent(content)
- }, [content])
-
- const handleSwitchSibling = useCallback((direction: 'prev' | 'next') => {
- if (direction === 'prev')
- item.prevSibling && switchSibling?.(item.prevSibling)
- else
- item.nextSibling && switchSibling?.(item.nextSibling)
- }, [switchSibling, item.prevSibling, item.nextSibling])
-
- const getContentWidth = () => {
- if (contentRef.current)
- setContentWidth(contentRef.current?.clientWidth)
- }
-
- useEffect(() => {
- if (!contentRef.current)
- return
- const resizeObserver = new ResizeObserver(() => {
- getContentWidth()
- })
- resizeObserver.observe(contentRef.current)
- return () => {
- resizeObserver.disconnect()
- }
- }, [])
-
return (
- <div className='mb-2 flex justify-end last:mb-0'>
- <div className={cn('group relative mr-4 flex max-w-full items-start pl-14', isEditing && 'flex-1')}>
- <div className={cn('mr-2 gap-1', isEditing ? 'hidden' : 'flex')}>
- <div
- className="absolute hidden gap-0.5 rounded-[10px] border-[0.5px] border-components-actionbar-border bg-components-actionbar-bg p-0.5 shadow-md backdrop-blur-sm group-hover:flex"
- style={{ right: contentWidth + 8 }}
- >
- <ActionButton onClick={() => {
- copy(content)
- Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
- }}>
- <RiClipboardLine className='h-4 w-4' />
- </ActionButton>
- {enableEdit && <ActionButton onClick={handleEdit}>
- <RiEditLine className='h-4 w-4' />
- </ActionButton>}
- </div>
- </div>
+ <div className='flex justify-end mb-2 last:mb-0 pl-14'>
+ <div className='group relative mr-4 max-w-full'>
<div
- ref={contentRef}
- className='w-full rounded-2xl bg-[#D1E9FF]/50 px-4 py-3 text-sm text-gray-900'
+ className='px-4 py-3 bg-[#D1E9FF]/50 rounded-2xl text-sm text-gray-900'
style={theme?.chatBubbleColorStyle ? CssTransform(theme.chatBubbleColorStyle) : {}}
>
{
!!message_files?.length && (
<FileList
- className='mb-2'
files={message_files}
showDeleteAction={false}
showDownloadAction={true}
/>
)
}
- { !isEditing
- ? <Markdown content={content} />
- : <div className="
- flex flex-col gap-2 rounded-xl
- border border-components-chat-input-border bg-components-panel-bg-blur p-[9px] shadow-md
- ">
- <div className="max-h-[158px] overflow-y-auto overflow-x-hidden">
- <Textarea
- className={cn(
- 'body-lg-regular w-full p-1 leading-6 text-text-tertiary outline-none',
- )}
- autoFocus
- minRows={1}
- value={editedContent}
- onChange={e => setEditedContent(e.target.value)}
- />
- </div>
- <div className="flex justify-end gap-2">
- <Button variant='ghost' onClick={handleCancelEditing}>{t('common.operation.cancel')}</Button>
- <Button variant='primary' onClick={handleResend}>{t('common.chat.resend')}</Button>
- </div>
- </div> }
- { !isEditing && <ContentSwitch
- count={item.siblingCount}
- currentIndex={item.siblingIndex}
- prevDisabled={!item.prevSibling}
- nextDisabled={!item.nextSibling}
- switchSibling={handleSwitchSibling}
- />}
+ <Markdown content={content} />
</div>
<div className='mt-1 h-[18px]' />
</div>
- <div className='h-10 w-10 shrink-0'>
+ <div className='shrink-0 w-10 h-10'>
{
questionIcon || (
- <div className='h-full w-full rounded-full border-[0.5px] border-black/5'>
- <User className='h-full w-full' />
+ <div className='w-full h-full rounded-full border-[0.5px] border-black/5'>
+ <User className='w-full h-full' />
</div>
)
}
--
Gitblit v1.8.0