mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
fix(desktop): show message Copy button on hover at bottom-right
Move the Copy button from always-visible below messages to the bottom-right side of each message bubble, only appearing on hover. Reduces visual clutter in chat conversations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
41fc58d73a
commit
739b353a89
@ -8,12 +8,14 @@ type Props = {
|
||||
|
||||
export function AssistantMessage({ content, isStreaming }: Props) {
|
||||
return (
|
||||
<div className="mb-5 ml-10 max-w-[calc(100%-2.5rem)]">
|
||||
<div className="rounded-[20px] rounded-tl-[8px] border border-[var(--color-border)]/60 bg-[var(--color-surface)] px-4 py-3 text-sm text-[var(--color-text-primary)] shadow-sm">
|
||||
<MarkdownRenderer content={content} />
|
||||
{isStreaming && (
|
||||
<span className="ml-0.5 inline-block h-4 w-0.5 animate-shimmer bg-[var(--color-brand)] align-text-bottom" />
|
||||
)}
|
||||
<div className="group mb-5 ml-10 flex items-end gap-1.5">
|
||||
<div className="min-w-0">
|
||||
<div className="rounded-[20px] rounded-tl-[8px] border border-[var(--color-border)]/60 bg-[var(--color-surface)] px-4 py-3 text-sm text-[var(--color-text-primary)] shadow-sm">
|
||||
<MarkdownRenderer content={content} />
|
||||
{isStreaming && (
|
||||
<span className="ml-0.5 inline-block h-4 w-0.5 animate-shimmer bg-[var(--color-brand)] align-text-bottom" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MessageActionBar
|
||||
|
||||
@ -3,22 +3,18 @@ import { CopyButton } from '../shared/CopyButton'
|
||||
type Props = {
|
||||
copyText?: string
|
||||
copyLabel: string
|
||||
align?: 'start' | 'end'
|
||||
}
|
||||
|
||||
export function MessageActionBar({
|
||||
copyText,
|
||||
copyLabel,
|
||||
align = 'start',
|
||||
}: Props) {
|
||||
const hasCopy = Boolean(copyText?.trim())
|
||||
|
||||
if (!hasCopy) return null
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`mt-1.5 flex ${align === 'end' ? 'justify-end' : 'justify-start'}`}
|
||||
>
|
||||
<div className="shrink-0 pb-2 opacity-0 transition-opacity duration-200 group-hover:opacity-100">
|
||||
<CopyButton
|
||||
text={copyText!}
|
||||
label={copyLabel}
|
||||
|
||||
@ -11,28 +11,28 @@ export function UserMessage({ content, attachments }: Props) {
|
||||
const hasText = content.trim().length > 0
|
||||
|
||||
return (
|
||||
<div className="mb-5 flex justify-end">
|
||||
<div className="max-w-[82%] space-y-2">
|
||||
<div className="group mb-5 flex items-end justify-end gap-1.5">
|
||||
<div className="min-w-0 max-w-[82%] space-y-2">
|
||||
{attachments && attachments.length > 0 && (
|
||||
<AttachmentGallery attachments={attachments} variant="message" />
|
||||
)}
|
||||
|
||||
{hasText && (
|
||||
<>
|
||||
<div
|
||||
className="bg-[var(--color-surface-user-msg)] px-4 py-3 text-sm leading-relaxed text-[var(--color-text-primary)] whitespace-pre-wrap break-words"
|
||||
style={{ borderRadius: '18px 4px 18px 18px' }}
|
||||
>
|
||||
{content}
|
||||
</div>
|
||||
<MessageActionBar
|
||||
copyText={content}
|
||||
copyLabel="Copy prompt"
|
||||
align="end"
|
||||
/>
|
||||
</>
|
||||
<div
|
||||
className="bg-[var(--color-surface-user-msg)] px-4 py-3 text-sm leading-relaxed text-[var(--color-text-primary)] whitespace-pre-wrap break-words"
|
||||
style={{ borderRadius: '18px 4px 18px 18px' }}
|
||||
>
|
||||
{content}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{hasText && (
|
||||
<MessageActionBar
|
||||
copyText={content}
|
||||
copyLabel="Copy prompt"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user