From a430284aa21e3ae1f0d5654e55b2ad2852519cc2 Mon Sep 17 00:00:00 2001
From: wwf <yearningwang@iqtogether.com>
Date: 星期三, 04 六月 2025 15:17:49 +0800
Subject: [PATCH] 初始化

---
 app/components/base/chat/chat/answer/operation.tsx |  197 ++++++++++++++++++++++++++++++-------------------
 1 files changed, 120 insertions(+), 77 deletions(-)

diff --git a/app/components/base/chat/chat/answer/operation.tsx b/app/components/base/chat/chat/answer/operation.tsx
index 0fbb7ce..dcd3df6 100644
--- a/app/components/base/chat/chat/answer/operation.tsx
+++ b/app/components/base/chat/chat/answer/operation.tsx
@@ -5,22 +5,21 @@
   useState,
 } from 'react'
 import { useTranslation } from 'react-i18next'
-import {
-  RiClipboardLine,
-  RiResetLeftLine,
-  RiThumbDownLine,
-  RiThumbUpLine,
-} from '@remixicon/react'
 import type { ChatItem } from '../../types'
 import { useChatContext } from '../context'
-import copy from 'copy-to-clipboard'
-import Toast from '@/app/components/base/toast'
-import AnnotationCtrlButton from '@/app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-button'
-import EditReplyModal from '@/app/components/app/annotation/edit-annotation-modal'
-import Log from '@/app/components/base/chat/chat/log'
-import ActionButton, { ActionButtonState } from '@/app/components/base/action-button'
-import NewAudioButton from '@/app/components/base/new-audio-button'
+import RegenerateBtn from '@/app/components/base/regenerate-btn'
 import cn from '@/utils/classnames'
+import CopyBtn from '@/app/components/base/copy-btn'
+import { MessageFast } from '@/app/components/base/icons/src/vender/solid/communication'
+import AudioBtn from '@/app/components/base/audio-btn'
+import AnnotationCtrlBtn from '@/app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-btn'
+import EditReplyModal from '@/app/components/app/annotation/edit-annotation-modal'
+import {
+  ThumbsDown,
+  ThumbsUp,
+} from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
+import Tooltip from '@/app/components/base/tooltip'
+import Log from '@/app/components/base/chat/chat/log'
 
 type OperationProps = {
   item: ChatItem
@@ -61,6 +60,7 @@
     adminFeedback,
     agent_thoughts,
   } = item
