mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-28 21:42:27 +08:00
refactor: update styles and layout in markdown and message components
- Removed unnecessary letter and word spacing in markdown styles. - Adjusted padding in Inputbar for improved layout. - Modified margin properties in CitationsList and Message components for consistency. - Enhanced MessageHeader logic to conditionally hide based on message type. - Updated icon sizes in MessageMenubar for better alignment. - Added margin adjustments in ThinkingBlock for improved spacing.
This commit is contained in:
parent
8340922263
commit
5b9ff3053b
@ -3,8 +3,6 @@
|
||||
line-height: 1.6;
|
||||
user-select: text;
|
||||
word-break: break-word;
|
||||
letter-spacing: 0.02em;
|
||||
word-spacing: 0.05em;
|
||||
|
||||
h1:first-child,
|
||||
h2:first-child,
|
||||
@ -59,7 +57,7 @@
|
||||
p {
|
||||
margin: 1.3em 0;
|
||||
white-space: pre-wrap;
|
||||
line-height: 2;
|
||||
line-height: 1.6;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 5px;
|
||||
@ -87,7 +85,7 @@
|
||||
li {
|
||||
margin-bottom: 0.5em;
|
||||
pre {
|
||||
margin: 1.5em 0;
|
||||
margin: 1.5em 0 !important;
|
||||
}
|
||||
&::marker {
|
||||
color: var(--color-text-3);
|
||||
@ -201,6 +199,7 @@
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
a,
|
||||
|
||||
@ -188,12 +188,6 @@ const HtmlArtifactsCard: FC<Props> = ({ html }) => {
|
||||
<span>HTML</span>
|
||||
</TypeBadge>
|
||||
</TitleSection>
|
||||
{isStreaming && (
|
||||
<StreamingIndicator>
|
||||
<ClipLoader size={16} color="currentColor" />
|
||||
<StreamingText>{t('html_artifacts.generating')}</StreamingText>
|
||||
</StreamingIndicator>
|
||||
)}
|
||||
</Header>
|
||||
<Content>
|
||||
{isStreaming && !hasContent ? (
|
||||
@ -336,42 +330,16 @@ const TypeBadge = styled.div`
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 4px 8px;
|
||||
padding: 3px 6px;
|
||||
background: var(--color-background-mute);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 6px;
|
||||
font-size: 11px;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-secondary);
|
||||
width: fit-content;
|
||||
`
|
||||
|
||||
const StreamingIndicator = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
background: var(--color-status-warning);
|
||||
border: 1px solid var(--color-status-warning);
|
||||
border-radius: 8px;
|
||||
color: var(--color-text);
|
||||
font-size: 12px;
|
||||
opacity: 0.9;
|
||||
|
||||
[theme-mode='light'] & {
|
||||
background: #fef3c7;
|
||||
border-color: #fbbf24;
|
||||
color: #92400e;
|
||||
}
|
||||
`
|
||||
|
||||
const StreamingText = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-weight: 500;
|
||||
`
|
||||
|
||||
const Content = styled.div`
|
||||
padding: 0;
|
||||
background: var(--color-background);
|
||||
|
||||
@ -955,7 +955,7 @@ const Container = styled.div`
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 0 20px 18px 20px;
|
||||
padding: 0 24px 18px 24px;
|
||||
`
|
||||
|
||||
const InputBarContainer = styled.div`
|
||||
|
||||
@ -151,6 +151,7 @@ const ThinkingTimeSeconds = memo(
|
||||
|
||||
const CollapseContainer = styled(Collapse)`
|
||||
margin: 15px 0;
|
||||
margin-top: 5px;
|
||||
`
|
||||
|
||||
const MessageTitleLabel = styled.div`
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
exports[`ThinkingBlock > basic rendering > should match snapshot 1`] = `
|
||||
.c0 {
|
||||
margin: 15px 0;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.c1 {
|
||||
|
||||
@ -188,7 +188,7 @@ const OpenButton = styled(Button)`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 3px 8px;
|
||||
margin: 8px 0;
|
||||
margin-bottom: 8px;
|
||||
align-self: flex-start;
|
||||
font-size: 12px;
|
||||
background-color: var(--color-background-soft);
|
||||
|
||||
@ -127,8 +127,6 @@ const MessageItem: FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const showHeader = messageStyle === 'plain' || isAssistantMessage
|
||||
|
||||
return (
|
||||
<MessageContainer
|
||||
key={message.id}
|
||||
@ -138,15 +136,7 @@ const MessageItem: FC<Props> = ({
|
||||
'message-user': !isAssistantMessage
|
||||
})}
|
||||
ref={messageContainerRef}>
|
||||
{showHeader && (
|
||||
<MessageHeader
|
||||
message={message}
|
||||
assistant={assistant}
|
||||
model={model}
|
||||
key={getModelUniqId(model)}
|
||||
topic={topic}
|
||||
/>
|
||||
)}
|
||||
<MessageHeader message={message} assistant={assistant} model={model} key={getModelUniqId(model)} topic={topic} />
|
||||
{isEditing && (
|
||||
<MessageEditor
|
||||
message={message}
|
||||
@ -170,7 +160,7 @@ const MessageItem: FC<Props> = ({
|
||||
</MessageErrorBoundary>
|
||||
</MessageContentContainer>
|
||||
{showMenubar && (
|
||||
<MessageFooter className="MessageFooter" $isLastMessage={isLastMessage}>
|
||||
<MessageFooter className="MessageFooter" $isLastMessage={isLastMessage} $messageStyle={messageStyle}>
|
||||
<MessageMenubar
|
||||
message={message}
|
||||
assistant={assistant}
|
||||
@ -199,7 +189,7 @@ const MessageContainer = styled.div`
|
||||
transition: background-color 0.3s ease;
|
||||
transform: translateZ(0);
|
||||
will-change: transform;
|
||||
padding: 10px 10px 0 10px;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
&.message-highlight {
|
||||
background-color: var(--color-primary-mute);
|
||||
@ -227,14 +217,15 @@ const MessageContentContainer = styled(Scrollbar)`
|
||||
overflow-y: auto;
|
||||
`
|
||||
|
||||
const MessageFooter = styled.div<{ $isLastMessage: boolean }>`
|
||||
const MessageFooter = styled.div<{ $isLastMessage: boolean; $messageStyle: 'plain' | 'bubble' }>`
|
||||
display: flex;
|
||||
flex-direction: ${({ $isLastMessage }) => ($isLastMessage ? 'row-reverse' : 'row')};
|
||||
flex-direction: ${({ $isLastMessage, $messageStyle }) =>
|
||||
$isLastMessage && $messageStyle === 'plain' ? 'row-reverse' : 'row'};
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
margin-left: 46px;
|
||||
margin-top: 2px;
|
||||
margin-top: 8px;
|
||||
`
|
||||
|
||||
const NewContextMessage = styled.div`
|
||||
|
||||
@ -57,6 +57,7 @@ const MessageHeader: FC<Props> = memo(({ assistant, model, message, topic }) =>
|
||||
}, [message, model, t, userName])
|
||||
|
||||
const isAssistantMessage = message.role === 'assistant'
|
||||
const isUserMessage = message.role === 'user'
|
||||
const showMinappIcon = sidebarIcons.visible.includes('minapp')
|
||||
|
||||
const avatarName = useMemo(() => firstLetter(assistant?.name).toUpperCase(), [assistant?.name])
|
||||
@ -68,6 +69,12 @@ const MessageHeader: FC<Props> = memo(({ assistant, model, message, topic }) =>
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [model?.provider, showMinappIcon])
|
||||
|
||||
const hideHeader = isBubbleStyle ? isUserMessage && !isMultiSelectMode : false
|
||||
|
||||
if (hideHeader) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Container className="message-header">
|
||||
{isAssistantMessage ? (
|
||||
|
||||
@ -188,7 +188,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
{
|
||||
label: t('common.edit'),
|
||||
key: 'edit',
|
||||
icon: <FilePenLine size={16} />,
|
||||
icon: <FilePenLine size={15} />,
|
||||
onClick: onEdit
|
||||
}
|
||||
]
|
||||
@ -196,13 +196,13 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
{
|
||||
label: t('chat.message.new.branch'),
|
||||
key: 'new-branch',
|
||||
icon: <Split size={16} />,
|
||||
icon: <Split size={15} />,
|
||||
onClick: onNewBranch
|
||||
},
|
||||
{
|
||||
label: t('chat.multiple.select'),
|
||||
key: 'multi-select',
|
||||
icon: <ListChecks size={16} />,
|
||||
icon: <ListChecks size={15} />,
|
||||
onClick: () => {
|
||||
toggleMultiSelectMode(true)
|
||||
}
|
||||
@ -210,7 +210,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
{
|
||||
label: t('chat.save'),
|
||||
key: 'save',
|
||||
icon: <Save size={16} color="var(--color-icon)" style={{ marginTop: 3 }} />,
|
||||
icon: <Save size={15} color="var(--color-icon)" style={{ marginTop: 3 }} />,
|
||||
children: [
|
||||
{
|
||||
label: t('chat.save.file.title'),
|
||||
@ -232,7 +232,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
{
|
||||
label: t('chat.topics.export.title'),
|
||||
key: 'export',
|
||||
icon: <Share size={16} color="var(--color-icon)" style={{ marginTop: 3 }} />,
|
||||
icon: <Share size={15} color="var(--color-icon)" style={{ marginTop: 3 }} />,
|
||||
children: [
|
||||
exportMenuOptions.plain_text && {
|
||||
label: t('chat.topics.copy.plain_text'),
|
||||
@ -413,13 +413,14 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
}, [message])
|
||||
|
||||
const softHoverBg = isBubbleStyle && !isLastMessage
|
||||
|
||||
const showMessageTokens = isBubbleStyle ? isAssistantMessage : true
|
||||
const showMessageTokens = !isBubbleStyle
|
||||
const isUserBubbleStyleMessage = isBubbleStyle && isUserMessage
|
||||
|
||||
return (
|
||||
<>
|
||||
{showMessageTokens && <MessageTokens message={message} />}
|
||||
<MenusBar className={classNames({ menubar: true, show: isLastMessage })}>
|
||||
<MenusBar
|
||||
className={classNames({ menubar: true, show: isLastMessage, 'user-bubble-style': isUserBubbleStyleMessage })}>
|
||||
{message.role === 'user' && (
|
||||
<Tooltip title={t('common.regenerate')} mouseEnterDelay={0.8}>
|
||||
<ActionButton
|
||||
@ -439,7 +440,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
)}
|
||||
<Tooltip title={t('common.copy')} mouseEnterDelay={0.8}>
|
||||
<ActionButton className="message-action-button" onClick={onCopy} $softHoverBg={softHoverBg}>
|
||||
{!copied && <Copy size={16} />}
|
||||
{!copied && <Copy size={15} />}
|
||||
{copied && <CheckOutlined style={{ color: 'var(--color-primary)' }} />}
|
||||
</ActionButton>
|
||||
</Tooltip>
|
||||
@ -456,7 +457,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
open={showRegenerateTooltip}
|
||||
onOpenChange={setShowRegenerateTooltip}>
|
||||
<ActionButton className="message-action-button" $softHoverBg={softHoverBg}>
|
||||
<RefreshCw size={16} />
|
||||
<RefreshCw size={15} />
|
||||
</ActionButton>
|
||||
</Tooltip>
|
||||
</Popconfirm>
|
||||
@ -464,7 +465,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
{isAssistantMessage && (
|
||||
<Tooltip title={t('message.mention.title')} mouseEnterDelay={0.8}>
|
||||
<ActionButton className="message-action-button" onClick={onMentionModel} $softHoverBg={softHoverBg}>
|
||||
<AtSign size={16} />
|
||||
<AtSign size={15} />
|
||||
</ActionButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
@ -538,7 +539,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
className="message-action-button"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
$softHoverBg={softHoverBg}>
|
||||
<Languages size={16} />
|
||||
<Languages size={15} />
|
||||
</ActionButton>
|
||||
</Tooltip>
|
||||
</Dropdown>
|
||||
@ -549,7 +550,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
{message.useful ? (
|
||||
<ThumbsUp size={17.5} fill="var(--color-primary)" strokeWidth={0} />
|
||||
) : (
|
||||
<ThumbsUp size={16} />
|
||||
<ThumbsUp size={15} />
|
||||
)}
|
||||
</ActionButton>
|
||||
</Tooltip>
|
||||
@ -569,7 +570,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
||||
mouseEnterDelay={1}
|
||||
open={showDeleteTooltip}
|
||||
onOpenChange={setShowDeleteTooltip}>
|
||||
<Trash size={16} />
|
||||
<Trash size={15} />
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</Popconfirm>
|
||||
@ -597,7 +598,10 @@ const MenusBar = styled.div`
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 5px;
|
||||
|
||||
&.user-bubble-style {
|
||||
margin-top: 5px;
|
||||
}
|
||||
`
|
||||
|
||||
const ActionButton = styled.div<{ $softHoverBg?: boolean }>`
|
||||
|
||||
Loading…
Reference in New Issue
Block a user