fix(audio): corrige redownload de áudio + move botão de velocidade antes do waveform
1. MessageArea: handleRedownloadMedia usava selectedChat?.instanceId (undefined no formato legado) — substituído por instance_name ?? instanceId. O clique em 'Toque para baixar áudio' agora chama o backend corretamente. 2. MessageBubble/AudioBubble: botão de velocidade (1×/1.5×/2×) movido para entre o botão play e as barras do waveform, conforme layout do WhatsApp. A linha inferior agora exibe apenas o tempo decorrido. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,10 +61,11 @@ const MessageArea: React.FC<MessageAreaProps> = ({
|
|||||||
|
|
||||||
// ── Re-download de mídia não baixada ─────────────────────────────────────
|
// ── Re-download de mídia não baixada ─────────────────────────────────────
|
||||||
const handleRedownloadMedia = useCallback(async (msg: Message) => {
|
const handleRedownloadMedia = useCallback(async (msg: Message) => {
|
||||||
const instanceId = selectedChat?.instanceId
|
// selectedChat no formato legado usa instance_name (não instanceId)
|
||||||
|
const instanceId = selectedChat?.instance_name ?? selectedChat?.instanceId
|
||||||
if (!instanceId || !msg.id) return
|
if (!instanceId || !msg.id) return
|
||||||
await mediaApi.redownload(instanceId, String(msg.id))
|
await mediaApi.redownload(instanceId, String(msg.id))
|
||||||
}, [selectedChat?.instanceId])
|
}, [selectedChat?.instance_name, selectedChat?.instanceId])
|
||||||
const mediaMessages = messages.filter(m => m.type === 'image' || m.type === 'video')
|
const mediaMessages = messages.filter(m => m.type === 'image' || m.type === 'video')
|
||||||
|
|
||||||
const handleInternalScroll = useCallback(() => {
|
const handleInternalScroll = useCallback(() => {
|
||||||
|
|||||||
@@ -123,7 +123,15 @@ const AudioBubble: React.FC<AudioBubbleProps> = ({ msg, fullMediaUrl, isOut, Tim
|
|||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Waveform + meta */}
|
{/* Speed — antes do waveform, alinhado ao centro vertical */}
|
||||||
|
<button
|
||||||
|
onClick={cycleSpeed}
|
||||||
|
className="text-[11px] font-bold text-[#667781] hover:text-[#111b21] transition-colors leading-none shrink-0 w-7 text-center"
|
||||||
|
>
|
||||||
|
{speed === 1 ? '1×' : speed === 1.5 ? '1.5×' : '2×'}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Waveform + tempo */}
|
||||||
<div className="flex-1 flex flex-col gap-1 min-w-0">
|
<div className="flex-1 flex flex-col gap-1 min-w-0">
|
||||||
<div className="flex items-end gap-[2px] h-7">
|
<div className="flex items-end gap-[2px] h-7">
|
||||||
{waveHeights.map((h, i) => (
|
{waveHeights.map((h, i) => (
|
||||||
@@ -137,17 +145,9 @@ const AudioBubble: React.FC<AudioBubbleProps> = ({ msg, fullMediaUrl, isOut, Tim
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<span className="text-[11px] text-[#667781] tabular-nums leading-none">
|
||||||
<span className="text-[11px] text-[#667781] tabular-nums leading-none">
|
{currentTime > 0 ? formatTime(currentTime) : formatTime(duration)}
|
||||||
{currentTime > 0 ? formatTime(currentTime) : formatTime(duration)}
|
</span>
|
||||||
</span>
|
|
||||||
<button
|
|
||||||
onClick={cycleSpeed}
|
|
||||||
className="text-[11px] font-bold text-[#667781] hover:text-[#111b21] transition-colors leading-none"
|
|
||||||
>
|
|
||||||
{speed === 1 ? '1×' : speed === 1.5 ? '1.5×' : '2×'}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{TimestampRow}
|
{TimestampRow}
|
||||||
|
|||||||
Reference in New Issue
Block a user