fix: exclude embed thumbnails from image context menu actions

Add data-embed-thumbnail marker to VideoEmbed, GenericEmbed, and
RichEmbed thumbnail containers. Update detection logic to skip
these alongside avatars. Also remove redundant filename derivation
in Save Image menu item.
This commit is contained in:
Jannis Braun
2026-03-25 03:23:23 +01:00
parent 4ea319646a
commit aeb4ea6e1d
5 changed files with 6 additions and 8 deletions
+2 -2
View File
@@ -173,9 +173,9 @@ export function Message({ message, isCompact, isFirstInGroup, previousMessageId
e.stopPropagation(); e.stopPropagation();
const selectedText = window.getSelection()?.toString() ?? ''; const selectedText = window.getSelection()?.toString() ?? '';
// Detect if the right-click target is a content image (not an avatar) // Detect if the right-click target is a content image (not an avatar or embed thumbnail)
const imgEl = (e.target as HTMLElement).closest('img') as HTMLImageElement | null; const imgEl = (e.target as HTMLElement).closest('img') as HTMLImageElement | null;
const isContentImage = imgEl && !imgEl.closest('[data-avatar]'); const isContentImage = imgEl && !imgEl.closest('[data-avatar]') && !imgEl.closest('[data-embed-thumbnail]');
const imageUrl = isContentImage ? imgEl.src : null; const imageUrl = isContentImage ? imgEl.src : null;
const items = buildMessageMenuItems({ const items = buildMessageMenuItems({
@@ -41,7 +41,7 @@ export function GenericEmbed({ embed }: GenericEmbedProps) {
)} )}
</div> </div>
{embed.image && ( {embed.image && (
<div className="w-[80px] h-[80px] m-3 flex-shrink-0"> <div data-embed-thumbnail className="w-[80px] h-[80px] m-3 flex-shrink-0">
<img <img
src={embed.image} src={embed.image}
alt="" alt=""
@@ -50,7 +50,7 @@ export function RichEmbed({ embed }: RichEmbedProps) {
> >
<div className="flex items-start gap-3 p-3"> <div className="flex items-start gap-3 p-3">
{embed.image && ( {embed.image && (
<div className="w-[80px] h-[80px] flex-shrink-0"> <div data-embed-thumbnail className="w-[80px] h-[80px] flex-shrink-0">
<img <img
src={embed.image} src={embed.image}
alt="" alt=""
@@ -45,6 +45,7 @@ export function VideoEmbed({ embed }: VideoEmbedProps) {
) : ( ) : (
<button <button
type="button" type="button"
data-embed-thumbnail
onClick={() => setIsPlaying(true)} onClick={() => setIsPlaying(true)}
className="absolute inset-0 w-full h-full flex items-center justify-center group focus:outline-none" className="absolute inset-0 w-full h-full flex items-center justify-center group focus:outline-none"
aria-label={`Play ${embed.title ?? 'video'}`} aria-label={`Play ${embed.title ?? 'video'}`}
@@ -55,10 +55,7 @@ export function buildMessageMenuItems(params: MessageMenuParams): ContextMenuIte
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z" /> <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z" />
</svg> </svg>
), ),
onClick: () => { onClick: () => saveImage(imageUrl),
const filename = imageUrl.split('/').pop()?.split('?')[0] ?? 'image';
saveImage(imageUrl, filename);
},
}); });
items.push({ items.push({
key: 'copy-image', key: 'copy-image',