chore: chat input and feature readonly

This commit is contained in:
Joel 2025-10-15 14:45:54 +08:00
parent df4e32aaa0
commit 738d3001be
10 changed files with 52 additions and 11 deletions

View File

@ -39,6 +39,7 @@ const DebugWithSingleModel = (
) => {
const { userProfile } = useAppContext()
const {
readonly,
modelConfig,
appId,
inputs,
@ -154,6 +155,7 @@ const DebugWithSingleModel = (
return (
<Chat
readonly={readonly}
config={config}
chatList={chatList}
isResponding={isResponding}

View File

@ -50,13 +50,14 @@ function getActionButtonState(state: ActionButtonState) {
}
}
const ActionButton = ({ className, size, state = ActionButtonState.Default, styleCss, children, ref, ...props }: ActionButtonProps) => {
const ActionButton = ({ className, size, state = ActionButtonState.Default, styleCss, children, ref, disabled, ...props }: ActionButtonProps) => {
return (
<button
type='button'
className={classNames(
actionButtonVariants({ className, size }),
getActionButtonState(state),
disabled && 'cursor-not-allowed text-text-disabled hover:bg-transparent hover:text-text-disabled',
)}
ref={ref}
style={styleCss}

View File

@ -27,8 +27,10 @@ import { useToastContext } from '@/app/components/base/toast'
import FeatureBar from '@/app/components/base/features/new-feature-panel/feature-bar'
import type { FileUpload } from '@/app/components/base/features/types'
import { TransferMethod } from '@/types/app'
import { noop } from 'lodash-es'
type ChatInputAreaProps = {
readonly?: boolean
botName?: string
showFeatureBar?: boolean
showFileUpload?: boolean
@ -44,6 +46,7 @@ type ChatInputAreaProps = {
disabled?: boolean
}
const ChatInputArea = ({
readonly,
botName,
showFeatureBar,
showFileUpload,
@ -159,6 +162,7 @@ const ChatInputArea = ({
const operation = (
<Operation
ref={holdSpaceRef}
readonly={readonly}
fileConfig={visionConfig}
speechToTextConfig={speechToTextConfig}
onShowVoiceInput={handleShowVoiceInput}
@ -194,7 +198,7 @@ const ChatInputArea = ({
className={cn(
'body-lg-regular w-full resize-none bg-transparent p-1 leading-6 text-text-primary outline-none',
)}
placeholder={t('common.chat.inputPlaceholder', { botName }) || ''}
placeholder={readonly ? t('common.chat.inputDisabledPlaceholder') : t('common.chat.inputPlaceholder', { botName }) || ''}
autoFocus
minRows={1}
onResize={handleTextareaResize}
@ -211,6 +215,7 @@ const ChatInputArea = ({
onDragLeave={handleDragFileLeave}
onDragOver={handleDragFileOver}
onDrop={handleDropFile}
readOnly={readonly}
/>
</div>
{
@ -232,7 +237,12 @@ const ChatInputArea = ({
)
}
</div>
{showFeatureBar && <FeatureBar showFileUpload={showFileUpload} disabled={featureBarDisabled} onFeatureBarClick={onFeatureBarClick} />}
{showFeatureBar && <FeatureBar
showFileUpload={showFileUpload}
disabled={featureBarDisabled}
onFeatureBarClick={readonly ? noop : onFeatureBarClick}
hideEditEntrance={readonly}
/>}
</>
)
}

View File

@ -12,8 +12,10 @@ import ActionButton from '@/app/components/base/action-button'
import { FileUploaderInChatInput } from '@/app/components/base/file-uploader'
import type { FileUpload } from '@/app/components/base/features/types'
import cn from '@/utils/classnames'
import { noop } from 'lodash'
type OperationProps = {
readonly?: boolean
fileConfig?: FileUpload
speechToTextConfig?: EnableType
onShowVoiceInput?: () => void
@ -22,6 +24,7 @@ type OperationProps = {
}
const Operation = (
{
readonly,
ref,
fileConfig,
speechToTextConfig,
@ -43,12 +46,13 @@ const Operation = (
ref={ref}
>
<div className='flex items-center space-x-1'>
{fileConfig?.enabled && <FileUploaderInChatInput fileConfig={fileConfig} />}
{fileConfig?.enabled && <FileUploaderInChatInput readonly={readonly} fileConfig={fileConfig} />}
{
speechToTextConfig?.enabled && (
<ActionButton
size='l'
onClick={onShowVoiceInput}
disabled={readonly}
onClick={readonly ? noop : onShowVoiceInput}
>
<RiMicLine className='h-5 w-5' />
</ActionButton>
@ -58,7 +62,8 @@ const Operation = (
<Button
className='ml-3 w-8 px-0'
variant='primary'
onClick={onSend}
onClick={readonly ? noop : onSend}
disabled={readonly}
style={
theme
? {

View File

@ -17,10 +17,13 @@ export type ChatContextValue = Pick<ChatProps, 'config'
| 'onAnnotationRemoved'
| 'disableFeedback'
| 'onFeedback'
>
> & {
readonly?: boolean
}
const ChatContext = createContext<ChatContextValue>({
chatList: [],
readonly: false,
})
type ChatContextProviderProps = {
@ -29,6 +32,7 @@ type ChatContextProviderProps = {
export const ChatContextProvider = ({
children,
readonly = false,
config,
isResponding,
chatList,
@ -46,6 +50,7 @@ export const ChatContextProvider = ({
return (
<ChatContext.Provider value={{
config,
readonly,
isResponding,
chatList: chatList || [],
showPromptLog,

View File

@ -36,6 +36,7 @@ import { useStore as useAppStore } from '@/app/components/app/store'
import type { AppData } from '@/models/share'
export type ChatProps = {
readonly?: boolean
appData?: AppData
chatList: ChatItem[]
config?: ChatConfig
@ -77,6 +78,7 @@ export type ChatProps = {
}
const Chat: FC<ChatProps> = ({
readonly = false,
appData,
config,
onSend,
@ -221,6 +223,7 @@ const Chat: FC<ChatProps> = ({
return (
<ChatContextProvider
readonly={readonly}
config={config}
chatList={chatList}
isResponding={isResponding}
@ -324,6 +327,7 @@ const Chat: FC<ChatProps> = ({
inputsForm={inputsForm}
theme={themeBuilder?.theme}
isResponding={isResponding}
readonly={readonly}
/>
)
}

View File

@ -13,6 +13,7 @@ type Props = {
showFileUpload?: boolean
disabled?: boolean
onFeatureBarClick?: (state: boolean) => void
hideEditEntrance?: boolean
}
const FeatureBar = ({
@ -20,6 +21,7 @@ const FeatureBar = ({
showFileUpload = true,
disabled,
onFeatureBarClick,
hideEditEntrance = false,
}: Props) => {
const { t } = useTranslation()
const features = useFeatures(s => s.features)
@ -132,10 +134,14 @@ const FeatureBar = ({
)}
</div>
<div className='body-xs-regular grow text-text-tertiary'>{t('appDebug.feature.bar.enableText')}</div>
<Button className='shrink-0' variant='ghost-accent' size='small' onClick={() => onFeatureBarClick?.(true)}>
<div className='mx-1'>{t('appDebug.feature.bar.manage')}</div>
<RiArrowRightLine className='h-3.5 w-3.5 text-text-accent' />
</Button>
{
!hideEditEntrance && (
<Button className='shrink-0' variant='ghost-accent' size='small' onClick={() => onFeatureBarClick?.(true)}>
<div className='mx-1'>{t('appDebug.feature.bar.manage')}</div>
<RiArrowRightLine className='h-3.5 w-3.5 text-text-accent' />
</Button>
)
}
</div>
)}
</div>

View File

@ -13,21 +13,27 @@ import { TransferMethod } from '@/types/app'
type FileUploaderInChatInputProps = {
fileConfig: FileUpload
readonly?: boolean
}
const FileUploaderInChatInput = ({
fileConfig,
readonly,
}: FileUploaderInChatInputProps) => {
const renderTrigger = useCallback((open: boolean) => {
return (
<ActionButton
size='l'
className={cn(open && 'bg-state-base-hover')}
disabled={readonly}
>
<RiAttachmentLine className='h-5 w-5' />
</ActionButton>
)
}, [])
if(readonly)
return renderTrigger(false)
return (
<FileFromLinkOrLocal
trigger={renderTrigger}

View File

@ -663,6 +663,7 @@ const translation = {
hitScore: 'Retrieval Score:',
},
inputPlaceholder: 'Talk to {{botName}}',
inputDisabledPlaceholder: 'Preview Only',
thinking: 'Thinking...',
thought: 'Thought',
resend: 'Resend',

View File

@ -657,6 +657,7 @@ const translation = {
hitScore: '召回得分:',
},
inputPlaceholder: '和 {{botName}} 聊天',
inputDisabledPlaceholder: '仅供试用',
thinking: '深度思考中...',
thought: '已深度思考',
resend: '重新发送',