diff --git a/src/renderer/src/assets/main.css b/src/renderer/src/assets/main.css index a1585ad6a..475a30b4a 100644 --- a/src/renderer/src/assets/main.css +++ b/src/renderer/src/assets/main.css @@ -10738,3 +10738,36 @@ body { font-size: 11px; color: var(--text-muted); } + +/* Right-click context menu on messages */ +.chat-context-menu { + position: fixed; + z-index: 1000; + min-width: 160px; + padding: 4px; + background: var(--bg-elevated); + border: 1px solid var(--border-bright); + border-radius: var(--radius-md); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); +} + +.chat-context-menu-item { + display: flex; + align-items: center; + gap: 8px; + width: 100%; + padding: 8px 12px; + background: none; + border: none; + border-radius: var(--radius-sm); + color: var(--text-primary); + font-size: 13px; + font-family: var(--font-sans); + cursor: pointer; + transition: background var(--transition); + text-align: left; +} + +.chat-context-menu-item:hover { + background: var(--bg-hover); +} diff --git a/src/renderer/src/screens/Chat/MessageRow.tsx b/src/renderer/src/screens/Chat/MessageRow.tsx index 45520aa00..81ea024d6 100644 --- a/src/renderer/src/screens/Chat/MessageRow.tsx +++ b/src/renderer/src/screens/Chat/MessageRow.tsx @@ -1,4 +1,5 @@ -import { memo, useMemo } from "react"; +import { memo, useMemo, useState, useCallback, useEffect, useRef } from "react"; +import { Copy } from "lucide-react"; import icon from "../../assets/icon.png"; import { AgentMarkdown } from "../../components/AgentMarkdown"; import { AttachmentChip } from "../../components/AttachmentChip"; @@ -30,24 +31,21 @@ export const HermesAvatar = memo(function HermesAvatar({ ); }); -/** - * Empty box the size of an avatar. Rendered in place of the avatar on - * continuation rows of a turn (the thinking/tool rows and answer bubble that - * follow the first row) so one turn shows a single avatar while every row - * stays aligned to the same content column. - */ export const AvatarSpacer = memo(function AvatarSpacer(): React.JSX.Element { return ); -}); +}); \ No newline at end of file diff --git a/src/shared/i18n/locales/en/chat.ts b/src/shared/i18n/locales/en/chat.ts index 1a28eae43..375909147 100644 --- a/src/shared/i18n/locales/en/chat.ts +++ b/src/shared/i18n/locales/en/chat.ts @@ -131,6 +131,7 @@ export default { queued: "{{count}} message(s) queued — will send when the agent finishes", queuedCount: "{{count}} queued", queuedAttachment: "{{count}} attachment(s)", + copyMessage: "Copy message", queuedCancel: "Remove from queue", worktree: { loading: "Loading", diff --git a/src/shared/i18n/locales/es/chat.ts b/src/shared/i18n/locales/es/chat.ts index 1cdf05413..7d6744433 100644 --- a/src/shared/i18n/locales/es/chat.ts +++ b/src/shared/i18n/locales/es/chat.ts @@ -107,6 +107,7 @@ export default { version: "Mostrar la versión de Hermes", }, queued: "{{count}} mensaje(s) en cola — se enviará cuando el agente termine", + copyMessage: "Copiar mensaje", queuedCancel: "Quitar de la cola", worktree: { loading: "Cargando", diff --git a/src/shared/i18n/locales/id/chat.ts b/src/shared/i18n/locales/id/chat.ts index bf4a24061..18f927a5b 100644 --- a/src/shared/i18n/locales/id/chat.ts +++ b/src/shared/i18n/locales/id/chat.ts @@ -81,6 +81,7 @@ export default { persona: "Tampilkan persona saat ini", version: "Tampilkan versi Hermes", }, + copyMessage: "Salin pesan", queuedCancel: "Batalkan pesan antrian", worktree: { loading: "Memuat", diff --git a/src/shared/i18n/locales/ja/chat.ts b/src/shared/i18n/locales/ja/chat.ts index 83461d9f9..9bf3b404f 100644 --- a/src/shared/i18n/locales/ja/chat.ts +++ b/src/shared/i18n/locales/ja/chat.ts @@ -80,6 +80,7 @@ export default { persona: "現在のペルソナを表示", version: "Hermes バージョンを表示", }, + copyMessage: "メッセージをコピー", queuedCancel: "キューから削除", worktree: { loading: "読み込み中", diff --git a/src/shared/i18n/locales/pl/chat.ts b/src/shared/i18n/locales/pl/chat.ts index fa5b153c1..aff7cd8b3 100644 --- a/src/shared/i18n/locales/pl/chat.ts +++ b/src/shared/i18n/locales/pl/chat.ts @@ -87,6 +87,7 @@ export default { }, queued: "{{count}} wiadomość/wiadomości w kolejce — zostaną wysłane po zakończeniu pracy agenta", + copyMessage: "Kopiuj wiadomość", queuedCancel: "Usuń z kolejki", worktree: { loading: "Ładowanie", diff --git a/src/shared/i18n/locales/pt-BR/chat.ts b/src/shared/i18n/locales/pt-BR/chat.ts index 1050f2767..7769b01be 100644 --- a/src/shared/i18n/locales/pt-BR/chat.ts +++ b/src/shared/i18n/locales/pt-BR/chat.ts @@ -81,6 +81,7 @@ export default { persona: "Mostrar a persona atual", version: "Mostrar a versão do Hermes", }, + copyMessage: "Copiar mensagem", queuedCancel: "Remover da fila", worktree: { loading: "Carregando", diff --git a/src/shared/i18n/locales/pt-PT/chat.ts b/src/shared/i18n/locales/pt-PT/chat.ts index 819dbc9bf..02a47a598 100644 --- a/src/shared/i18n/locales/pt-PT/chat.ts +++ b/src/shared/i18n/locales/pt-PT/chat.ts @@ -93,6 +93,7 @@ export default { }, queued: "{{count}} mensagem(ns) em fila — serão enviadas quando o agente terminar", + copyMessage: "Copiar mensagem", queuedCancel: "Remover da fila", worktree: { loading: "A carregar", diff --git a/src/shared/i18n/locales/tr/chat.ts b/src/shared/i18n/locales/tr/chat.ts index 40c29f531..a03b11c65 100644 --- a/src/shared/i18n/locales/tr/chat.ts +++ b/src/shared/i18n/locales/tr/chat.ts @@ -104,6 +104,7 @@ export default { version: "Hermes sürümünü göster", }, queued: "{{count}} mesaj sırada — ajan işini bitirince gönderilecek", + copyMessage: "Mesajı kopyala", queuedCancel: "Sıradan kaldır", worktree: { loading: "Yükleniyor", diff --git a/src/shared/i18n/locales/zh-CN/chat.ts b/src/shared/i18n/locales/zh-CN/chat.ts index 49d107459..7a299369e 100644 --- a/src/shared/i18n/locales/zh-CN/chat.ts +++ b/src/shared/i18n/locales/zh-CN/chat.ts @@ -77,6 +77,7 @@ export default { persona: "查看当前人格", version: "查看 Hermes 版本", }, + copyMessage: "复制消息", queuedCancel: "从队列中移除", worktree: { loading: "加载中", diff --git a/src/shared/i18n/locales/zh-TW/chat.ts b/src/shared/i18n/locales/zh-TW/chat.ts index 337c15a67..1937c4249 100644 --- a/src/shared/i18n/locales/zh-TW/chat.ts +++ b/src/shared/i18n/locales/zh-TW/chat.ts @@ -66,6 +66,7 @@ export default { version: "檢視 Hermes 版本", }, queued: "{{count}} 則訊息已排隊 — 代理完成後將自動傳送", + copyMessage: "複製訊息", queuedCancel: "從佇列中移除", worktree: { loading: "載入中",