feat: render markdown when show assistant prompt (#4365)

* feat: render markdown when show assistant prompt

* fix: polish user experience
This commit is contained in:
fullex 2025-04-04 09:37:29 +08:00 committed by GitHub
parent fb5ddaf9d5
commit 4d5cfe06f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 26 deletions

View File

@ -2,7 +2,7 @@ import 'emoji-picker-element'
import { CloseCircleFilled } from '@ant-design/icons'
import EmojiPicker from '@renderer/components/EmojiPicker'
import { Box, HStack } from '@renderer/components/Layout'
import { Box, HSpaceBetweenStack, HStack } from '@renderer/components/Layout'
import { estimateTextTokens } from '@renderer/services/TokenService'
import { Assistant, AssistantSettings } from '@renderer/types'
import { getLeadingEmoji } from '@renderer/utils'
@ -10,21 +10,23 @@ import { Button, Input, Popover } from 'antd'
import TextArea from 'antd/es/input/TextArea'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import ReactMarkdown from 'react-markdown'
import styled from 'styled-components'
interface Props {
assistant: Assistant
updateAssistant: (assistant: Assistant) => void
updateAssistantSettings: (settings: AssistantSettings) => void
onOk: () => void
updateAssistantSettings?: (settings: AssistantSettings) => void
onOk?: () => void
}
const AssistantPromptSettings: React.FC<Props> = ({ assistant, updateAssistant, onOk }) => {
const AssistantPromptSettings: React.FC<Props> = ({ assistant, updateAssistant }) => {
const [emoji, setEmoji] = useState(getLeadingEmoji(assistant.name) || assistant.emoji)
const [name, setName] = useState(assistant.name.replace(getLeadingEmoji(assistant.name) || '', '').trim())
const [prompt, setPrompt] = useState(assistant.prompt)
const [tokenCount, setTokenCount] = useState(0)
const { t } = useTranslation()
const [showMarkdown, setShowMarkdown] = useState(prompt.length > 0)
useEffect(() => {
const updateTokenCount = async () => {
@ -92,22 +94,39 @@ const AssistantPromptSettings: React.FC<Props> = ({ assistant, updateAssistant,
{t('common.prompt')}
</Box>
<TextAreaContainer>
{showMarkdown ? (
<MarkdownContainer onClick={() => setShowMarkdown(false)}>
<ReactMarkdown className="markdown">{prompt}</ReactMarkdown>
<div style={{ height: '30px' }} />
</MarkdownContainer>
) : (
<TextArea
rows={10}
placeholder={t('common.assistant') + t('common.prompt')}
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
onBlur={onUpdate}
onBlur={() => {
onUpdate()
}}
autoFocus={true}
spellCheck={false}
style={{ minHeight: 'calc(80vh - 200px)', maxHeight: 'calc(80vh - 150px)' }}
style={{ minHeight: 'calc(80vh - 200px)', maxHeight: 'calc(80vh - 200px)', paddingBottom: '30px' }}
/>
<TokenCount>Tokens: {tokenCount}</TokenCount>
)}
</TextAreaContainer>
<HStack width="100%" justifyContent="flex-end" mt="10px">
<Button type="primary" onClick={onOk}>
{t('common.close')}
<HSpaceBetweenStack width="100%" justifyContent="flex-end" mt="10px">
<TokenCount>Tokens: {tokenCount}</TokenCount>
{showMarkdown ? (
<Button type="primary" onClick={() => setShowMarkdown(false)}>
{t('common.edit')}
</Button>
</HStack>
) : (
<Button type="primary" onClick={() => setShowMarkdown(true)}>
{t('common.save')}
</Button>
)}
</HSpaceBetweenStack>
</Container>
)
}
@ -135,15 +154,19 @@ const TextAreaContainer = styled.div`
`
const TokenCount = styled.div`
position: absolute;
bottom: 8px;
right: 8px;
background-color: var(--color-background-soft);
padding: 2px 8px;
padding: 2px 2px;
border-radius: 4px;
font-size: 12px;
font-size: 14px;
color: var(--color-text-2);
user-select: none;
`
const MarkdownContainer = styled.div`
min-height: calc(80vh - 200px);
max-height: calc(80vh - 200px);
padding-right: 2px;
overflow: auto;
overflow-x: hidden;
`
export default AssistantPromptSettings

View File

@ -114,7 +114,6 @@ const AssistantSettingPopupContainer: React.FC<Props> = ({ resolve, tab, ...prop
assistant={assistant}
updateAssistant={updateAssistant}
updateAssistantSettings={updateAssistantSettings}
onOk={onOk}
/>
)}
{menu === 'model' && (