+  const hasAnnotation = !!annotation?.id
   const [localFeedback, setLocalFeedback] = useState(config?.supportAnnotation ? adminFeedback : feedback)
 
   const content = useMemo(() => {
@@ -81,13 +81,13 @@
   const operationWidth = useMemo(() => {
     let width = 0
     if (!isOpeningStatement)
-      width += 26
+      width += 28
     if (!isOpeningStatement && showPromptLog)
-      width += 28 + 8
+      width += 102 + 8
     if (!isOpeningStatement && config?.text_to_speech?.enabled)
-      width += 26
+      width += 33
     if (!isOpeningStatement && config?.supportAnnotation && config?.annotation_reply?.enabled)
-      width += 26
+      width += 56 + 8
     if (config?.supportFeedback && !localFeedback?.rating && onFeedback && !isOpeningStatement)
       width += 60 + 8
     if (config?.supportFeedback && localFeedback?.rating && onFeedback && !isOpeningStatement)
@@ -102,78 +102,121 @@
       <div
         className={cn(
           'absolute flex justify-end gap-1',
-          hasWorkflowProcess && '-bottom-4 right-2',
-          !positionRight && '-bottom-4 right-2',
+          hasWorkflowProcess && '-top-3.5 -right-3.5',
+          !positionRight && '-top-3.5 -right-3.5',
           !hasWorkflowProcess && positionRight && '!top-[9px]',
         )}
         style={(!hasWorkflowProcess && positionRight) ? { left: contentWidth + 8 } : {}}
       >
-        {showPromptLog && !isOpeningStatement && (
-          <div className='hidden group-hover:block'>
-            <Log logItem={item} />
-          </div>
-        )}
         {!isOpeningStatement && (
-          <div className='ml-1 hidden items-center 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'>
-            {(config?.text_to_speech?.enabled) && (
-              <NewAudioButton
-                id={id}
-                value={content}
-                voice={config?.text_to_speech?.voice}
-              />
-            )}
-            <ActionButton onClick={() => {
-              copy(content)
-              Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
-            }}>
-              <RiClipboardLine className='h-4 w-4' />
-            </ActionButton>
-            {!noChatInput && (
-              <ActionButton onClick={() => onRegenerate?.(item)}>
-                <RiResetLeftLine className='h-4 w-4' />
-              </ActionButton>
-            )}
-            {(config?.supportAnnotation && config.annotation_reply?.enabled) && (
-              <AnnotationCtrlButton
-                appId={config?.appId || ''}
-                messageId={id}
-                cached={!!annotation?.id}
-                query={question}
-                answer={content}
-                onAdded={(id, authorName) => onAnnotationAdded?.(id, authorName, question, content, index)}
-                onEdit={() => setIsShowReplyModal(true)}
-              />
-            )}
-          </div>
+          <CopyBtn
+            value={content}
+            className='hidden group-hover:block'
+          />
         )}
-        {!isOpeningStatement && config?.supportFeedback && !localFeedback?.rating && onFeedback && (
-          <div className='ml-1 hidden items-center 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'>
-            {!localFeedback?.rating && (
+
+        {!isOpeningStatement && (showPromptLog || config?.text_to_speech?.enabled) && (
+          <div className='hidden group-hover:flex items-center w-max h-[28px] p-0.5 rounded-lg bg-white border-[0.5px] border-gray-100 shadow-md shrink-0'>
+            {showPromptLog && (
               <>
-                <ActionButton onClick={() => handleFeedback('like')}>
-                  <RiThumbUpLine className='h-4 w-4' />
-                </ActionButton>
-                <ActionButton onClick={() => handleFeedback('dislike')}>
-                  <RiThumbDownLine className='h-4 w-4' />
-                </ActionButton>
+                <Log logItem={item} />
+                <div className='mx-1 w-[1px] h-[14px] bg-gray-200' />
+              </>
+            )}
+
+            {(config?.text_to_speech?.enabled) && (
+              <>
+                <AudioBtn
+                  id={id}
+                  value={content}
+                  noCache={false}
+                  voice={config?.text_to_speech?.voice}
+                  className='hidden group-hover:block'
+                />
               </>
             )}
           </div>
         )}
-        {!isOpeningStatement && config?.supportFeedback && localFeedback?.rating && onFeedback && (
-          <div className='ml-1 flex items-center gap-0.5 rounded-[10px] border-[0.5px] border-components-actionbar-border bg-components-actionbar-bg p-0.5 shadow-md backdrop-blur-sm'>
-            {localFeedback?.rating === 'like' && (
-              <ActionButton state={ActionButtonState.Active} onClick={() => handleFeedback(null)}>
-                <RiThumbUpLine className='h-4 w-4' />
-              </ActionButton>
-            )}
-            {localFeedback?.rating === 'dislike' && (
-              <ActionButton state={ActionButtonState.Destructive} onClick={() => handleFeedback(null)}>
-                <RiThumbDownLine className='h-4 w-4' />
-              </ActionButton>
-            )}
-          </div>
+
+        {(!isOpeningStatement && config?.supportAnnotation && config.annotation_reply?.enabled) && (
+          <AnnotationCtrlBtn
+            appId={config?.appId || ''}
+            messageId={id}
+            annotationId={annotation?.id || ''}
+            className='hidden group-hover:block ml-1 shrink-0'
+            cached={hasAnnotation}
+            query={question}
+            answer={content}
+            onAdded={(id, authorName) => onAnnotationAdded?.(id, authorName, question, content, index)}
+            onEdit={() => setIsShowReplyModal(true)}
+            onRemoved={() => onAnnotationRemoved?.(index)}
+          />
         )}
+        {
+          annotation?.id && (
+            <div
+              className='relative box-border flex items-center justify-center h-7 w-7 p-0.5 rounded-lg bg-white cursor-pointer text-[#444CE7] shadow-md group-hover:hidden'
+            >
+              <div className='p-1 rounded-lg bg-[#EEF4FF] '>
+                <MessageFast className='w-4 h-4' />
+              </div>
+            </div>
+          )
+        }
+        {
+          !isOpeningStatement && !noChatInput && <RegenerateBtn className='hidden group-hover:block mr-1' onClick={() => onRegenerate?.(item)} />
+        }
+        {
+          config?.supportFeedback && !localFeedback?.rating && onFeedback && !isOpeningStatement && (
+            <div className='hidden group-hover:flex shrink-0 items-center px-0.5 bg-white border-[0.5px] border-gray-100 shadow-md text-gray-500 rounded-lg'>
+              <Tooltip popupContent={t('appDebug.operation.agree')}>
+                <div
+                  className='flex items-center justify-center mr-0.5 w-6 h-6 rounded-md hover:bg-black/5 hover:text-gray-800 cursor-pointer'
+                  onClick={() => handleFeedback('like')}
+                >
+                  <ThumbsUp className='w-4 h-4' />
+                </div>
+              </Tooltip>
+              <Tooltip
+                popupContent={t('appDebug.operation.disagree')}
+              >
+                <div
+                  className='flex items-center justify-center w-6 h-6 rounded-md hover:bg-black/5 hover:text-gray-800 cursor-pointer'
+                  onClick={() => handleFeedback('dislike')}
+                >
+                  <ThumbsDown className='w-4 h-4' />
+                </div>
+              </Tooltip>
+            </div>
+          )
+        }
+        {
+          config?.supportFeedback && localFeedback?.rating && onFeedback && !isOpeningStatement && (
+            <Tooltip
+              popupContent={localFeedback.rating === 'like' ? t('appDebug.operation.cancelAgree') : t('appDebug.operation.cancelDisagree')}
+            >
+              <div
+                className={`
+                  flex items-center justify-center w-7 h-7 rounded-[10px] border-[2px] border-white cursor-pointer
+                  ${localFeedback.rating === 'like' && 'bg-blue-50 text-blue-600'}
+                  ${localFeedback.rating === 'dislike' && 'bg-red-100 text-red-600'}
+                `}
+                onClick={() => handleFeedback(null)}
+              >
+                {
+                  localFeedback.rating === 'like' && (
+                    <ThumbsUp className='w-4 h-4' />
+                  )
+                }
+                {
+                  localFeedback.rating === 'dislike' && (
+                    <ThumbsDown className='w-4 h-4' />
+                  )
+                }
+              </div>
+            </Tooltip>
+          )
+        }
       </div>
       <EditReplyModal
         isShow={isShowReplyModal}

--
Gitblit v1.8.0