feat(Messages): enhance citations display with improved styling and translation support
- Added a title for the citations list with translation using `useTranslation`. - Introduced an `Info` icon next to the citations title. - Updated the `CitationsContainer` styling for better visual appeal. - Refactored citation rendering logic in `MessageContent` to streamline citation handling.
This commit is contained in:
parent
1bb27ee3f9
commit
c7ed15684a
@ -1,7 +1,8 @@
|
||||
import Favicon from '@renderer/components/Icons/FallbackFavicon'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import { FileSearch } from 'lucide-react'
|
||||
import { FileSearch, Info } from 'lucide-react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
interface Citation {
|
||||
@ -19,11 +20,16 @@ interface CitationsListProps {
|
||||
}
|
||||
|
||||
const CitationsList: React.FC<CitationsListProps> = ({ citations }) => {
|
||||
console.log('CitationsList', citations)
|
||||
const { t } = useTranslation()
|
||||
|
||||
if (!citations || citations.length === 0) return null
|
||||
|
||||
return (
|
||||
<CitationsContainer className="footnotes">
|
||||
<CitationsTitle>
|
||||
<span>{t('message.citations')}</span>
|
||||
<Info size={14} style={{ opacity: 0.6 }} />
|
||||
</CitationsTitle>
|
||||
{citations.map((citation) => (
|
||||
<HStack key={citation.url || citation.number} style={{ alignItems: 'center', gap: 8 }}>
|
||||
<span style={{ fontSize: 13, color: 'var(--color-text-2)' }}>{citation.number}.</span>
|
||||
@ -83,7 +89,7 @@ const KnowledgeCitation: React.FC<{ citation: Citation }> = ({ citation }) => {
|
||||
|
||||
const CitationsContainer = styled.div`
|
||||
background-color: rgb(242, 247, 253);
|
||||
border-radius: 4px;
|
||||
border-radius: 10px;
|
||||
padding: 8px 12px;
|
||||
margin: 12px 0;
|
||||
display: flex;
|
||||
@ -95,6 +101,15 @@ const CitationsContainer = styled.div`
|
||||
}
|
||||
`
|
||||
|
||||
const CitationsTitle = styled.div`
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
color: var(--color-text-1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
`
|
||||
|
||||
const CitationLink = styled.a`
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { DownOutlined, InfoCircleOutlined, SyncOutlined, TranslationOutlined, UpOutlined } from '@ant-design/icons'
|
||||
import { SyncOutlined, TranslationOutlined } from '@ant-design/icons'
|
||||
import { isOpenAIWebSearch } from '@renderer/config/models'
|
||||
import { getModelUniqId } from '@renderer/services/ModelService'
|
||||
import { Message, Model } from '@renderer/types'
|
||||
@ -7,7 +7,7 @@ import { withMessageThought } from '@renderer/utils/formats'
|
||||
import { Divider, Flex } from 'antd'
|
||||
import { clone } from 'lodash'
|
||||
import { Search } from 'lucide-react'
|
||||
import React, { Fragment, useMemo, useState } from 'react'
|
||||
import React, { Fragment, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import BarLoader from 'react-spinners/BarLoader'
|
||||
import BeatLoader from 'react-spinners/BeatLoader'
|
||||
@ -30,7 +30,6 @@ const MessageContent: React.FC<Props> = ({ message: _message, model }) => {
|
||||
const { t } = useTranslation()
|
||||
const message = withMessageThought(clone(_message))
|
||||
const isWebCitation = model && (isOpenAIWebSearch(model) || model.provider === 'openrouter')
|
||||
const [citationsCollapsed, setCitationsCollapsed] = useState(true)
|
||||
|
||||
// HTML实体编码辅助函数
|
||||
const encodeHTML = (str: string) => {
|
||||
@ -140,10 +139,11 @@ const MessageContent: React.FC<Props> = ({ message: _message, model }) => {
|
||||
return data
|
||||
}, [
|
||||
formattedCitations,
|
||||
message?.metadata?.annotations,
|
||||
message?.metadata?.groundingMetadata?.groundingChunks,
|
||||
message?.metadata?.webSearch?.results,
|
||||
message?.metadata?.webSearchInfo
|
||||
message.metadata?.annotations,
|
||||
message.metadata?.groundingMetadata?.groundingChunks,
|
||||
message.metadata?.knowledge,
|
||||
message.metadata?.webSearch?.results,
|
||||
message.metadata?.webSearchInfo
|
||||
])
|
||||
|
||||
// Process content to make citation numbers clickable
|
||||
@ -251,17 +251,7 @@ const MessageContent: React.FC<Props> = ({ message: _message, model }) => {
|
||||
</Fragment>
|
||||
)}
|
||||
{hasCitations && (
|
||||
<CitationsContainer>
|
||||
<CitationsHeader onClick={() => setCitationsCollapsed(!citationsCollapsed)}>
|
||||
<div>
|
||||
{t('message.citations')}
|
||||
<InfoCircleOutlined style={{ fontSize: '14px', marginLeft: '4px', opacity: 0.6 }} />
|
||||
</div>
|
||||
{citationsCollapsed ? <DownOutlined /> : <UpOutlined />}
|
||||
</CitationsHeader>
|
||||
|
||||
{!citationsCollapsed && (
|
||||
<CitationsContent>
|
||||
<>
|
||||
{message?.metadata?.groundingMetadata && message.status === 'success' && (
|
||||
<>
|
||||
<CitationsList
|
||||
@ -325,9 +315,7 @@ const MessageContent: React.FC<Props> = ({ message: _message, model }) => {
|
||||
}))}
|
||||
/>
|
||||
)}
|
||||
</CitationsContent>
|
||||
)}
|
||||
</CitationsContainer>
|
||||
</>
|
||||
)}
|
||||
|
||||
<MessageAttachments message={message} />
|
||||
@ -335,30 +323,6 @@ const MessageContent: React.FC<Props> = ({ message: _message, model }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const CitationsContainer = styled.div`
|
||||
margin-top: 12px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
`
|
||||
|
||||
const CitationsHeader = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
background-color: var(--color-background-mute);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-border);
|
||||
}
|
||||
`
|
||||
|
||||
const CitationsContent = styled.div`
|
||||
padding: 10px;
|
||||
background-color: var(--color-background-mute);
|
||||
`
|
||||
const MessageContentLoading = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user