fix: message citations styles and bugs

This commit is contained in:
kangfenmao 2025-05-09 15:53:51 +08:00
parent e134cacbec
commit c66dfa50cf
3 changed files with 34 additions and 24 deletions

View File

@ -57,8 +57,10 @@ const MainTextBlock: React.FC<Props> = ({ block, citationBlockId, role, mentions
title: citation.title || citation.hostname || '', title: citation.title || citation.hostname || '',
content: citation.content?.substring(0, 200) content: citation.content?.substring(0, 200)
} }
const isLink = citation.url.startsWith('http')
const citationJson = encodeHTML(JSON.stringify(supData)) const citationJson = encodeHTML(JSON.stringify(supData))
const citationTag = `[<sup data-citation='${citationJson}'>${citationNum}</sup>](${citation.url})` const supTag = `<sup data-citation='${citationJson}'>${citationNum}</sup>`
const citationTag = isLink ? `[${supTag}](${citation.url})` : supTag
// Replace all occurrences of [citationNum] with the formatted citation // Replace all occurrences of [citationNum] with the formatted citation
const regex = new RegExp(`\\[${citationNum}\\]`, 'g') const regex = new RegExp(`\\[${citationNum}\\]`, 'g')

View File

@ -375,6 +375,7 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
width={680} width={680}
destroyOnClose destroyOnClose
styles={{ styles={{
header: { border: 'none' },
body: { body: {
padding: 0, padding: 0,
height: 'calc(100% - 55px)' height: 'calc(100% - 55px)'

View File

@ -2,7 +2,7 @@ import Favicon from '@renderer/components/Icons/FallbackFavicon'
import { HStack } from '@renderer/components/Layout' import { HStack } from '@renderer/components/Layout'
import { fetchWebContent } from '@renderer/utils/fetch' import { fetchWebContent } from '@renderer/utils/fetch'
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query' import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query'
import { Button, Drawer } from 'antd' import { Button, Drawer, Skeleton } from 'antd'
import { FileSearch } from 'lucide-react' import { FileSearch } from 'lucide-react'
import React, { useState } from 'react' import React, { useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -90,6 +90,7 @@ const CitationsList: React.FC<CitationsListProps> = ({ citations }) => {
onClose={() => setOpen(false)} onClose={() => setOpen(false)}
open={open} open={open}
width={680} width={680}
styles={{ header: { border: 'none' }, body: { paddingTop: 0 } }}
destroyOnClose={false}> destroyOnClose={false}>
{open && {open &&
citations.map((citation) => ( citations.map((citation) => (
@ -114,8 +115,6 @@ const handleLinkClick = (url: string, event: React.MouseEvent) => {
} }
const WebSearchCitation: React.FC<{ citation: Citation }> = ({ citation }) => { const WebSearchCitation: React.FC<{ citation: Citation }> = ({ citation }) => {
const { t } = useTranslation()
const { data: fetchedContent, isLoading } = useQuery({ const { data: fetchedContent, isLoading } = useQuery({
queryKey: ['webContent', citation.url], queryKey: ['webContent', citation.url],
queryFn: async () => { queryFn: async () => {
@ -129,44 +128,49 @@ const WebSearchCitation: React.FC<{ citation: Citation }> = ({ citation }) => {
return ( return (
<WebSearchCard> <WebSearchCard>
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}> <WebSearchCardHeader>
{citation.showFavicon && citation.url && ( {citation.showFavicon && citation.url && (
<Favicon hostname={new URL(citation.url).hostname} alt={citation.title || citation.hostname || ''} /> <Favicon hostname={new URL(citation.url).hostname} alt={citation.title || citation.hostname || ''} />
)} )}
<CitationLink href={citation.url} onClick={(e) => handleLinkClick(citation.url, e)}> <CitationLink className="text-nowrap" href={citation.url} onClick={(e) => handleLinkClick(citation.url, e)}>
{citation.title || <span className="hostname">{citation.hostname}</span>} {citation.title || <span className="hostname">{citation.hostname}</span>}
</CitationLink> </CitationLink>
</div> </WebSearchCardHeader>
{isLoading ? <div>{t('common.loading')}</div> : fetchedContent} {isLoading ? (
<Skeleton active paragraph={{ rows: 1 }} title={false} />
) : (
<WebSearchCardContent>{fetchedContent}</WebSearchCardContent>
)}
</WebSearchCard> </WebSearchCard>
) )
} }
const KnowledgeCitation: React.FC<{ citation: Citation }> = ({ citation }) => ( const KnowledgeCitation: React.FC<{ citation: Citation }> = ({ citation }) => (
<WebSearchCard> <WebSearchCard>
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}> <WebSearchCardHeader>
{citation.showFavicon && <FileSearch width={16} />} {citation.showFavicon && <FileSearch width={16} />}
<CitationLink href={citation.url} onClick={(e) => handleLinkClick(citation.url, e)}> <CitationLink className="text-nowrap" href={citation.url} onClick={(e) => handleLinkClick(citation.url, e)}>
{citation.title} {citation.title}
</CitationLink> </CitationLink>
</div> </WebSearchCardHeader>
{citation.content && truncateText(citation.content, 100)} <WebSearchCardContent>{citation.content && truncateText(citation.content, 100)}</WebSearchCardContent>
</WebSearchCard> </WebSearchCard>
) )
const OpenButton = styled(Button)` const OpenButton = styled(Button)`
display: flex; display: flex;
align-items: center; align-items: center;
padding: 2px 6px; padding: 3px 8px;
margin-bottom: 8px; margin-bottom: 8px;
align-self: flex-start; align-self: flex-start;
font-size: 12px; font-size: 12px;
background-color: var(--color-background-soft);
border-radius: var(--list-item-border-radius);
` `
const PreviewIcons = styled.div` const PreviewIcons = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
margin-right: 8px;
` `
const PreviewIcon = styled.div` const PreviewIcon = styled.div`
@ -193,10 +197,6 @@ const CitationLink = styled.a`
color: var(--color-text-1); color: var(--color-text-1);
text-decoration: none; text-decoration: none;
&:hover {
text-decoration: underline;
}
.hostname { .hostname {
color: var(--color-link); color: var(--color-link);
} }
@ -212,13 +212,20 @@ const WebSearchCard = styled.div`
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
background-color: var(--color-background); background-color: var(--color-background);
transition: all 0.3s ease; transition: all 0.3s ease;
`
&:hover { const WebSearchCardHeader = styled.div`
box-shadow: 0 4px 12px var(--color-border-soft); display: flex;
background-color: var(--color-hover); flex-direction: row;
border-color: var(--color-primary-soft); align-items: center;
transform: translateY(-2px); gap: 8px;
} margin-bottom: 6px;
`
const WebSearchCardContent = styled.div`
font-size: 13px;
line-height: 1.6;
color: var(--color-text-2);
` `
export default CitationsList export default CitationsList