From 4efa6fb2f2e223fa9f92dc36ccc382b60681c087 Mon Sep 17 00:00:00 2001 From: VPS 4 Deploy Agent Date: Tue, 12 May 2026 03:31:59 +0200 Subject: [PATCH] =?UTF-8?q?fix(media):=20aplica=20estado=20'n=C3=A3o=20dis?= =?UTF-8?q?pon=C3=ADvel'=20a=20imagem,=20v=C3=ADdeo,=20documento=20e=20sti?= =?UTF-8?q?cker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Estende o tratamento de erro 400/404 do redownload para todos os tipos de mídia. Quando mediaUnavailable=true (payload ausente no backend), cada tipo exibe sua mensagem específica e desabilita o clique: - Imagem: 'Imagem não disponível' - Vídeo: 'Vídeo não disponível' - Documento: 'Arquivo não disponível' + cursor-default - Sticker: 'Figurinha não disponível' DocumentBubble recebe nova prop mediaUnavailable para controle interno. Co-Authored-By: Claude Sonnet 4.6 --- .../frontend/components/MessageBubble.tsx | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/clube67/newwhats.local/frontend/components/MessageBubble.tsx b/clube67/newwhats.local/frontend/components/MessageBubble.tsx index 55eebc0..ea27d23 100644 --- a/clube67/newwhats.local/frontend/components/MessageBubble.tsx +++ b/clube67/newwhats.local/frontend/components/MessageBubble.tsx @@ -163,6 +163,7 @@ interface DocumentBubbleProps { TimestampRow: React.ReactNode onRedownload?: () => void isRedownloading?: boolean + mediaUnavailable?: boolean } const DOC_TYPES: Record = { @@ -177,7 +178,7 @@ const DOC_TYPES: Record = { csv: { bg: '#276749', label: 'CSV' }, } -const DocumentBubble: React.FC = ({ msg, fullMediaUrl, TimestampRow, onRedownload, isRedownloading }) => { +const DocumentBubble: React.FC = ({ msg, fullMediaUrl, TimestampRow, onRedownload, isRedownloading, mediaUnavailable }) => { const [previewOpen, setPreviewOpen] = useState(false) // Derive extension from media_type or media_url @@ -203,6 +204,7 @@ const DocumentBubble: React.FC = ({ msg, fullMediaUrl, Time const isPdf = ext === 'pdf' const handleClick = () => { + if (mediaUnavailable) return if (!fullMediaUrl) { onRedownload?.() return @@ -219,7 +221,7 @@ const DocumentBubble: React.FC = ({ msg, fullMediaUrl, Time
{/* Type icon */}
= ({ msg, fullMediaUrl, Time {filename} - {isRedownloading ? 'Baixando...' : `${ext.toUpperCase()}${sizeStr ? ` · ${sizeStr}` : ''}`} + {isRedownloading ? 'Baixando...' : mediaUnavailable ? 'Arquivo não disponível' : `${ext.toUpperCase()}${sizeStr ? ` · ${sizeStr}` : ''}`}
@@ -618,8 +620,8 @@ const MessageBubble: React.FC = ({ return (
fullMediaUrl ? (onOpenMedia ? onOpenMedia(msg) : window.open(fullMediaUrl, '_blank')) : handleRedownload()} + className={`relative group/media w-[268px] h-[200px] bg-black/5 overflow-hidden ${fullMediaUrl || mediaUnavailable ? '' : 'cursor-pointer'}`} + onClick={() => fullMediaUrl ? (onOpenMedia ? onOpenMedia(msg) : window.open(fullMediaUrl, '_blank')) : (mediaUnavailable ? undefined : handleRedownload())} > {fullMediaUrl ? ( = ({ className="w-full h-full object-cover transition-transform group-hover/media:scale-[1.03] block" /> ) : ( -
+
{isRedownloading ?
- : <>Toque para baixar + : <>{mediaUnavailable ? 'Imagem não disponível' : 'Toque para baixar'} }
)} @@ -658,8 +660,8 @@ const MessageBubble: React.FC = ({ return (
fullMediaUrl ? (onOpenMedia ? onOpenMedia(msg) : window.open(fullMediaUrl, '_blank')) : handleRedownload()} + className={`relative w-[268px] h-[200px] bg-black overflow-hidden group/vid ${fullMediaUrl || mediaUnavailable ? '' : 'cursor-pointer'}`} + onClick={() => fullMediaUrl ? (onOpenMedia ? onOpenMedia(msg) : window.open(fullMediaUrl, '_blank')) : (mediaUnavailable ? undefined : handleRedownload())} > {fullMediaUrl ? (
@@ -668,10 +670,10 @@ const MessageBubble: React.FC = ({
) : ( -
+
{isRedownloading ?
- : <>
)} @@ -717,7 +719,7 @@ const MessageBubble: React.FC = ({ } return ; case 'document': - return ; + return ; case 'sticker': return (
@@ -725,14 +727,14 @@ const MessageBubble: React.FC = ({ ? Sticker : (
{isRedownloading ?
: } - {isRedownloading ? 'Baixando...' : 'Toque para baixar figurinha'} + {isRedownloading ? 'Baixando...' : mediaUnavailable ? 'Figurinha não disponível' : 'Toque para baixar figurinha'}
) }