fix(audio): trata erro 400/404 no redownload com estado 'Áudio não disponível'

Mensagens antigas sem mediaPayload retornam 400 do backend (sem como
re-solicitar ao WhatsApp). O erro agora é capturado em handleRedownload,
que seta mediaUnavailable=true — o botão fica desabilitado e exibe
'Áudio não disponível' em vez de explodir com Uncaught (in promise).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
VPS 4 Deploy Agent
2026-05-12 03:26:26 +02:00
parent 0af0eba663
commit 5fb9a8f34a
@@ -328,16 +328,20 @@ const MessageBubble: React.FC<MessageBubbleProps> = ({
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
const [listOpen, setListOpen] = useState(false);
const [isRedownloading, setIsRedownloading] = useState(false);
const [mediaUnavailable, setMediaUnavailable] = useState(false);
const handleRedownload = useCallback(async () => {
if (!onRedownloadMedia || isRedownloading) return
if (!onRedownloadMedia || isRedownloading || mediaUnavailable) return
setIsRedownloading(true)
try {
await onRedownloadMedia(msg)
} catch (err: any) {
const status = err?.response?.status ?? err?.status
if (status === 400 || status === 404) setMediaUnavailable(true)
} finally {
setIsRedownloading(false)
}
}, [onRedownloadMedia, msg, isRedownloading])
}, [onRedownloadMedia, msg, isRedownloading, mediaUnavailable])
const isOut = msg.direction === 'out';
const showActionsLeft = isOut;
const showActionsRight = !isOut;
@@ -696,14 +700,16 @@ const MessageBubble: React.FC<MessageBubbleProps> = ({
return (
<div>
<div
onClick={handleRedownload}
className="flex items-center gap-2.5 bg-[#f0f2f5] px-3 py-2.5 rounded-xl border border-black/5 w-[260px] cursor-pointer hover:bg-[#e8eaed] transition-colors"
onClick={mediaUnavailable ? undefined : handleRedownload}
className={`flex items-center gap-2.5 bg-[#f0f2f5] px-3 py-2.5 rounded-xl border border-black/5 w-[260px] transition-colors ${mediaUnavailable ? 'cursor-default opacity-60' : 'cursor-pointer hover:bg-[#e8eaed]'}`}
>
{isRedownloading
? <div className="w-8 h-8 border-2 border-slate-400 border-t-transparent rounded-full animate-spin shrink-0" />
: <div className="w-10 h-10 rounded-full bg-[#8696a0] flex items-center justify-center shrink-0"><Mic className="w-4 h-4 text-white" /></div>
}
<span className="text-[12px] text-[#667781]">{isRedownloading ? 'Baixando...' : 'Toque para baixar áudio'}</span>
<span className="text-[12px] text-[#667781]">
{isRedownloading ? 'Baixando...' : mediaUnavailable ? 'Áudio não disponível' : 'Toque para baixar áudio'}
</span>
</div>
{TimestampRow}
</div>