import { type AttachmentHandle, downloadAndDecryptAttachment } from '@chat-app/shared/chat'; import { useEffect, useMemo, useRef, useState } from 'react'; import { getCachedAttachment, putCachedAttachment } from '../lib/attachmentCache'; import { getVoiceSpeed, setVoiceSpeed, VOICE_SPEEDS, type VoiceSpeed } from '../lib/voiceSpeedSettings'; import { supabase } from '../lib/supabase'; import { AlertIcon, MicIcon, SpinnerIcon } from './icons'; interface Props { handle: AttachmentHandle; } const BAR_COUNT = 48; // Custom voice-message player with waveform visualisation. Decoded peaks are // computed once per blob via OfflineAudioContext so playback only carries the // rendered DOM. Falls back to a rectangular bar if decoding fails (e.g. the // blob mime is recognised by