@exode-team/react-recorder 1.1.14 → 1.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/components/AudioRecorder.js +50 -0
  2. package/dist/components/AudioRecorder.js.map +1 -0
  3. package/dist/components/AudioRecorder.messages.js +47 -0
  4. package/dist/components/AudioRecorder.messages.js.map +1 -0
  5. package/dist/components/AudioRecorder.styled.js +16 -0
  6. package/dist/components/AudioRecorder.styled.js.map +1 -0
  7. package/dist/components/IdleControl/IdleControl.js +12 -0
  8. package/dist/components/IdleControl/IdleControl.js.map +1 -0
  9. package/dist/components/IdleControl/IdleControl.styled.js +68 -0
  10. package/dist/components/IdleControl/IdleControl.styled.js.map +1 -0
  11. package/dist/components/RecordingShell/RecordingShell.js +80 -0
  12. package/dist/components/RecordingShell/RecordingShell.js.map +1 -0
  13. package/dist/components/RecordingShell/RecordingShell.styled.js +159 -0
  14. package/dist/components/RecordingShell/RecordingShell.styled.js.map +1 -0
  15. package/dist/components/VoiceMessagePlayer/VoiceMessagePlayer.js +151 -0
  16. package/dist/components/VoiceMessagePlayer/VoiceMessagePlayer.js.map +1 -0
  17. package/dist/components/VoiceMessagePlayer/VoiceMessagePlayer.styled.js +92 -0
  18. package/dist/components/VoiceMessagePlayer/VoiceMessagePlayer.styled.js.map +1 -0
  19. package/dist/components/VoiceRecorderInput/PreviewBars.js +52 -0
  20. package/dist/components/VoiceRecorderInput/PreviewBars.js.map +1 -0
  21. package/dist/components/VoiceRecorderInput/TimelineBars.js +31 -0
  22. package/dist/components/VoiceRecorderInput/TimelineBars.js.map +1 -0
  23. package/dist/components/VoiceRecorderInput/VoiceRecorderInput.js +51 -0
  24. package/dist/components/VoiceRecorderInput/VoiceRecorderInput.js.map +1 -0
  25. package/dist/components/VoiceRecorderInput/VoiceRecorderInput.styled.js +175 -0
  26. package/dist/components/VoiceRecorderInput/VoiceRecorderInput.styled.js.map +1 -0
  27. package/dist/components/WaveformBars/WaveformBars.js +29 -0
  28. package/dist/components/WaveformBars/WaveformBars.js.map +1 -0
  29. package/dist/components/WaveformBars/WaveformBars.styled.js +20 -0
  30. package/dist/components/WaveformBars/WaveformBars.styled.js.map +1 -0
  31. package/dist/constants.js +17 -0
  32. package/dist/constants.js.map +1 -0
  33. package/dist/hooks/useAudioBlobLoader.js +175 -0
  34. package/dist/hooks/useAudioBlobLoader.js.map +1 -0
  35. package/dist/hooks/useAudioPlayback.js +119 -0
  36. package/dist/hooks/useAudioPlayback.js.map +1 -0
  37. package/dist/hooks/useAudioRecorderHandlers.js +137 -0
  38. package/dist/hooks/useAudioRecorderHandlers.js.map +1 -0
  39. package/dist/hooks/useMediaRecorder.js +127 -0
  40. package/dist/hooks/useMediaRecorder.js.map +1 -0
  41. package/dist/hooks/useRecorderVisualization.js +94 -0
  42. package/dist/hooks/useRecorderVisualization.js.map +1 -0
  43. package/dist/hooks/useRecordingSender.js +53 -0
  44. package/dist/hooks/useRecordingSender.js.map +1 -0
  45. package/dist/hooks/useRecordingTiming.js +93 -0
  46. package/dist/hooks/useRecordingTiming.js.map +1 -0
  47. package/dist/hooks/useVoiceMessagePlayer.js +177 -0
  48. package/dist/hooks/useVoiceMessagePlayer.js.map +1 -0
  49. package/dist/hooks/useVoiceRecorder.js +153 -0
  50. package/dist/hooks/useVoiceRecorder.js.map +1 -0
  51. package/dist/hooks/useVoiceRecorderInput.js +163 -0
  52. package/dist/hooks/useVoiceRecorderInput.js.map +1 -0
  53. package/dist/index.js +13 -2659
  54. package/dist/index.js.map +1 -1
  55. package/dist/platform/animation-frame-adapter.js +14 -0
  56. package/dist/platform/animation-frame-adapter.js.map +1 -0
  57. package/dist/platform/audio-analyzer-adapter.js +74 -0
  58. package/dist/platform/audio-analyzer-adapter.js.map +1 -0
  59. package/dist/platform/audio-blob-fetcher.js +19 -0
  60. package/dist/platform/audio-blob-fetcher.js.map +1 -0
  61. package/dist/platform/audio-playback-adapter.js +114 -0
  62. package/dist/platform/audio-playback-adapter.js.map +1 -0
  63. package/dist/platform/audio-playback-manager.js +26 -0
  64. package/dist/platform/audio-playback-manager.js.map +1 -0
  65. package/dist/platform/media-recorder-adapter.js +23 -0
  66. package/dist/platform/media-recorder-adapter.js.map +1 -0
  67. package/dist/platform/microphone.js +24 -0
  68. package/dist/platform/microphone.js.map +1 -0
  69. package/dist/platform/mpeg-frame.js +60 -0
  70. package/dist/platform/mpeg-frame.js.map +1 -0
  71. package/dist/utils/format.js +13 -0
  72. package/dist/utils/format.js.map +1 -0
  73. package/dist/utils/math.js +16 -0
  74. package/dist/utils/math.js.map +1 -0
  75. package/dist/utils/pseudo-waveform.js +40 -0
  76. package/dist/utils/pseudo-waveform.js.map +1 -0
  77. package/dist/utils/voice-blob-cache.js +35 -0
  78. package/dist/utils/voice-blob-cache.js.map +1 -0
  79. package/dist/utils/voice-playback-chain.js +42 -0
  80. package/dist/utils/voice-playback-chain.js.map +1 -0
  81. package/package.json +2 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils/math.ts","../src/utils/format.ts","../src/constants.ts","../src/utils/pseudo-waveform.ts","../src/platform/microphone.ts","../src/platform/media-recorder-adapter.ts","../src/platform/audio-playback-adapter.ts","../src/platform/mpeg-frame.ts","../src/platform/audio-analyzer-adapter.ts","../src/platform/audio-blob-fetcher.ts","../src/platform/animation-frame-adapter.ts","../src/hooks/useMediaRecorder.ts","../src/hooks/useAudioPlayback.ts","../src/hooks/useRecordingTiming.ts","../src/hooks/useRecorderVisualization.ts","../src/hooks/useRecordingSender.ts","../src/hooks/useVoiceRecorder.ts","../src/hooks/useAudioBlobLoader.ts","../src/platform/audio-playback-manager.ts","../src/hooks/useVoiceMessagePlayer.ts","../src/hooks/useAudioRecorderHandlers.ts","../src/components/AudioRecorder.styled.ts","../src/components/IdleControl/IdleControl.styled.ts","../src/components/IdleControl/IdleControl.tsx","../src/components/WaveformBars/WaveformBars.styled.tsx","../src/components/WaveformBars/WaveformBars.tsx","../src/components/RecordingShell/RecordingShell.styled.ts","../src/components/RecordingShell/RecordingShell.tsx","../src/components/AudioRecorder.messages.ts","../src/components/AudioRecorder.tsx","../src/hooks/useVoiceRecorderInput.ts","../src/components/VoiceRecorderInput/PreviewBars.tsx","../src/components/VoiceRecorderInput/TimelineBars.tsx","../src/components/VoiceRecorderInput/VoiceRecorderInput.styled.ts","../src/components/VoiceRecorderInput/VoiceRecorderInput.tsx","../src/utils/voice-playback-chain.ts","../src/components/VoiceMessagePlayer/VoiceMessagePlayer.styled.ts","../src/components/VoiceMessagePlayer/VoiceMessagePlayer.tsx","../src/utils/voice-blob-cache.ts"],"sourcesContent":["/**\n * Math utilities\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport const clampValue = (value: number, lowerBound = 0, upperBound = 100): number => {\n const safe = Number.isFinite(value) ? value : 0;\n\n return Math.min(Math.max(safe, lowerBound), upperBound);\n};\n\nexport const roundTo = (value: number, precision = 2): number => {\n const factor = Math.pow(10, precision);\n\n return Math.round(value * factor) / factor;\n};","/**\n * Format utilities\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport const formatTime = (seconds: number): string => {\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n\n return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;\n};","/**\n * AudioRecorder constants\n *\n * @author: exode <hello@exode.ru>\n */\n\nexport const AUDIO_LEVEL_BARS = 40;\n\n/** Waveform decoding resamples to this rate — only the amplitude envelope matters */\nexport const WAVEFORM_SAMPLE_RATE = 44100;\n\nexport const createInitialLevels = (): number[] => Array.from({ length: AUDIO_LEVEL_BARS }, () => 0);\n\nexport const TIMELINE_SAMPLE_INTERVAL = 150;\nexport const TIMELINE_BAR_WIDTH = 3;\nexport const TIMELINE_BAR_GAP = 2;\nexport const TIMELINE_BAR_MIN_HEIGHT = 3;\nexport const TIMELINE_BAR_MAX_HEIGHT = 24;\n","/**\n * Pseudo waveform utilities\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { AUDIO_LEVEL_BARS } from '../constants';\n\nimport { clampValue } from './math';\n\n\n/** Deterministic generator: the same source always draws the same waveform */\nconst seededRandom = (seed: number) => {\n let state = Math.abs(Math.floor(seed)) % 2147483647 || 1;\n\n return () => (state = state * 16807 % 2147483647) / 2147483647;\n};\n\nconst hashString = (value: string): number => {\n let hash = 0;\n\n for (let i = 0; i < value.length; i += 1) {\n hash = (hash * 31 + value.charCodeAt(i)) | 0;\n }\n\n return hash;\n};\n\n/**\n * Decorative levels for runtimes that cannot decode audio at all — WebAudio\n * rejects every mp3 inside iPad apps running on macOS. Purely cosmetic: it\n * stands in for a flat line and says nothing about the recording itself.\n */\nexport const createPseudoLevels = (seed: string, barCount: number = AUDIO_LEVEL_BARS): number[] => {\n const random = seededRandom(hashString(seed));\n const levels: number[] = [];\n\n let level = 45 + random() * 25;\n\n for (let i = 0; i < barCount; i += 1) {\n /** Smooth drift instead of pure noise, so it reads as speech rather than static */\n level = clampValue(level + (random() - 0.5) * 42, 14);\n\n /** Slight fade at both ends — that is how a real recording usually looks */\n levels.push(level * (0.72 + 0.28 * Math.sin((i / (barCount - 1)) * Math.PI)));\n }\n\n return levels;\n};\n","/**\n * Microphone platform adapter\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport type MicErrorKind = 'permission' | 'not-supported' | 'unknown';\n\nexport const classifyMicError = (error: unknown): MicErrorKind => {\n const domError = error instanceof DOMException ? error : null;\n\n if (\n domError?.name === 'NotAllowedError'\n || domError?.name === 'NotFoundError'\n || domError?.name === 'NotReadableError'\n ) {\n return 'permission';\n }\n\n return 'unknown';\n};\n\nexport const requestMicrophoneAccess = async (): Promise<MediaStream> => {\n if (typeof navigator === 'undefined' || !navigator.mediaDevices?.getUserMedia) {\n throw new Error('MediaRecorder is not supported in this browser');\n }\n\n return navigator.mediaDevices.getUserMedia({ audio: true });\n};","/**\n * MediaRecorder platform adapter\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport interface RecorderSession {\n recorder: MediaRecorder;\n stream: MediaStream;\n}\n\nexport interface RecorderSessionCallbacks {\n onDataAvailable: (event: BlobEvent) => void;\n onStop: () => void;\n onPause: () => void;\n onResume: () => void;\n}\n\nexport const createRecorderSession = (\n stream: MediaStream,\n callbacks: RecorderSessionCallbacks,\n options?: { mimeType?: string },\n): RecorderSession => {\n const recorderOptions: MediaRecorderOptions = {};\n\n if (options?.mimeType && MediaRecorder.isTypeSupported(options.mimeType)) {\n recorderOptions.mimeType = options.mimeType;\n }\n\n const recorder = new MediaRecorder(stream, recorderOptions);\n\n recorder.ondataavailable = callbacks.onDataAvailable;\n recorder.onstop = callbacks.onStop;\n recorder.onpause = callbacks.onPause;\n recorder.onresume = callbacks.onResume;\n\n return { recorder, stream };\n};\n\nexport const stopStream = (stream: MediaStream): void => {\n stream.getTracks().forEach((track) => track.stop());\n};","/**\n * Audio playback platform adapter\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport interface AudioPlayback {\n audio: HTMLAudioElement;\n url: string;\n}\n\nexport interface PlaybackCallbacks {\n onLoadedMetadata: (duration: number) => void;\n onTimeUpdate: (currentTime: number) => void;\n onEnded: () => void;\n onPlay?: () => void;\n onPause?: () => void;\n onStop?: () => void;\n onSeekBackward?: () => void;\n onSeekForward?: () => void;\n onPreviousTrack?: () => void;\n onNextTrack?: () => void;\n}\n\nconst SEEK_OFFSET = 5;\n\nconst setupMediaSession = (audio: HTMLAudioElement, callbacks: PlaybackCallbacks): void => {\n if (!('mediaSession' in navigator)) {\n return;\n }\n\n navigator.mediaSession.setActionHandler('play', () => {\n audio.play().catch(() => {});\n });\n\n navigator.mediaSession.setActionHandler('pause', () => {\n audio.pause();\n });\n\n navigator.mediaSession.setActionHandler('stop', () => {\n audio.pause();\n audio.currentTime = 0;\n callbacks.onStop?.();\n });\n\n navigator.mediaSession.setActionHandler('seekbackward', () => {\n audio.currentTime = Math.max(0, audio.currentTime - SEEK_OFFSET);\n callbacks.onSeekBackward?.();\n });\n\n navigator.mediaSession.setActionHandler('seekforward', () => {\n audio.currentTime = Math.min(audio.duration, audio.currentTime + SEEK_OFFSET);\n callbacks.onSeekForward?.();\n });\n\n navigator.mediaSession.setActionHandler('seekto', (details) => {\n if (details.seekTime != null && isFinite(audio.duration)) {\n audio.currentTime = details.seekTime;\n }\n });\n\n navigator.mediaSession.setActionHandler('previoustrack', () => {\n callbacks.onPreviousTrack?.();\n });\n\n navigator.mediaSession.setActionHandler('nexttrack', () => {\n callbacks.onNextTrack?.();\n });\n};\n\nconst clearMediaSession = (): void => {\n if (!('mediaSession' in navigator)) {\n return;\n }\n\n const actions: MediaSessionAction[] = [\n 'play', 'pause', 'stop',\n 'seekbackward', 'seekforward', 'seekto',\n 'previoustrack', 'nexttrack',\n ];\n\n actions.forEach((action) => {\n navigator.mediaSession.setActionHandler(action, null);\n });\n\n navigator.mediaSession.playbackState = 'none';\n};\n\nexport const createAudioPlayback = (url: string, callbacks: PlaybackCallbacks): AudioPlayback => {\n const audio = new Audio(url);\n\n /**\n * A detached element is not reliably rendered by every WebKit runtime\n * (notably iPad apps running on macOS), so keep it in the document.\n */\n audio.style.display = 'none';\n document.body.appendChild(audio);\n\n audio.onloadedmetadata = () => {\n callbacks.onLoadedMetadata(audio.duration);\n };\n\n audio.ontimeupdate = () => {\n callbacks.onTimeUpdate(audio.currentTime);\n };\n\n audio.onended = () => {\n callbacks.onEnded();\n };\n\n audio.onplay = () => {\n setupMediaSession(audio, callbacks);\n\n if ('mediaSession' in navigator) {\n navigator.mediaSession.playbackState = 'playing';\n }\n\n callbacks.onPlay?.();\n };\n\n audio.onpause = () => {\n if ('mediaSession' in navigator) {\n navigator.mediaSession.playbackState = 'paused';\n }\n\n callbacks.onPause?.();\n };\n\n return { audio, url };\n};\n\nexport const cleanupAudio = (audio: HTMLAudioElement): void => {\n audio.pause();\n audio.remove();\n audio.src = '';\n audio.onended = null;\n audio.ontimeupdate = null;\n audio.onloadedmetadata = null;\n audio.onplay = null;\n audio.onpause = null;\n clearMediaSession();\n};\n\nexport const createObjectURL = (blob: Blob): string => {\n return URL.createObjectURL(blob);\n};\n\nexport const revokeObjectURL = (url: string): void => {\n URL.revokeObjectURL(url);\n};\n","/**\n * MPEG frame scanner\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nconst MPEG_LAYER_III = 1;\nconst MPEG_SAMPLE_RATES = [ 44100, 48000, 32000 ];\nconst MPEG_BITRATES_V1 = [ 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 ];\nconst MPEG_BITRATES_V2 = [ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 ];\n\n/** Length of the Layer III frame at the given offset, or 0 when it is not one */\nconst readFrameLength = (bytes: Uint8Array, offset: number): number => {\n if (offset + 3 >= bytes.length || bytes[offset] !== 0xff || (bytes[offset + 1] & 0xe0) !== 0xe0) {\n return 0;\n }\n\n /** Version ids: 0 = MPEG 2.5, 1 = reserved, 2 = MPEG 2, 3 = MPEG 1 */\n const version = (bytes[offset + 1] >> 3) & 0x03;\n const layer = (bytes[offset + 1] >> 1) & 0x03;\n const bitrateIndex = (bytes[offset + 2] >> 4) & 0x0f;\n const sampleRateIndex = (bytes[offset + 2] >> 2) & 0x03;\n\n const isReserved = version === 1\n || layer !== MPEG_LAYER_III\n || sampleRateIndex === 3\n || bitrateIndex === 0\n || bitrateIndex === 0x0f;\n\n if (isReserved) {\n return 0;\n }\n\n const isVersion1 = version === 3;\n const padding = (bytes[offset + 2] >> 1) & 0x01;\n const bitrate = (isVersion1 ? MPEG_BITRATES_V1 : MPEG_BITRATES_V2)[bitrateIndex] * 1000;\n const sampleRate = MPEG_SAMPLE_RATES[sampleRateIndex] / (isVersion1 ? 1 : version === 2 ? 2 : 4);\n\n return Math.floor((isVersion1 ? 144 : 72) * bitrate / sampleRate) + padding;\n};\n\n/**\n * Some mp3 (e.g. converted from wma) keep junk between the ID3 tag and the\n * first MPEG frame: media elements skip it, the WebAudio decoder does not.\n * Returns the offset of the first real frame, or 0 when there is none.\n */\nexport const findFirstFrameOffset = (bytes: Uint8Array): number => {\n let start = 0;\n\n /** ID3v2 header: \"ID3\" + version + flags + 4 syncsafe size bytes */\n if (bytes.length >= 10 && bytes[0] === 0x49 && bytes[1] === 0x44 && bytes[2] === 0x33) {\n start = 10 + ((bytes[6] << 21) | (bytes[7] << 14) | (bytes[8] << 7) | bytes[9]);\n\n /** ID3v2.4 may append a 10 byte footer copy of the header */\n if (bytes[5] & 0x10) {\n start += 10;\n }\n }\n\n for (let i = start; i < bytes.length - 3; i += 1) {\n const length = readFrameLength(bytes, i);\n\n /** Junk can open with a valid looking header, so require the next frame to follow */\n if (length && readFrameLength(bytes, i + length)) {\n return i;\n }\n }\n\n return 0;\n};\n","/**\n * Audio analyzer platform adapter\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { AUDIO_LEVEL_BARS, WAVEFORM_SAMPLE_RATE } from '../constants';\n\nimport { findFirstFrameOffset } from './mpeg-frame';\n\n\nexport interface StreamAnalyzer {\n context: AudioContext;\n analyser: AnalyserNode;\n}\n\nexport const createStreamAnalyzer = (stream: MediaStream): StreamAnalyzer => {\n const context = new AudioContext();\n const analyser = context.createAnalyser();\n const source = context.createMediaStreamSource(stream);\n\n source.connect(analyser);\n analyser.fftSize = 256;\n\n return { context, analyser };\n};\n\nexport const readFrequencyLevels = (analyser: AnalyserNode, barCount: number = AUDIO_LEVEL_BARS): number[] => {\n const bufferLength = analyser.frequencyBinCount;\n const dataArray = new Uint8Array(bufferLength);\n\n analyser.getByteFrequencyData(dataArray);\n\n const step = Math.max(1, Math.floor(bufferLength / barCount));\n const levels: number[] = [];\n\n for (let i = 0; i < barCount; i += 1) {\n const value = dataArray[i * step] ?? 0;\n levels.push((value / 255) * 100);\n }\n\n return levels;\n};\n\n/** decodeAudioData detaches the buffer, so the retry re-reads the blob */\nconst decodeSkippingJunk = async (context: BaseAudioContext, blob: Blob): Promise<AudioBuffer> => {\n try {\n return await context.decodeAudioData(await blob.arrayBuffer());\n } catch (error) {\n const bytes = new Uint8Array(await blob.arrayBuffer());\n const offset = findFirstFrameOffset(bytes);\n\n if (!offset) {\n throw error;\n }\n\n return context.decodeAudioData(bytes.buffer.slice(offset));\n }\n};\n\nexport const decodeAudioLevels = async (\n blob: Blob,\n barCount: number = AUDIO_LEVEL_BARS,\n): Promise<number[]> => {\n /**\n * Offline rendering keeps the audio hardware untouched. Runtimes that\n * cannot decode at all (iPad apps on macOS reject every mp3) fall through\n * to the caller, which draws a placeholder waveform instead.\n */\n const context = new OfflineAudioContext(1, 1, WAVEFORM_SAMPLE_RATE);\n\n const audioBuffer = await decodeSkippingJunk(context, blob);\n const channelData = audioBuffer.getChannelData(0);\n\n if (!channelData.length) {\n return Array.from({ length: barCount }, () => 0);\n }\n\n const levels: number[] = [];\n const segmentLength = Math.max(1, Math.floor(channelData.length / barCount));\n\n for (let i = 0; i < barCount; i += 1) {\n const segmentStart = i * segmentLength;\n let sum = 0;\n\n for (let j = 0; j < segmentLength; j += 1) {\n const sample = channelData[segmentStart + j];\n if (sample !== undefined) {\n sum += Math.abs(sample);\n }\n }\n\n const average = sum / segmentLength;\n levels.push(Math.min(100, average * 200));\n }\n\n return levels;\n};","/**\n * Audio blob fetcher platform adapter\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport const fetchAudioBlob = async (\n url: string,\n signal?: AbortSignal,\n): Promise<Blob> => {\n const response = await fetch(url, {\n signal,\n mode: 'cors',\n credentials: 'omit',\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch audio: ${response.status}`);\n }\n\n return response.blob();\n};\n","/**\n * Animation frame platform adapter\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport const scheduleFrame = (callback: FrameRequestCallback): number => {\n return requestAnimationFrame(callback);\n};\n\nexport const cancelFrame = (id: number): void => {\n cancelAnimationFrame(id);\n};","/**\n * useMediaRecorder\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback, useRef, useState } from 'react';\n\nimport { classifyMicError, createRecorderSession, requestMicrophoneAccess, stopStream } from '../platform';\n\nimport type { MediaRecorderCallbacks } from '../types';\n\n\ninterface UseMediaRecorderResult {\n isRecording: boolean;\n isPaused: boolean;\n startRecording: (mimeType: string) => Promise<void>;\n stopRecording: () => void;\n cancelRecording: () => void;\n togglePause: () => void;\n cleanupStream: () => void;\n}\n\nconst useMediaRecorder = (callbacks: MediaRecorderCallbacks): UseMediaRecorderResult => {\n\n const [ isRecording, setIsRecording ] = useState(false);\n const [ isPaused, setIsPaused ] = useState(false);\n\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const mediaStreamRef = useRef<MediaStream | null>(null);\n const audioChunksRef = useRef<Blob[]>([]);\n const discardRef = useRef(false);\n const needsPreviewRef = useRef(false);\n\n const cleanupStream = useCallback(() => {\n if (mediaStreamRef.current) {\n stopStream(mediaStreamRef.current);\n mediaStreamRef.current = null;\n }\n }, []);\n\n const startRecording = useCallback(async (mimeType: string) => {\n try {\n const stream = await requestMicrophoneAccess();\n\n mediaStreamRef.current = stream;\n callbacks.onStreamAcquired(stream);\n\n audioChunksRef.current = [];\n discardRef.current = false;\n\n const { recorder } = createRecorderSession(stream, {\n onDataAvailable: (event) => {\n if (event.data.size > 0) {\n audioChunksRef.current.push(event.data);\n callbacks.onDataChunk(event.data);\n }\n\n if (needsPreviewRef.current) {\n callbacks.onNeedsPreview(audioChunksRef.current);\n needsPreviewRef.current = false;\n }\n },\n onStop: () => {\n const discarded = discardRef.current;\n\n discardRef.current = false;\n mediaRecorderRef.current = null;\n cleanupStream();\n setIsRecording(false);\n setIsPaused(false);\n\n callbacks.onStopped(audioChunksRef.current, discarded);\n },\n onPause: () => {\n setIsPaused(true);\n callbacks.onPaused();\n },\n onResume: () => {\n setIsPaused(false);\n needsPreviewRef.current = false;\n callbacks.onResumed();\n },\n }, { mimeType });\n\n mediaRecorderRef.current = recorder;\n recorder.start();\n setIsRecording(true);\n setIsPaused(false);\n } catch (error) {\n console.error('[audio-recorder] Error accessing microphone:', error);\n\n const kind = classifyMicError(error);\n\n if (kind === 'permission') {\n callbacks.onPermissionDenied(error);\n } else {\n callbacks.onError(error);\n }\n }\n }, [ callbacks, cleanupStream ]);\n\n const stopRecording = useCallback(() => {\n if (!mediaRecorderRef.current || !isRecording) {\n return;\n }\n\n if (mediaRecorderRef.current.state === 'paused') {\n mediaRecorderRef.current.resume();\n }\n\n mediaRecorderRef.current.stop();\n }, [ isRecording ]);\n\n const cancelRecording = useCallback(() => {\n if (!mediaRecorderRef.current) {\n return;\n }\n\n discardRef.current = true;\n needsPreviewRef.current = false;\n\n if (mediaRecorderRef.current.state !== 'inactive') {\n mediaRecorderRef.current.stop();\n }\n }, []);\n\n const togglePause = useCallback(() => {\n if (!mediaRecorderRef.current || !isRecording) {\n return;\n }\n\n if (mediaRecorderRef.current.state === 'recording') {\n needsPreviewRef.current = true;\n\n try {\n mediaRecorderRef.current.requestData();\n } catch (error) {\n console.warn('[audio-recorder] requestData failed', error);\n }\n\n mediaRecorderRef.current.pause();\n } else if (mediaRecorderRef.current.state === 'paused') {\n needsPreviewRef.current = false;\n mediaRecorderRef.current.resume();\n }\n }, [ isRecording ]);\n\n return {\n isPaused,\n isRecording,\n togglePause,\n cleanupStream,\n stopRecording,\n startRecording,\n cancelRecording,\n };\n};\n\n\nexport { useMediaRecorder };\n","/**\n * useAudioPlayback\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback, useRef, useState } from 'react';\n\nimport { cleanupAudio, createAudioPlayback, createObjectURL, revokeObjectURL } from '../platform';\n\n\ninterface UseAudioPlaybackResult {\n audioURL: string | null;\n isPlaying: boolean;\n playbackTime: number;\n playbackDuration: number;\n mountBlob: (blob: Blob) => string;\n togglePlayback: (onError?: (error: unknown) => void) => void;\n stopPlayback: () => void;\n resetPlayback: () => void;\n cleanupAudioElement: () => void;\n}\n\nconst useAudioPlayback = (): UseAudioPlaybackResult => {\n\n const [ audioURL, setAudioURL ] = useState<string | null>(null);\n const [ isPlaying, setIsPlaying ] = useState(false);\n const [ playbackTime, setPlaybackTime ] = useState(0);\n const [ playbackDuration, setPlaybackDuration ] = useState(0);\n\n const audioRef = useRef<HTMLAudioElement | null>(null);\n\n const cleanupAudioElement = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) {\n return;\n }\n\n cleanupAudio(audio);\n audioRef.current = null;\n }, []);\n\n const setAudioUrlSafely = useCallback((value: string | null) => {\n setAudioURL((prev) => {\n if (prev) {\n revokeObjectURL(prev);\n }\n\n return value;\n });\n }, []);\n\n const resetPlayback = useCallback(() => {\n setPlaybackTime(0);\n setPlaybackDuration(0);\n setIsPlaying(false);\n setAudioUrlSafely(null);\n cleanupAudioElement();\n }, [ cleanupAudioElement, setAudioUrlSafely ]);\n\n const mountBlob = useCallback((blob: Blob): string => {\n const url = createObjectURL(blob);\n\n setAudioUrlSafely(url);\n cleanupAudioElement();\n\n const { audio } = createAudioPlayback(url, {\n onLoadedMetadata: (duration) => setPlaybackDuration(duration),\n onTimeUpdate: (currentTime) => setPlaybackTime(currentTime),\n onEnded: () => {\n setIsPlaying(false);\n setPlaybackTime(0);\n },\n onPlay: () => setIsPlaying(true),\n onPause: () => setIsPlaying(false),\n });\n\n audioRef.current = audio;\n setPlaybackTime(0);\n setPlaybackDuration(0);\n setIsPlaying(false);\n\n return url;\n }, [ cleanupAudioElement, setAudioUrlSafely ]);\n\n const togglePlayback = useCallback((onError?: (error: unknown) => void) => {\n if (!audioURL) {\n return;\n }\n\n if (!audioRef.current) {\n const { audio } = createAudioPlayback(audioURL, {\n onLoadedMetadata: (duration) => setPlaybackDuration(duration),\n onTimeUpdate: (currentTime) => setPlaybackTime(currentTime),\n onEnded: () => {\n setIsPlaying(false);\n setPlaybackTime(0);\n },\n onPlay: () => setIsPlaying(true),\n onPause: () => setIsPlaying(false),\n });\n\n audioRef.current = audio;\n }\n\n const audio = audioRef.current;\n if (!audio) {\n return;\n }\n\n if (audio.paused) {\n if (audio.duration > 0 && playbackDuration > 0) {\n audio.currentTime = Math.min(playbackTime, audio.duration);\n }\n\n audio.play()\n .then(() => setIsPlaying(true))\n .catch((error) => {\n setIsPlaying(false);\n onError?.(error);\n });\n } else {\n audio.pause();\n setIsPlaying(false);\n }\n }, [ audioURL, playbackDuration, playbackTime ]);\n\n const stopPlayback = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) {\n return;\n }\n\n audio.pause();\n audio.currentTime = 0;\n setIsPlaying(false);\n setPlaybackTime(0);\n }, []);\n\n return {\n audioURL,\n isPlaying,\n mountBlob,\n playbackTime,\n stopPlayback,\n resetPlayback,\n togglePlayback,\n playbackDuration,\n cleanupAudioElement,\n };\n};\n\n\nexport { useAudioPlayback };\n","/**\n * useRecordingTiming\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { roundTo } from '../utils';\n\n\ninterface UseRecordingTimingResult {\n recordingTime: number;\n lastDuration: number;\n getElapsedMs: () => number;\n pauseSession: () => void;\n resetSession: () => void;\n resumeSession: () => void;\n startNewSession: () => void;\n}\n\nconst useRecordingTiming = (): UseRecordingTimingResult => {\n\n const [ lastDuration, setLastDuration ] = useState(0);\n const [ recordingTime, setRecordingTime ] = useState(0);\n\n const timerRef = useRef<NodeJS.Timeout | null>(null);\n const recordingStartRef = useRef<number | null>(null);\n const recordingAccumulatedRef = useRef(0);\n\n const stopTicker = useCallback(() => {\n if (timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n }, []);\n\n const startTicker = useCallback(() => {\n if (timerRef.current) {\n clearInterval(timerRef.current);\n }\n\n timerRef.current = setInterval(() => {\n if (recordingStartRef.current === null) {\n setRecordingTime(roundTo(recordingAccumulatedRef.current));\n\n return;\n }\n\n const elapsed =\n (performance.now() - recordingStartRef.current) / 1000 +\n recordingAccumulatedRef.current;\n setRecordingTime(roundTo(elapsed));\n }, 100);\n }, []);\n\n const startNewSession = useCallback(() => {\n recordingAccumulatedRef.current = 0;\n setRecordingTime(0);\n setLastDuration(0);\n\n recordingStartRef.current = performance.now();\n startTicker();\n }, [ startTicker ]);\n\n const resumeSession = useCallback(() => {\n recordingStartRef.current = performance.now();\n startTicker();\n }, [ startTicker ]);\n\n const pauseSession = useCallback(() => {\n if (recordingStartRef.current === null) {\n return;\n }\n\n const elapsed = (performance.now() - recordingStartRef.current) / 1000;\n recordingAccumulatedRef.current += elapsed;\n recordingStartRef.current = null;\n\n setRecordingTime(roundTo(recordingAccumulatedRef.current));\n stopTicker();\n }, [ stopTicker ]);\n\n const getElapsedMs = useCallback(() => {\n const accumulated = recordingAccumulatedRef.current;\n\n const elapsed = recordingStartRef.current !== null\n ? (performance.now() - recordingStartRef.current) / 1000 + accumulated\n : accumulated;\n\n return Math.round(elapsed * 1000);\n }, []);\n\n const resetSession = useCallback(() => {\n const accumulated = recordingAccumulatedRef.current;\n\n const elapsed = recordingStartRef.current !== null\n ? (performance.now() - recordingStartRef.current) / 1000 + accumulated\n : accumulated;\n\n if (elapsed > 0) {\n setLastDuration(roundTo(elapsed));\n }\n\n stopTicker();\n recordingStartRef.current = null;\n recordingAccumulatedRef.current = 0;\n setRecordingTime(0);\n }, [ stopTicker ]);\n\n useEffect(() => {\n return () => {\n stopTicker();\n };\n }, [ stopTicker ]);\n\n return {\n lastDuration,\n getElapsedMs,\n pauseSession,\n resetSession,\n recordingTime,\n resumeSession,\n startNewSession,\n };\n};\n\n\nexport { useRecordingTiming };\n","/**\n * useRecorderVisualization\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback, useRef, useState } from 'react';\n\nimport { createInitialLevels } from '../constants';\n\nimport type { StreamAnalyzer } from '../platform';\nimport { cancelFrame, createStreamAnalyzer, decodeAudioLevels, readFrequencyLevels, scheduleFrame } from '../platform';\n\n\ninterface UseRecorderVisualizationResult {\n audioLevels: number[];\n previewLevels: number[];\n resetAudioLevels: () => void;\n resetPreviewLevels: () => void;\n resumeVisualization: () => void;\n cleanupVisualization: () => void;\n generatePreviewLevels: (blob: Blob) => Promise<void>;\n initializeVisualization: (stream: MediaStream) => void;\n stopVisualization: (options?: { resetLevels?: boolean; closeContext?: boolean }) => void;\n}\n\n\nconst useRecorderVisualization = (): UseRecorderVisualizationResult => {\n\n const [ audioLevels, setAudioLevels ] = useState<number[]>(createInitialLevels);\n const [ previewLevels, setPreviewLevels ] = useState<number[]>(createInitialLevels);\n\n const analyzerRef = useRef<StreamAnalyzer | null>(null);\n const animationFrameRef = useRef<number | null>(null);\n\n const resetAudioLevels = useCallback(() => {\n setAudioLevels(createInitialLevels);\n }, []);\n\n const resetPreviewLevels = useCallback(() => {\n setPreviewLevels(createInitialLevels);\n }, []);\n\n const stopVisualization = useCallback(\n (options?: { resetLevels?: boolean; closeContext?: boolean }) => {\n if (animationFrameRef.current) {\n cancelFrame(animationFrameRef.current);\n animationFrameRef.current = null;\n }\n\n if ((options?.closeContext ?? true) && analyzerRef.current) {\n void analyzerRef.current.context.close();\n analyzerRef.current = null;\n }\n\n if (options?.resetLevels ?? true) {\n resetAudioLevels();\n }\n },\n [ resetAudioLevels ],\n );\n\n const visualize = useCallback(() => {\n if (!analyzerRef.current) {\n return;\n }\n\n const { analyser } = analyzerRef.current;\n\n const draw = () => {\n animationFrameRef.current = scheduleFrame(draw);\n\n const levels = readFrequencyLevels(analyser);\n setAudioLevels(levels);\n };\n\n draw();\n }, []);\n\n const resumeVisualization = useCallback(() => {\n if (analyzerRef.current && !animationFrameRef.current) {\n visualize();\n }\n }, [ visualize ]);\n\n const initializeVisualization = useCallback(\n (stream: MediaStream) => {\n analyzerRef.current = createStreamAnalyzer(stream);\n visualize();\n },\n [ visualize ],\n );\n\n const generatePreviewLevels = useCallback(async (blob: Blob) => {\n try {\n const levels = await decodeAudioLevels(blob);\n\n setAudioLevels(levels);\n setPreviewLevels(levels);\n } catch (error) {\n console.warn('[audio-recorder] Failed to build waveform preview', error);\n setPreviewLevels(createInitialLevels());\n }\n }, []);\n\n const cleanupVisualization = useCallback(() => {\n if (animationFrameRef.current) {\n cancelFrame(animationFrameRef.current);\n }\n\n animationFrameRef.current = null;\n\n if (analyzerRef.current) {\n void analyzerRef.current.context.close();\n analyzerRef.current = null;\n }\n\n resetAudioLevels();\n resetPreviewLevels();\n }, [ resetAudioLevels, resetPreviewLevels ]);\n\n return {\n audioLevels,\n previewLevels,\n resetAudioLevels,\n stopVisualization,\n resetPreviewLevels,\n resumeVisualization,\n cleanupVisualization,\n generatePreviewLevels,\n initializeVisualization,\n };\n};\n\n\nexport { useRecorderVisualization };\n","/**\n * useRecordingSender — handles sending a recorded voice message via an upload strategy.\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback } from 'react';\n\nimport type { UploadStrategy } from '../types';\n\n\ninterface UseRecordingSenderOptions<TFile> {\n fileName: string;\n mimeType: string;\n audioBlob: Blob | null;\n uploadId: string;\n getDurationMs: () => number;\n uploader?: UploadStrategy<TFile>;\n onUploaded: (file: TFile, duration: number) => void | Promise<void>;\n deleteRecording: () => void;\n autoResetAfterUpload: boolean;\n onRecordingError?: (error: unknown) => void;\n}\n\n\nconst useRecordingSender = <TFile = unknown>(options: UseRecordingSenderOptions<TFile>) => {\n\n const {\n uploader,\n fileName,\n mimeType,\n uploadId,\n audioBlob,\n onUploaded,\n getDurationMs,\n onRecordingError,\n deleteRecording,\n autoResetAfterUpload,\n } = options;\n\n const sendRecording = useCallback(async () => {\n if (!audioBlob) {\n const error = new Error('Voice recording is not available');\n\n onRecordingError?.(error);\n\n return;\n }\n\n if (!uploader) {\n const error = new Error('Uploader strategy is not defined');\n\n onRecordingError?.(error);\n throw error;\n }\n\n try {\n const durationMs = getDurationMs();\n const durationSec = durationMs / 1000;\n\n const file = new File([ audioBlob ], fileName, {\n type: audioBlob.type || mimeType,\n });\n\n const uploaded = await uploader(file, { uploadId });\n await onUploaded(uploaded as TFile, durationSec);\n\n if (autoResetAfterUpload) {\n deleteRecording();\n }\n } catch (error) {\n onRecordingError?.(error);\n throw error;\n }\n }, [\n uploadId,\n uploader,\n fileName,\n audioBlob,\n mimeType,\n onUploaded,\n getDurationMs,\n deleteRecording,\n onRecordingError,\n autoResetAfterUpload,\n ]);\n\n return { sendRecording };\n};\n\n\nexport { useRecordingSender };\n","/**\n * useVoiceRecorder\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { formatTime } from '../utils';\nimport { useMediaRecorder } from './useMediaRecorder';\nimport { useAudioPlayback } from './useAudioPlayback';\nimport { useRecordingTiming } from './useRecordingTiming';\nimport { useRecorderVisualization } from './useRecorderVisualization';\nimport { useRecordingSender } from './useRecordingSender';\n\nimport type { UseVoiceRecorderOptions, UseVoiceRecorderResult } from '../types';\n\n\nfunction useVoiceRecorder<TFile = unknown>(props: UseVoiceRecorderOptions<TFile>): UseVoiceRecorderResult {\n\n const {\n uploadId,\n uploader,\n onUploaded,\n onRecordingStop,\n onRecordingStart,\n onRecordingError,\n onRecordingDelete,\n onPermissionDenied,\n fileName = 'record.webm',\n mimeType = 'audio/webm',\n autoResetAfterUpload = true,\n } = props;\n\n const [ audioBlob, setAudioBlob ] = useState<Blob | null>(null);\n\n const {\n audioURL,\n isPlaying,\n mountBlob,\n playbackTime,\n stopPlayback,\n resetPlayback,\n togglePlayback: _togglePlayback,\n playbackDuration,\n } = useAudioPlayback();\n\n const {\n audioLevels,\n previewLevels,\n resetAudioLevels,\n stopVisualization,\n resetPreviewLevels,\n resumeVisualization,\n cleanupVisualization,\n generatePreviewLevels,\n initializeVisualization,\n } = useRecorderVisualization();\n\n const {\n lastDuration,\n getElapsedMs,\n recordingTime,\n pauseSession,\n resetSession,\n resumeSession,\n startNewSession,\n } = useRecordingTiming();\n\n const resetCurrentRecording = useCallback(\n (opts?: { resetPreview?: boolean; resetLevels?: boolean; notifyDelete?: boolean }) => {\n setAudioBlob(null);\n resetPlayback();\n if (opts?.resetPreview ?? true) {\n resetPreviewLevels();\n }\n if (opts?.resetLevels) {\n resetAudioLevels();\n }\n if (opts?.notifyDelete) {\n onRecordingDelete?.();\n }\n },\n [ onRecordingDelete, resetAudioLevels, resetPlayback, resetPreviewLevels ],\n );\n\n const deleteRecording = useCallback(() => {\n resetCurrentRecording({\n resetLevels: true,\n notifyDelete: true,\n });\n\n resetSession();\n }, [ resetCurrentRecording, resetSession ]);\n\n const { sendRecording } = useRecordingSender<TFile>({\n audioBlob,\n fileName,\n mimeType,\n uploadId,\n uploader,\n onUploaded,\n deleteRecording,\n onRecordingError,\n autoResetAfterUpload,\n getDurationMs: getElapsedMs,\n });\n\n const mountRecordingBlob = useCallback((blob: Blob) => {\n setAudioBlob(blob);\n mountBlob(blob);\n }, [ mountBlob ]);\n\n const recorderCallbacks = useMemo(() => ({\n onDataChunk: () => {},\n onNeedsPreview: (chunks: Blob[]) => {\n const snapshot = new Blob(chunks, { type: mimeType });\n mountRecordingBlob(snapshot);\n void generatePreviewLevels(snapshot);\n },\n onStopped: (chunks: Blob[], discarded: boolean) => {\n pauseSession();\n stopVisualization({ resetLevels: false });\n\n if (discarded) {\n resetCurrentRecording({ notifyDelete: true });\n resetSession();\n return;\n }\n\n const blob = new Blob(chunks, { type: mimeType });\n onRecordingStop?.(blob);\n mountRecordingBlob(blob);\n void generatePreviewLevels(blob);\n resetSession();\n },\n onPaused: () => {\n pauseSession();\n stopVisualization({ resetLevels: false, closeContext: false });\n },\n onResumed: () => {\n resumeSession();\n resumeVisualization();\n },\n onStreamAcquired: (stream: MediaStream) => {\n initializeVisualization(stream);\n },\n onPermissionDenied: (error: unknown) => {\n onPermissionDenied?.(error);\n },\n onError: (error: unknown) => {\n onRecordingError?.(error);\n },\n }), [\n generatePreviewLevels,\n initializeVisualization,\n mimeType,\n mountRecordingBlob,\n onPermissionDenied,\n onRecordingError,\n onRecordingStop,\n pauseSession,\n resetCurrentRecording,\n resetSession,\n resumeSession,\n resumeVisualization,\n stopVisualization,\n ]);\n\n const {\n isPaused,\n isRecording,\n togglePause,\n cleanupStream,\n stopRecording,\n cancelRecording,\n startRecording: _startRecording,\n } = useMediaRecorder(recorderCallbacks);\n\n const startRecording = useCallback(async () => {\n resetCurrentRecording({ resetLevels: true });\n await _startRecording(mimeType);\n onRecordingStart?.();\n startNewSession();\n }, [ _startRecording, mimeType, onRecordingStart, resetCurrentRecording, startNewSession ]);\n\n useEffect(() => {\n return () => {\n cleanupVisualization();\n cleanupStream();\n resetPlayback();\n resetSession();\n };\n }, [ cleanupVisualization, cleanupStream, resetPlayback, resetSession ]);\n\n const togglePlayback = useCallback(() => {\n _togglePlayback(onRecordingError);\n }, [ _togglePlayback, onRecordingError ]);\n\n return {\n audioURL,\n isPaused,\n isPlaying,\n isRecording,\n audioLevels,\n lastDuration,\n playbackTime,\n recordingTime,\n previewLevels,\n playbackDuration,\n formatTime,\n stopPlayback,\n sendRecording,\n stopRecording,\n togglePlayback,\n startRecording,\n cancelRecording,\n deleteRecording,\n toggleRecordingPause: togglePause,\n hasRecording: Boolean(audioURL),\n };\n}\n\n\nexport { useVoiceRecorder };\n","/**\n * useAudioBlobLoader — loads audio blob from URL or preloaded data,\n * creates object URL and decodes waveform levels.\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { createInitialLevels } from '../constants';\nimport { createPseudoLevels } from '../utils';\n\nimport type { PlaybackCallbacks } from '../platform';\n\nimport {\n cleanupAudio,\n createAudioPlayback,\n createObjectURL,\n decodeAudioLevels,\n fetchAudioBlob,\n revokeObjectURL,\n} from '../platform';\n\n\ninterface UseAudioBlobLoaderOptions {\n src: string;\n waveformData?: number[];\n preloadedBlob?: Blob | null;\n playbackCallbacks: PlaybackCallbacks;\n}\n\ninterface UseAudioBlobLoaderResult {\n audioRef: React.MutableRefObject<HTMLAudioElement | null>;\n isLoading: boolean;\n isLoaded: boolean;\n waveformLevels: number[];\n ensureAudioLoaded: () => Promise<void>;\n}\n\nconst useAudioBlobLoader = (options: UseAudioBlobLoaderOptions): UseAudioBlobLoaderResult => {\n\n const { src, waveformData, preloadedBlob, playbackCallbacks } = options;\n\n const [ isLoading, setIsLoading ] = useState(false);\n const [ isLoaded, setIsLoaded ] = useState(false);\n const [ waveformLevels, setWaveformLevels ] = useState<number[]>(waveformData || createInitialLevels);\n\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const objectUrlRef = useRef<string | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n const waveformTokenRef = useRef(0);\n const waveformDataRef = useRef(waveformData);\n const callbacksRef = useRef(playbackCallbacks);\n waveformDataRef.current = waveformData;\n callbacksRef.current = playbackCallbacks;\n\n const createAudioFromUrl = useCallback((url: string) => {\n const { audio } = createAudioPlayback(url, {\n onLoadedMetadata: (dur) => callbacksRef.current.onLoadedMetadata(dur),\n onTimeUpdate: (time) => callbacksRef.current.onTimeUpdate(time),\n onEnded: () => callbacksRef.current.onEnded(),\n onPlay: () => callbacksRef.current.onPlay?.(),\n onPause: () => callbacksRef.current.onPause?.(),\n onStop: () => callbacksRef.current.onStop?.(),\n onSeekBackward: () => callbacksRef.current.onSeekBackward?.(),\n onSeekForward: () => callbacksRef.current.onSeekForward?.(),\n onPreviousTrack: () => callbacksRef.current.onPreviousTrack?.(),\n onNextTrack: () => callbacksRef.current.onNextTrack?.(),\n });\n\n audioRef.current = audio;\n setIsLoaded(true);\n }, []);\n\n /** Local recordings have no url of their own, so they still go through a blob */\n const createAudioFromBlob = useCallback((blob: Blob) => {\n if (objectUrlRef.current) {\n revokeObjectURL(objectUrlRef.current);\n }\n\n objectUrlRef.current = createObjectURL(blob);\n\n createAudioFromUrl(objectUrlRef.current);\n }, [ createAudioFromUrl ]);\n\n /**\n * Waveform is cosmetic: some files (e.g. mp3 with junk before the first\n * frame) fail to decode in Safari while playing fine, so a decode error\n * must never block playback. Token keeps only the latest decode.\n */\n const applyWaveformLevels = useCallback(async (blob: Blob, seed: string) => {\n /** Read through the ref: levels may arrive while the bytes are still loading */\n if (waveformDataRef.current) {\n return;\n }\n\n waveformTokenRef.current += 1;\n\n const token = waveformTokenRef.current;\n\n try {\n const levels = await decodeAudioLevels(blob);\n\n if (token === waveformTokenRef.current) {\n setWaveformLevels(levels);\n }\n } catch (error) {\n console.warn('[voice-player] Failed to decode waveform', error);\n\n /** Some runtimes decode nothing at all — draw a placeholder instead of a flat line */\n if (token === waveformTokenRef.current) {\n setWaveformLevels(createPseudoLevels(seed));\n }\n }\n }, []);\n\n const mountFromBlob = useCallback(async (blob: Blob) => {\n if (audioRef.current) {\n return;\n }\n\n setIsLoading(true);\n try {\n createAudioFromBlob(blob);\n } catch (error) {\n console.warn('[voice-player] Failed to mount blob', error);\n } finally {\n setIsLoading(false);\n }\n\n void applyWaveformLevels(blob, `${blob.size}`);\n }, [ applyWaveformLevels, createAudioFromBlob ]);\n\n /** Waveform bytes are cosmetic, so nothing here may delay playback */\n const loadWaveformSource = useCallback(async (url: string, cached?: Blob | null) => {\n if (waveformDataRef.current) {\n return;\n }\n\n if (cached) {\n return applyWaveformLevels(cached, url);\n }\n\n abortControllerRef.current?.abort();\n\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n try {\n const blob = await fetchAudioBlob(url, controller.signal);\n\n if (!controller.signal.aborted) {\n await applyWaveformLevels(blob, url);\n }\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return;\n }\n\n console.warn('[voice-player] Failed to fetch waveform source', error);\n }\n }, [ applyWaveformLevels ]);\n\n const ensureAudioLoaded = useCallback(async () => {\n if (audioRef.current) {\n return;\n }\n\n /** Only a recording that has not been uploaded yet has no url of its own */\n if (!src) {\n return preloadedBlob ? mountFromBlob(preloadedBlob) : undefined;\n }\n\n /**\n * Remote files play straight from their url: it streams with range\n * requests, keeps the user gesture (no await before play) and avoids\n * blob sources, which some WebKit runtimes refuse to render.\n */\n createAudioFromUrl(src);\n\n void loadWaveformSource(src, preloadedBlob);\n }, [ src, preloadedBlob, mountFromBlob, loadWaveformSource, createAudioFromUrl ]);\n\n /** Cleanup on src change or unmount */\n useEffect(() => {\n /** Drop the previous waveform so a failed decode cannot leave a foreign one */\n setWaveformLevels(waveformDataRef.current || createInitialLevels());\n\n return () => {\n abortControllerRef.current?.abort();\n waveformTokenRef.current += 1;\n if (audioRef.current) {\n cleanupAudio(audioRef.current);\n audioRef.current = null;\n }\n if (objectUrlRef.current) {\n revokeObjectURL(objectUrlRef.current);\n objectUrlRef.current = null;\n }\n setIsLoaded(false);\n };\n }, [ src ]);\n\n /** A cached recording mounts on its own only while it has no url yet */\n useEffect(() => {\n if (preloadedBlob && !src && !audioRef.current) {\n void mountFromBlob(preloadedBlob);\n }\n }, [ src, preloadedBlob, mountFromBlob ]);\n\n useEffect(() => {\n if (waveformData) {\n waveformTokenRef.current += 1;\n setWaveformLevels(waveformData);\n }\n }, [ waveformData ]);\n\n return {\n audioRef,\n isLoading,\n isLoaded,\n waveformLevels,\n ensureAudioLoaded,\n };\n};\n\n\nexport { useAudioBlobLoader };\n","/**\n * Global audio playback manager — ensures only one audio plays at a time\n *\n * @author: exode <hello@exode.ru>\n */\n\n\ntype StopCallback = () => void;\n\nconst listeners = new Set<StopCallback>();\n\nexport const audioPlaybackManager = {\n /** Register a stop callback for a player instance */\n subscribe: (callback: StopCallback) => {\n listeners.add(callback);\n\n return () => {\n listeners.delete(callback);\n };\n },\n\n /** Stop all other players except the caller */\n stopOthers: (except: StopCallback) => {\n listeners.forEach((cb) => {\n if (cb !== except) {\n cb();\n }\n });\n },\n};\n","/**\n * useVoiceMessagePlayer\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { formatTime } from '../utils';\nimport { audioPlaybackManager } from '../platform/audio-playback-manager';\n\nimport { useAudioBlobLoader } from './useAudioBlobLoader';\n\nimport type { UseVoiceMessagePlayerOptions, UseVoiceMessagePlayerResult } from '../types';\n\n\nconst useVoiceMessagePlayer = (options: UseVoiceMessagePlayerOptions): UseVoiceMessagePlayerResult => {\n\n const {\n src,\n onEnded,\n onPreviousTrack,\n onNextTrack,\n waveformData,\n preloadedBlob,\n duration: externalDuration,\n } = options;\n\n const onEndedRef = useRef(onEnded);\n const onPreviousTrackRef = useRef(onPreviousTrack);\n const onNextTrackRef = useRef(onNextTrack);\n\n onEndedRef.current = onEnded;\n onPreviousTrackRef.current = onPreviousTrack;\n onNextTrackRef.current = onNextTrack;\n\n const [ isPlaying, setIsPlaying ] = useState(false);\n const [ currentTime, setCurrentTime ] = useState(0);\n const [ duration, setDuration ] = useState(externalDuration || 0);\n\n const progress = duration > 0 ? currentTime / duration : 0;\n\n /** Stop this player (called by manager when another player starts) */\n const stopThis = useCallback(() => {\n const audio = audioRef.current;\n\n if (audio && !audio.paused) {\n audio.pause();\n }\n\n setIsPlaying(false);\n }, []);\n\n /** Subscribe to global manager on mount */\n useEffect(() => {\n return audioPlaybackManager.subscribe(stopThis);\n }, [ stopThis ]);\n\n const {\n audioRef,\n isLoading,\n isLoaded,\n waveformLevels,\n ensureAudioLoaded,\n } = useAudioBlobLoader({\n src,\n waveformData,\n preloadedBlob,\n playbackCallbacks: {\n onLoadedMetadata: (dur) => {\n if (!externalDuration && dur && isFinite(dur) && dur > 0.5) {\n setDuration(dur);\n }\n },\n onTimeUpdate: (time) => setCurrentTime(time),\n onEnded: () => {\n setIsPlaying(false);\n setCurrentTime(0);\n onEndedRef.current?.();\n },\n onPlay: () => setIsPlaying(true),\n onPause: () => setIsPlaying(false),\n onStop: () => {\n setIsPlaying(false);\n setCurrentTime(0);\n },\n onPreviousTrack: () => onPreviousTrackRef.current?.(),\n onNextTrack: () => onNextTrackRef.current?.(),\n },\n });\n\n /** Pre-fetch audio without playing (for viewport preloading) */\n const prefetch = useCallback(() => {\n if (isLoading || audioRef.current) {\n return;\n }\n\n void ensureAudioLoaded();\n }, [ isLoading, ensureAudioLoaded ]);\n\n /** Load audio and auto-play after loaded */\n const preload = useCallback(() => {\n if (isLoading || audioRef.current) {\n return;\n }\n\n audioPlaybackManager.stopOthers(stopThis);\n\n void ensureAudioLoaded().then(() => {\n const audio = audioRef.current;\n\n if (audio) {\n audio.play()\n .then(() => setIsPlaying(true))\n .catch(() => setIsPlaying(false));\n }\n });\n }, [ isLoading, ensureAudioLoaded, stopThis, audioRef ]);\n\n /** Programmatically start playback (used for chained playback) */\n const play = useCallback(() => {\n const audio = audioRef.current;\n\n if (audio) {\n audioPlaybackManager.stopOthers(stopThis);\n audio.play()\n .then(() => setIsPlaying(true))\n .catch(() => setIsPlaying(false));\n } else {\n preload();\n }\n }, [ stopThis, preload, audioRef ]);\n\n /** Toggle play/pause (only works after audio is loaded) */\n const togglePlayback = useCallback(() => {\n const audio = audioRef.current;\n\n if (!audio || isLoading) {\n return;\n }\n\n if (audio.paused) {\n audioPlaybackManager.stopOthers(stopThis);\n audio.play()\n .then(() => setIsPlaying(true))\n .catch(() => setIsPlaying(false));\n } else {\n audio.pause();\n setIsPlaying(false);\n }\n }, [ isLoading, stopThis, audioRef ]);\n\n const seekTo = useCallback((seekPercent: number) => {\n const audio = audioRef.current;\n\n if (!audio || !isFinite(audio.duration)) {\n return;\n }\n\n const time = seekPercent * audio.duration;\n\n audio.currentTime = time;\n setCurrentTime(time);\n }, [ audioRef ]);\n\n /** Seek to a specific time in seconds and start playback */\n const seekToTime = useCallback((seconds: number) => {\n const audio = audioRef.current;\n\n if (audio && isFinite(audio.duration)) {\n audioPlaybackManager.stopOthers(stopThis);\n\n audio.currentTime = Math.max(0, Math.min(seconds, audio.duration));\n setCurrentTime(audio.currentTime);\n\n audio.play()\n .then(() => setIsPlaying(true))\n .catch(() => setIsPlaying(false));\n } else {\n void ensureAudioLoaded().then(() => {\n const loadedAudio = audioRef.current;\n\n if (loadedAudio) {\n audioPlaybackManager.stopOthers(stopThis);\n\n loadedAudio.currentTime = Math.max(0, Math.min(\n seconds,\n loadedAudio.duration || seconds,\n ));\n\n setCurrentTime(loadedAudio.currentTime);\n\n loadedAudio.play()\n .then(() => setIsPlaying(true))\n .catch(() => setIsPlaying(false));\n }\n });\n }\n }, [\n audioRef,\n stopThis,\n ensureAudioLoaded,\n ]);\n\n /** Sync external duration */\n useEffect(() => {\n if (externalDuration) {\n setDuration(externalDuration);\n }\n }, [ externalDuration ]);\n\n return {\n play,\n progress,\n duration,\n isLoaded,\n isPlaying,\n isLoading,\n currentTime,\n waveformLevels,\n seekTo,\n seekToTime,\n prefetch,\n preload,\n formatTime,\n togglePlayback,\n };\n};\n\n\nexport { useVoiceMessagePlayer };\n","/**\n * useAudioRecorderHandlers — recording/send/cancel handlers for AudioRecorder\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport type { UseVoiceRecorderResult } from '../types';\nimport type { RecorderMessages } from '../components/AudioRecorder.messages';\n\n\ninterface UseAudioRecorderHandlersOptions {\n vibrate: (pattern: number | number[]) => void;\n messages: RecorderMessages;\n recorder: UseVoiceRecorderResult;\n onUploadError?: (error: unknown) => void;\n}\n\n\nconst useAudioRecorderHandlers = (options: UseAudioRecorderHandlersOptions) => {\n\n const {\n vibrate,\n recorder,\n messages,\n onUploadError,\n } = options;\n\n const {\n audioURL,\n isPaused,\n isRecording,\n hasRecording,\n stopPlayback,\n stopRecording,\n sendRecording,\n togglePlayback,\n startRecording,\n cancelRecording,\n deleteRecording,\n toggleRecordingPause,\n } = recorder;\n\n const shouldSendAfterStopRef = useRef(false);\n\n const [ isSending, setIsSending ] = useState(false);\n\n const startNewRecording = useCallback(async () => {\n if (isRecording) {\n return;\n }\n\n try {\n await startRecording();\n vibrate(50);\n } catch (error) {\n onUploadError?.(error);\n }\n }, [\n vibrate,\n isRecording,\n onUploadError,\n startRecording,\n ]);\n\n const handleRecordToggle = useCallback(() => {\n if (!isRecording) {\n if (audioURL) {\n stopPlayback();\n deleteRecording();\n }\n\n void startNewRecording();\n return;\n }\n\n if (isPaused) {\n stopPlayback();\n }\n\n toggleRecordingPause();\n }, [\n audioURL,\n isPaused,\n isRecording,\n stopPlayback,\n deleteRecording,\n startNewRecording,\n toggleRecordingPause,\n ]);\n\n const handleSend = useCallback(async () => {\n shouldSendAfterStopRef.current = false;\n setIsSending(true);\n try {\n stopPlayback();\n\n await sendRecording();\n } catch (error) {\n const uploadError = error instanceof Error\n ? error\n : new Error(messages.errors.loadFileFailed);\n\n onUploadError?.(uploadError);\n } finally {\n setIsSending(false);\n }\n }, [\n stopPlayback,\n onUploadError,\n sendRecording,\n messages.errors.loadFileFailed,\n ]);\n\n const handleSendRequest = useCallback(() => {\n if (isSending) {\n return;\n }\n\n if (isRecording) {\n setIsSending(true);\n shouldSendAfterStopRef.current = true;\n stopRecording();\n\n return;\n }\n\n void handleSend();\n }, [\n isSending,\n handleSend,\n isRecording,\n stopRecording,\n ]);\n\n const handleCancel = useCallback(() => {\n shouldSendAfterStopRef.current = false;\n\n if (isRecording) {\n cancelRecording();\n return;\n }\n\n if (audioURL) {\n stopPlayback();\n deleteRecording();\n }\n }, [\n audioURL,\n isRecording,\n stopPlayback,\n deleteRecording,\n cancelRecording,\n ]);\n\n const handlePlaybackToggle = useCallback(() => {\n if (!hasRecording) {\n return;\n }\n\n togglePlayback();\n }, [ hasRecording, togglePlayback ]);\n\n /** Auto-send after stop */\n useEffect(() => {\n if (!isRecording\n && hasRecording\n && shouldSendAfterStopRef.current\n ) {\n shouldSendAfterStopRef.current = false;\n\n void handleSend();\n }\n }, [\n handleSend,\n isRecording,\n hasRecording,\n ]);\n\n return {\n isSending,\n handleCancel,\n handleSendRequest,\n handleRecordToggle,\n handlePlaybackToggle,\n };\n};\n\n\nexport { useAudioRecorderHandlers };\n","/**\n * AudioRecorder styled components\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport styled from 'styled-components';\n\n\nexport const Container = styled.div`\n position: relative;\n width: 100%;\n transition: color 200ms ease, background-color 200ms ease;\n color: var(--text_primary, #0a0a0a);\n`;\n","/**\n * IdleControl styles\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport styled from 'styled-components';\n\n\nexport const IdleWrapper = styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n`;\n\nexport const IdleButton = styled.button`\n position: relative;\n width: 72px;\n height: 72px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 36px;\n border: 0;\n background: var(--background_content, #ffffff);\n color: color-mix(in srgb, var(--accent, #3f8ae0) 80%, white 20%);\n cursor: pointer;\n transition: transform 180ms ease, box-shadow 180ms ease, background-color 180ms ease;\n\n &:hover {\n transform: translateY(-2px);\n }\n\n &:active {\n transform: translateY(0);\n }\n\n &:focus-visible {\n outline: 2px solid color-mix(in srgb, var(--accent, #3f8ae0) 70%, transparent);\n outline-offset: 4px;\n }\n`;\n\nexport const IdleButtonOutline = styled.span`\n position: absolute;\n inset: 0;\n border-radius: 32px;\n border: 1px solid color-mix(in srgb, var(--accent, #3f8ae0) 28%, transparent);\n pointer-events: none;\n`;\n\nexport const IdleButtonGlow = styled.span`\n position: absolute;\n inset: 8px;\n border-radius: 28px;\n background: radial-gradient(\n 120% 120% at 50% 50%,\n color-mix(in srgb, var(--accent, #3f8ae0) 24%, transparent) 0%,\n color-mix(in srgb, var(--accent, #3f8ae0) 10%, transparent) 65%,\n transparent 100%\n );\n filter: blur(4px);\n pointer-events: none;\n`;\n\nexport const IdleInstruction = styled.div`\n font-size: 14px;\n text-align: center;\n color: color-mix(in srgb, var(--text_primary, #0a0a0a) 60%, transparent);\n`;\n","/**\n * IdleControl\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport React from 'react';\n\nimport { Icon32Microphone } from '@vkontakte/icons';\n\nimport { IdleButton, IdleButtonGlow, IdleButtonOutline, IdleInstruction, IdleWrapper } from './IdleControl.styled';\n\n\ninterface Props {\n onClick: () => void;\n instruction: string;\n startAriaLabel: string;\n}\n\n\nconst IdleControl = (props: Props) => {\n\n const {\n onClick,\n instruction,\n startAriaLabel,\n } = props;\n\n return (\n <IdleWrapper>\n <IdleButton type=\"button\" onClick={onClick} aria-label={startAriaLabel}>\n <IdleButtonOutline aria-hidden/>\n <IdleButtonGlow aria-hidden/>\n\n <Icon32Microphone height={48} width={48}/>\n </IdleButton>\n\n <IdleInstruction>\n {instruction}\n </IdleInstruction>\n </IdleWrapper>\n );\n};\n\n\nexport { IdleControl };","\nimport styled from 'styled-components';\n\nexport const Bars = styled.div`\n position: absolute;\n inset: 0;\n display: flex;\n align-items: flex-end;\n gap: 3px;\n`;\n\nexport const Bar = styled.div`\n flex: 1;\n min-width: 2px;\n border-radius: 9999px;\n background: var(--white, #ffffff);\n opacity: 0.6;\n transition: height 120ms ease, opacity 120ms ease;\n`;\n","/**\n * WaveformBars\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport React from 'react';\n\nimport { clampValue } from '../../utils/math';\n\nimport { Bar, Bars } from './WaveformBars.styled';\n\n\ninterface Props {\n scale?: number;\n divider?: number;\n values: number[];\n progress?: number;\n minHeight?: number;\n styleInterpolator?: (context: {\n normalized: number;\n height: number;\n index: number;\n progress: number;\n barProgress: number;\n isPlayed: boolean;\n }) => React.CSSProperties;\n}\n\n\nconst WaveformBars = (props: Props) => {\n\n const {\n values,\n progress,\n styleInterpolator,\n scale = 40,\n minHeight = 6,\n divider = 100,\n } = props;\n\n return (\n <Bars>\n {values.map((value, index) => {\n const normalized = clampValue(value);\n const height = Math.max(minHeight, (normalized / divider) * scale);\n const barProgress = values.length > 1 ? index / (values.length - 1) : 0;\n const isPlayed = (progress ?? 0) > 0 && barProgress <= (progress ?? 0);\n const interpolated = styleInterpolator?.({\n normalized,\n height,\n index,\n progress: progress ?? 0,\n barProgress,\n isPlayed,\n });\n\n return (\n <Bar key={index} style={{\n height: `${height}px`,\n ...interpolated,\n }}/>\n );\n })}\n </Bars>\n );\n};\n\n\nexport { WaveformBars };","/**\n * RecordingShell styles\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport styled from 'styled-components';\n\n\nexport const Wrapper = styled.div`\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n border-radius: 9999px;\n background: var(--background_hover, color-mix(in srgb, var(--text_primary, #0a0a0a) 6%, transparent));\n`;\n\nexport const CancelButton = styled.button`\n width: 38px;\n height: 38px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 19px;\n background: color-mix(in srgb, var(--exode_red) 10%, transparent);\n border: 0;\n flex-shrink: 0;\n color: color-mix(in srgb, var(--text_primary, #0a0a0a) 54%, transparent);\n cursor: pointer;\n transition: transform 160ms ease;\n\n &:hover:not(:disabled) {\n transform: translateY(-1px);\n }\n\n &:active:not(:disabled) {\n transform: translateY(0);\n }\n`;\n\nexport const Track = styled.div`\n flex: 1;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 8px 10px;\n border-radius: 9999px;\n background: color-mix(in srgb, var(--text_primary, #0a0a0a) 10%, transparent);\n`;\n\nexport const CircleButton = styled.button<{ $variant: 'record' | 'resume' | 'play' }>`\n width: 38px;\n height: 38px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 19px;\n border: 0;\n cursor: pointer;\n transition: transform 160ms ease, color 160ms ease, background-color 160ms ease, box-shadow 160ms ease;\n flex-shrink: 0;\n background: var(--background_content, #ffffff);\n\n color: ${({ $variant }) => {\n if ($variant === 'record') {\n return 'var(--exode_red, #ed1c24)';\n }\n\n if ($variant === 'resume') {\n return 'color-mix(in srgb, var(--accent, #3f8ae0) 86%, white 14%)';\n }\n\n return 'color-mix(in srgb, var(--text_primary, #0a0a0a) 80%, transparent)';\n }};\n\n &:hover:not(:disabled) {\n transform: translateY(-1px);\n }\n\n &:active:not(:disabled) {\n transform: translateY(0);\n }\n\n &:focus-visible {\n outline: 2px solid color-mix(in srgb, var(--accent, #3f8ae0) 70%, transparent);\n outline-offset: 2px;\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.45;\n transform: none;\n }\n`;\n\nexport const Waveform = styled.div<{ $expanded: boolean }>`\n position: relative;\n flex: ${({ $expanded }) => ($expanded ? 1.4 : 1)};\n height: 34px;\n display: flex;\n align-items: center;\n overflow: hidden;\n`;\n\nexport const Timer = styled.span`\n text-align: right;\n font-size: 13px;\n font-weight: 600;\n color: color-mix(in srgb, var(--text_primary, #0a0a0a) 86%, transparent);\n`;\n\nexport const SendButton = styled.button`\n width: 40px;\n height: 40px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 20px;\n border: 0;\n cursor: pointer;\n background: var(--accent, #3f8ae0);\n color: var(--white, #ffffff);\n transition: transform 160ms ease, opacity 160ms ease;\n\n &:hover:not(:disabled) {\n transform: translateY(-1px);\n }\n\n &:active:not(:disabled) {\n transform: translateY(0);\n }\n\n &:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n }\n`;\n\nexport const SpinnerSlot = styled.div`\n width: 22px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n`;\n\nexport const Spinner = styled.span`\n width: 100%;\n height: 100%;\n display: inline-block;\n box-sizing: border-box;\n border-radius: 50%;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-top-color: var(--white, #ffffff);\n border-right-color: var(--white, #ffffff);\n animation: audioRecorderSpinner 0.75s linear infinite;\n\n @keyframes audioRecorderSpinner {\n from {\n transform: rotate(0deg);\n }\n\n to {\n transform: rotate(360deg);\n }\n }\n`;\n","/**\n * RecordingShell\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport React, { useMemo } from 'react';\n\nimport {\n Icon16Microphone,\n Icon16Pause,\n Icon16Play,\n Icon28DeleteOutlineAndroid,\n Icon28SendOutline,\n} from '@vkontakte/icons';\n\nimport { WaveformBars } from '../WaveformBars/WaveformBars';\n\nimport {\n CancelButton,\n CircleButton,\n SendButton,\n Spinner,\n SpinnerSlot,\n Timer,\n Track,\n Waveform,\n Wrapper,\n} from './RecordingShell.styled';\n\n\ninterface Props {\n isRecording: boolean;\n isPaused: boolean;\n hasRecording: boolean;\n isPlaying: boolean;\n lastDuration: number;\n recordingTime: number;\n playbackTime: number;\n playbackDuration: number;\n audioLevels: number[];\n previewLevels: number[];\n isSending: boolean;\n cancelAriaLabel: string;\n stopAriaLabel: string;\n startAriaLabel: string;\n pauseRecordingAriaLabel: string;\n resumeRecordingAriaLabel: string;\n playAriaLabel: string;\n pausePlaybackAriaLabel: string;\n sendAriaLabel: string;\n onSend: () => void;\n onCancel: () => void;\n onRecordToggle: () => void;\n onTogglePlayback: () => void;\n formatTime: (seconds: number) => string;\n}\n\n\nconst RecordingShell = (props: Props) => {\n\n const {\n isPaused,\n isPlaying,\n isSending,\n isRecording,\n audioLevels,\n hasRecording,\n playbackTime,\n previewLevels,\n recordingTime,\n stopAriaLabel,\n playAriaLabel,\n sendAriaLabel,\n startAriaLabel,\n cancelAriaLabel,\n playbackDuration,\n pausePlaybackAriaLabel,\n pauseRecordingAriaLabel,\n resumeRecordingAriaLabel,\n onSend,\n onCancel,\n formatTime,\n onRecordToggle,\n onTogglePlayback,\n } = props;\n\n const { lastDuration } = props;\n\n const isPreview = !isRecording || isPaused;\n const waveformValues = isRecording ? audioLevels : (hasRecording ? previewLevels : audioLevels);\n\n const effectiveDuration = recordingTime\n || playbackDuration\n || lastDuration\n || 1;\n\n const progress = (isPreview && isPlaying)\n ? Math.min(1, playbackTime / effectiveDuration)\n : 0;\n\n const displayTime = useMemo(() => {\n if (isPlaying) {\n return formatTime(playbackTime);\n }\n\n if (isRecording && !isPaused) {\n return formatTime(recordingTime);\n }\n\n if (isRecording && isPaused) {\n return formatTime(recordingTime);\n }\n\n if (lastDuration > 0) {\n return formatTime(lastDuration);\n }\n\n if (hasRecording) {\n if (playbackDuration > 0.5) {\n return formatTime(playbackDuration);\n }\n\n if (recordingTime > 0) {\n return formatTime(recordingTime);\n }\n }\n\n return formatTime(0);\n }, [\n isPaused,\n isPlaying,\n formatTime,\n isRecording,\n lastDuration,\n hasRecording,\n playbackTime,\n recordingTime,\n playbackDuration,\n ]);\n\n const recordButtonDisabled = isSending;\n const recordButtonIcon = !isRecording || isPaused\n ? <Icon16Microphone width={24} height={24}/>\n : <Icon16Pause width={24} height={24}/>;\n const recordButtonVariant: 'record' | 'resume' = !isRecording || isPaused ? 'resume' : 'record';\n const recordButtonAria = !isRecording\n ? startAriaLabel\n : isPaused\n ? resumeRecordingAriaLabel\n : pauseRecordingAriaLabel || stopAriaLabel;\n\n const canShowPlayback = !isRecording || isPaused;\n const playbackDisabled = !hasRecording && !isRecording;\n const playbackIcon = isPlaying\n ? <Icon16Pause width={24} height={24}/>\n : <Icon16Play width={24} height={24}/>;\n const playbackAria = isPlaying ? pausePlaybackAriaLabel : playAriaLabel;\n\n const sendDisabled = isSending || (!hasRecording && !isRecording);\n\n return (\n <Wrapper>\n <CancelButton type=\"button\" onClick={onCancel} aria-label={cancelAriaLabel}>\n <Icon28DeleteOutlineAndroid fill=\"var(--exode_red)\" width={24} height={24} style={{ minWidth: 24 }}/>\n </CancelButton>\n\n <Track>\n <CircleButton type=\"button\"\n $variant={recordButtonVariant}\n onClick={onRecordToggle}\n aria-label={recordButtonAria}\n disabled={recordButtonDisabled}>\n {recordButtonIcon}\n </CircleButton>\n\n {!canShowPlayback ? null : (\n <CircleButton type=\"button\"\n $variant=\"play\"\n onClick={onTogglePlayback}\n aria-label={playbackAria}\n disabled={playbackDisabled}>\n {playbackIcon}\n </CircleButton>\n )}\n\n <Waveform $expanded={canShowPlayback}>\n <WaveformBars scale={42}\n minHeight={6}\n divider={100}\n progress={progress}\n values={waveformValues}\n styleInterpolator={({ normalized, isPlayed, progress: p }) => ({\n height: `${12 + normalized / 2}px`,\n maxHeight: '34px',\n opacity: p > 0\n ? (isPlayed ? 0.80 : 0.22)\n : 0.38 + Math.min(0.5, normalized / 120),\n transition: 'opacity 80ms ease',\n })}/>\n </Waveform>\n\n <Timer>\n {displayTime}\n </Timer>\n </Track>\n\n <SendButton type=\"button\" onClick={onSend} disabled={sendDisabled} aria-label={sendAriaLabel}>\n {isSending ? (\n <SpinnerSlot>\n <Spinner/>\n </SpinnerSlot>\n ) : (\n <Icon28SendOutline width={24} height={24}/>\n )}\n </SendButton>\n </Wrapper>\n );\n};\n\n\nexport { RecordingShell };\n","/**\n * AudioRecorder messages — i18n-ready message definitions and merge utility\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport interface RecorderMessages {\n buttons: {\n send: string;\n cancel: string;\n };\n instruction: string;\n aria: {\n startRecording: string;\n stopRecording: string;\n pauseRecording: string;\n resumeRecording: string;\n playRecording: string;\n pausePlayback: string;\n };\n errors: {\n loadFileFailed: string;\n };\n}\n\nexport type RecorderMessagesInput = Partial<{\n buttons: Partial<RecorderMessages['buttons']>;\n instruction: RecorderMessages['instruction'];\n aria: Partial<RecorderMessages['aria']>;\n errors: Partial<RecorderMessages['errors']>;\n}>;\n\nexport const DEFAULT_MESSAGES: RecorderMessages = {\n buttons: {\n cancel: 'Cancel',\n send: 'Send',\n },\n instruction: 'Tap to start recording',\n aria: {\n startRecording: 'Start recording voice message',\n stopRecording: 'Stop recording voice message',\n pauseRecording: 'Pause recording',\n resumeRecording: 'Resume recording',\n playRecording: 'Play recording',\n pausePlayback: 'Pause playback',\n },\n errors: {\n loadFileFailed: 'Failed to upload audio file',\n },\n};\n\nexport const mergeMessages = (custom?: RecorderMessagesInput): RecorderMessages => {\n if (!custom) {\n return DEFAULT_MESSAGES;\n }\n\n return {\n buttons: {\n ...DEFAULT_MESSAGES.buttons,\n ...custom.buttons,\n },\n instruction: custom.instruction ?? DEFAULT_MESSAGES.instruction,\n aria: {\n ...DEFAULT_MESSAGES.aria,\n ...custom.aria,\n },\n errors: {\n ...DEFAULT_MESSAGES.errors,\n ...custom.errors,\n },\n };\n};\n","/**\n * AudioRecorder\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { useVoiceRecorder } from '../hooks';\nimport { useAudioRecorderHandlers } from '../hooks/useAudioRecorderHandlers';\n\nimport { Container } from './AudioRecorder.styled';\nimport { IdleControl } from './IdleControl/IdleControl';\nimport { RecordingShell } from './RecordingShell/RecordingShell';\n\nimport { mergeMessages, type RecorderMessagesInput } from './AudioRecorder.messages';\n\nimport {\n type StorageFileEntity,\n type UploadStrategy,\n type UseVoiceRecorderOptions,\n} from '../types';\n\n\ntype RecorderOptionOverrides = Omit<\n UseVoiceRecorderOptions<Partial<StorageFileEntity>>,\n 'uploadId' | 'onUploaded' | 'uploader'\n>;\n\ninterface Props extends Partial<RecorderOptionOverrides> {\n uploader: UploadStrategy<Partial<StorageFileEntity>>;\n messages?: RecorderMessagesInput;\n uploadId?: string;\n className?: string;\n onUploadError?: (error: unknown) => void;\n onUploaded?: (file: Partial<StorageFileEntity>, duration: number) => void | Promise<void>;\n}\n\n\nconst AudioRecorder = (props: Props) => {\n\n const {\n fileName,\n uploadId,\n mimeType,\n className,\n uploader,\n onUploaded,\n onUploadError,\n onRecordingStop,\n onRecordingError,\n onRecordingStart,\n onRecordingDelete,\n onPermissionDenied,\n autoResetAfterUpload,\n messages: customMessages,\n } = props;\n\n const messages = useMemo(() => mergeMessages(customMessages), [ customMessages ]);\n\n const [ resolvedUploadId ] = useState(\n () =>\n uploadId ??\n (typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `upload-${Date.now()}`),\n );\n\n const handleRecorderError = useCallback(\n (error: unknown) => {\n onRecordingError?.(error);\n onUploadError?.(error);\n },\n [ onRecordingError, onUploadError ],\n );\n\n const vibrate = useCallback((pattern: number | number[]) => {\n if (typeof navigator !== 'undefined' && 'vibrate' in navigator) {\n navigator.vibrate(pattern);\n }\n }, []);\n\n const recorder = useVoiceRecorder<Partial<StorageFileEntity>>({\n fileName,\n mimeType,\n onRecordingStop,\n onRecordingStart,\n onRecordingDelete,\n onPermissionDenied,\n autoResetAfterUpload,\n uploader,\n uploadId: resolvedUploadId,\n onRecordingError: handleRecorderError,\n onUploaded: onUploaded ?? (() => {}),\n });\n\n const {\n isSending,\n handleCancel,\n handleSendRequest,\n handleRecordToggle,\n handlePlaybackToggle,\n } = useAudioRecorderHandlers({\n vibrate,\n recorder,\n messages,\n onUploadError,\n });\n\n const {\n isPaused,\n isPlaying,\n formatTime,\n audioLevels,\n isRecording,\n lastDuration,\n playbackTime,\n hasRecording,\n previewLevels,\n recordingTime,\n playbackDuration,\n } = recorder;\n\n const showRecorderBar = isRecording || hasRecording || isSending;\n\n return (\n <Container className={className}>\n {showRecorderBar ? (\n <RecordingShell isPaused={isPaused}\n isSending={isSending}\n isPlaying={isPlaying}\n formatTime={formatTime}\n onCancel={handleCancel}\n isRecording={isRecording}\n audioLevels={audioLevels}\n onSend={handleSendRequest}\n playbackTime={playbackTime}\n lastDuration={lastDuration}\n hasRecording={hasRecording}\n previewLevels={previewLevels}\n recordingTime={recordingTime}\n playbackDuration={playbackDuration}\n onRecordToggle={handleRecordToggle}\n sendAriaLabel={messages.buttons.send}\n onTogglePlayback={handlePlaybackToggle}\n cancelAriaLabel={messages.buttons.cancel}\n playAriaLabel={messages.aria.playRecording}\n stopAriaLabel={messages.aria.stopRecording}\n startAriaLabel={messages.aria.startRecording}\n pauseRecordingAriaLabel={messages.aria.pauseRecording}\n resumeRecordingAriaLabel={messages.aria.resumeRecording}\n pausePlaybackAriaLabel={messages.aria.pausePlayback}/>\n ) : (\n <IdleControl onClick={handleRecordToggle}\n startAriaLabel={messages.aria.startRecording}\n instruction={messages.instruction}/>\n )}\n </Container>\n );\n};\n\n\nexport { AudioRecorder };\n","/**\n * useVoiceRecorderInput — orchestrates recording, sending and timeline for VoiceRecorderInput\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useVoiceRecorder } from './useVoiceRecorder';\nimport { TIMELINE_SAMPLE_INTERVAL } from '../constants';\nimport type { UploadStrategy } from '../types';\n\n\ninterface UseVoiceRecorderInputOptions {\n uploader?: UploadStrategy<unknown>;\n onUploaded?: (file: unknown, duration: number) => void | Promise<void>;\n onSend?: (file: File, duration: number) => void | Promise<void>;\n onError?: (error: unknown) => void;\n onCancel?: () => void;\n onPermissionDenied?: (error: unknown) => void;\n autoStart?: boolean;\n mimeType?: string;\n fileName?: string;\n}\n\n\nconst useVoiceRecorderInput = (options: UseVoiceRecorderInputOptions) => {\n\n const {\n onSend,\n onError,\n onCancel,\n uploader,\n onUploaded,\n onPermissionDenied,\n autoStart = true,\n mimeType = 'audio/webm',\n fileName = 'voice-message.webm',\n } = options;\n\n const [ isSending, setIsSending ] = useState(false);\n const [ timelineLevels, setTimelineLevels ] = useState<number[]>([]);\n\n const audioBlobRef = useRef<Blob | null>(null);\n const audioLevelsRef = useRef<number[]>([]);\n const lastDurationRef = useRef(0);\n const shouldSendAfterStopRef = useRef(false);\n const doSendRef = useRef<() => Promise<void>>();\n const autoStartedRef = useRef(false);\n\n const [ uploadId ] = useState(\n () => typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `upload-${Date.now()}`,\n );\n\n const handleRecordingStop = useCallback((blob: Blob) => {\n audioBlobRef.current = blob;\n if (shouldSendAfterStopRef.current) {\n shouldSendAfterStopRef.current = false;\n void doSendRef.current?.();\n }\n }, []);\n\n const recorder = useVoiceRecorder({\n fileName,\n mimeType,\n uploadId,\n onPermissionDenied,\n onRecordingStop: handleRecordingStop,\n onRecordingError: onError,\n uploader: onSend ? undefined : uploader,\n onUploaded: onSend ? (() => {}) : (onUploaded ?? (() => {})),\n });\n\n const {\n audioLevels,\n isPaused,\n isRecording,\n recordingTime,\n hasRecording,\n stopPlayback,\n sendRecording,\n stopRecording,\n startRecording,\n cancelRecording,\n deleteRecording,\n toggleRecordingPause,\n } = recorder;\n\n audioLevelsRef.current = audioLevels;\n\n useEffect(() => {\n if (recordingTime > 0) {\n lastDurationRef.current = recordingTime;\n }\n }, [ recordingTime ]);\n\n const isPreview = isPaused || (!isRecording && hasRecording);\n const isActiveRecording = isRecording && !isPaused;\n\n useEffect(() => {\n if (!isActiveRecording) {\n return;\n }\n const interval = setInterval(() => {\n const levels = audioLevelsRef.current;\n const peak = levels.length > 0 ? Math.max(...levels) : 0;\n setTimelineLevels((prev) => [ ...prev, peak ]);\n }, TIMELINE_SAMPLE_INTERVAL);\n return () => clearInterval(interval);\n }, [ isActiveRecording ]);\n\n useEffect(() => {\n if (isRecording && !isPaused) {\n setTimelineLevels([]);\n }\n }, [ isRecording ]);\n\n const handleResume = useCallback(() => {\n stopPlayback();\n toggleRecordingPause();\n }, [\n stopPlayback,\n toggleRecordingPause,\n ]);\n\n const handlePause = toggleRecordingPause;\n\n const handleCancel = useCallback(() => {\n shouldSendAfterStopRef.current = false;\n\n if (isRecording) {\n cancelRecording();\n } else if (hasRecording) {\n stopPlayback();\n deleteRecording();\n }\n onCancel?.();\n }, [\n onCancel,\n isRecording,\n hasRecording,\n stopPlayback,\n cancelRecording,\n deleteRecording,\n ]);\n\n const doSend = useCallback(async () => {\n setIsSending(true);\n try {\n stopPlayback();\n if (onSend) {\n if (!audioBlobRef.current) {\n return;\n }\n\n const file = new File(\n [ audioBlobRef.current ],\n fileName,\n { type: audioBlobRef.current.type || mimeType },\n );\n\n await onSend(\n file,\n recordingTime || lastDurationRef.current || 0,\n );\n\n deleteRecording();\n } else {\n await sendRecording();\n }\n } catch (error) {\n onError?.(error);\n } finally {\n setIsSending(false);\n }\n }, [\n onSend,\n onError,\n fileName,\n mimeType,\n recordingTime,\n sendRecording,\n stopPlayback,\n deleteRecording,\n ]);\n\n doSendRef.current = doSend;\n\n const handleSendRequest = useCallback(async () => {\n if (isSending) {\n return;\n }\n\n if (isRecording) {\n shouldSendAfterStopRef.current = true;\n\n stopRecording();\n\n return;\n }\n\n await doSend();\n }, [\n doSend,\n isRecording,\n isSending,\n stopRecording,\n ]);\n\n useEffect(() => {\n if (autoStart && !autoStartedRef.current) {\n autoStartedRef.current = true;\n void startRecording().catch((error) => {\n onPermissionDenied?.(error);\n });\n }\n }, [ autoStart ]);\n\n return {\n recorder,\n isSending,\n isPreview,\n timelineLevels,\n lastDurationRef,\n handleResume,\n handlePause,\n handleCancel,\n handleSendRequest,\n };\n};\n\n\nexport { useVoiceRecorderInput };\n","/**\n * PreviewBars — renders waveform bars in preview mode (paused/stopped)\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport React from 'react';\n\nimport { TIMELINE_BAR_MAX_HEIGHT, TIMELINE_BAR_MIN_HEIGHT, TIMELINE_BAR_WIDTH } from '../../constants';\n\n\ninterface PreviewBarsProps {\n isPlaying: boolean;\n playbackTime: number;\n lastDuration: number;\n recordingTime: number;\n previewLevels: number[];\n timelineLevels: number[];\n visibleBarsCount: number;\n}\n\n\nconst PreviewBars = (props: PreviewBarsProps) => {\n\n const {\n isPlaying,\n playbackTime,\n lastDuration,\n previewLevels,\n recordingTime,\n timelineLevels,\n visibleBarsCount,\n } = props;\n\n const maxBars = visibleBarsCount;\n\n const sourceLevels = timelineLevels.length > 0\n ? timelineLevels\n : previewLevels;\n\n if (!sourceLevels.length) {\n return (\n <>\n {Array.from({ length: maxBars }, (_, i) => (\n <div key={i} style={{\n width: `${TIMELINE_BAR_WIDTH}px`,\n height: `${TIMELINE_BAR_MIN_HEIGHT}px`,\n borderRadius: '9999px',\n flexShrink: 0,\n background: 'color-mix(in srgb, var(--text_primary, #0a0a0a) 15%, transparent)',\n }}/>\n ))}\n </>\n );\n }\n\n /** Interpolate source levels to fill container */\n const bars: number[] = [];\n\n for (let i = 0; i < maxBars; i++) {\n const srcIndex = (i / maxBars) * sourceLevels.length;\n const low = Math.floor(srcIndex);\n\n const high = Math.min(low + 1, sourceLevels.length - 1);\n const frac = srcIndex - low;\n\n bars.push((sourceLevels[low] ?? 0) * (1 - frac) + (sourceLevels[high] ?? 0) * frac);\n }\n\n const totalDuration = recordingTime || lastDuration || 1;\n const progress = isPlaying ? Math.min(1, playbackTime / totalDuration) : 0;\n\n return (\n <>\n {bars.map((level, i) => {\n const normalized = Math.min(100, level);\n const height = TIMELINE_BAR_MIN_HEIGHT + (normalized / 100) * (TIMELINE_BAR_MAX_HEIGHT - TIMELINE_BAR_MIN_HEIGHT);\n const isPlayed = progress > 0 && (i / maxBars) <= progress;\n\n return (\n <div key={i} style={{\n flexShrink: 0,\n height: `${height}px`,\n borderRadius: '9999px',\n width: `${TIMELINE_BAR_WIDTH}px`,\n background: !isPlaying\n ? 'color-mix(in srgb, var(--text_primary, #0a0a0a) 55%, transparent)'\n : isPlayed\n ? 'color-mix(in srgb, var(--text_primary, #0a0a0a) 80%, transparent)'\n : 'color-mix(in srgb, var(--text_primary, #0a0a0a) 22%, transparent)',\n transition: 'background 80ms ease',\n }}/>\n );\n })}\n </>\n );\n};\n\n\nexport { PreviewBars };\n","/**\n * TimelineBars — renders waveform bars during active recording\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport React from 'react';\n\nimport { TIMELINE_BAR_MAX_HEIGHT, TIMELINE_BAR_MIN_HEIGHT, TIMELINE_BAR_WIDTH } from '../../constants';\n\n\ninterface TimelineBarsProps {\n timelineLevels: number[];\n visibleBarsCount: number;\n}\n\n\nconst TimelineBars = (props: TimelineBarsProps) => {\n\n const { timelineLevels, visibleBarsCount } = props;\n\n const maxBars = visibleBarsCount;\n const visible = timelineLevels.slice(-maxBars);\n\n const padded = [\n ...visible,\n ...Array.from({ length: Math.max(0, maxBars - visible.length) }, () => 0),\n ];\n\n return (\n <>\n {padded.map((level, i) => {\n const normalized = Math.min(100, level);\n const height = TIMELINE_BAR_MIN_HEIGHT + (normalized / 100) * (TIMELINE_BAR_MAX_HEIGHT - TIMELINE_BAR_MIN_HEIGHT);\n const hasValue = i < visible.length;\n\n return (\n <div key={i} style={{\n width: `${TIMELINE_BAR_WIDTH}px`,\n height: `${height}px`,\n borderRadius: '9999px',\n flexShrink: 0,\n transition: 'height 120ms ease',\n background: hasValue\n ? 'color-mix(in srgb, var(--text_primary, #0a0a0a) 55%, transparent)'\n : 'color-mix(in srgb, var(--text_primary, #0a0a0a) 18%, transparent)',\n }}/>\n );\n })}\n </>\n );\n};\n\n\nexport { TimelineBars };\n","/**\n * VoiceRecorderInput styles\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport styled from 'styled-components';\n\n\nexport const Wrapper = styled.div`\n display: flex;\n align-items: center;\n width: 100%;\n gap: 6px;\n padding: 0 4px;\n color: var(--text_primary, #0a0a0a);\n`;\n\nexport const CancelButton = styled.button`\n width: 32px;\n height: 32px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 16px;\n background: transparent;\n border: 0;\n margin-right: 4px;\n flex-shrink: 0;\n color: color-mix(in srgb, var(--text_primary, #0a0a0a) 45%, transparent);\n cursor: pointer;\n transition: color 160ms ease, background-color 160ms ease;\n`;\n\nexport const RecordTrack = styled.div`\n flex: 1;\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px 4px 4px;\n border-radius: 9999px;\n background: color-mix(in srgb, var(--text_primary, #0a0a0a) 8%, transparent);\n min-width: 0;\n`;\n\n/** Container for control buttons — auto-sized, no fixed width */\nexport const ButtonSlot = styled.div`\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px;\n flex-shrink: 0;\n`;\n\nexport const StopButton = styled.button`\n width: 26px;\n height: 26px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 13px;\n border: 0;\n flex-shrink: 0;\n cursor: pointer;\n background: var(--background_content, #ffffff);\n color: var(--exode_red, #ed1c24);\n transition: transform 120ms ease;\n\n &:hover:not(:disabled) {\n transform: scale(1.05);\n }\n\n &:active:not(:disabled) {\n transform: scale(0.96);\n }\n\n &:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n`;\n\nexport const WaveformArea = styled.div`\n flex: 1;\n height: 28px;\n display: flex;\n align-items: flex-end;\n justify-content: flex-start;\n gap: 2px;\n overflow: hidden;\n min-width: 0;\n padding-bottom: 2px;\n`;\n\nexport const Timer = styled.span`\n font-size: 13px;\n font-weight: 500;\n flex-shrink: 0;\n color: color-mix(in srgb, var(--text_primary, #0a0a0a) 60%, transparent);\n font-variant-numeric: tabular-nums;\n`;\n\nexport const SendButton = styled.button`\n width: 32px;\n height: 32px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 16px;\n border: 0;\n flex-shrink: 0;\n cursor: pointer;\n background: transparent;\n color: var(--accent, #3f8ae0);\n transition: opacity 140ms ease;\n padding: 0;\n\n &:hover:not(:disabled) {\n opacity: 0.75;\n }\n\n &:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n }\n`;\n\nexport const MicIndicator = styled.button`\n width: 26px;\n height: 26px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 13px;\n border: 0;\n flex-shrink: 0;\n cursor: pointer;\n background: var(--background_content, #ffffff);\n color: color-mix(in srgb, var(--accent, #3f8ae0) 86%, white 14%);\n transition: background-color 140ms ease, transform 120ms ease;\n\n &:active {\n transform: scale(0.94);\n }\n`;\n\nexport const PlayPauseButton = styled.button`\n width: 26px;\n height: 26px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 13px;\n border: 0;\n flex-shrink: 0;\n cursor: pointer;\n background: var(--background_content, #ffffff);\n color: var(--text_primary, #0a0a0a);\n transition: transform 120ms ease;\n\n &:hover {\n transform: scale(1.06);\n }\n\n &:active {\n transform: scale(0.94);\n }\n`;\n\nexport const SpinnerIcon = styled.span`\n width: 20px;\n height: 20px;\n display: inline-block;\n border-radius: 50%;\n border: 2px solid color-mix(in srgb, var(--accent, #3f8ae0) 25%, transparent);\n border-top-color: var(--accent, #3f8ae0);\n border-right-color: var(--accent, #3f8ae0);\n animation: voiceRecorderSpin 0.75s linear infinite;\n\n @keyframes voiceRecorderSpin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n`;\n","/**\n * VoiceRecorderInput\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport React, { useEffect, useLayoutEffect, useRef, useState } from 'react';\n\nimport { Icon16Pause, Icon16Play, Icon20Voice, Icon28DeleteOutlineAndroid, Icon28SendOutline } from '@vkontakte/icons';\n\nimport type { UploadStrategy } from '../../types';\nimport { TIMELINE_BAR_GAP, TIMELINE_BAR_WIDTH } from '../../constants';\n\nimport { useVoiceRecorderInput } from '../../hooks/useVoiceRecorderInput';\n\nimport { PreviewBars } from './PreviewBars';\nimport { TimelineBars } from './TimelineBars';\n\nimport {\n ButtonSlot,\n CancelButton,\n MicIndicator,\n PlayPauseButton,\n RecordTrack,\n SendButton,\n SpinnerIcon,\n StopButton,\n Timer,\n WaveformArea,\n Wrapper,\n} from './VoiceRecorderInput.styled';\n\n\ninterface Props {\n uploader?: UploadStrategy<unknown>;\n onUploaded?: (file: unknown) => void | Promise<void>;\n onCancel?: () => void;\n onSend?: (file: File, duration: number) => void | Promise<void>;\n onError?: (error: unknown) => void;\n onPermissionDenied?: (error: unknown) => void;\n autoStart?: boolean;\n mimeType?: string;\n fileName?: string;\n className?: string;\n}\n\n\nconst VoiceRecorderInput = (props: Props) => {\n\n const { className, ...inputOptions } = props;\n\n const waveformRef = useRef<HTMLDivElement>(null);\n\n const {\n recorder,\n isSending,\n isPreview,\n timelineLevels,\n lastDurationRef,\n handleResume,\n handlePause,\n handleCancel,\n handleSendRequest,\n } = useVoiceRecorderInput(inputOptions);\n\n const {\n isPlaying,\n isRecording,\n recordingTime,\n hasRecording,\n previewLevels,\n playbackTime,\n formatTime,\n togglePlayback,\n } = recorder;\n\n const [ visibleBarsCount, setVisibleBarsCount ] = useState(0);\n\n const measureBars = () => {\n const el = waveformRef.current;\n if (!el) {\n return;\n }\n setVisibleBarsCount(\n Math.floor(el.clientWidth / (TIMELINE_BAR_WIDTH + TIMELINE_BAR_GAP)),\n );\n };\n\n /** Sync recalc before paint — catches layout shifts from button changes */\n useLayoutEffect(measureBars);\n\n /** ResizeObserver for external size changes (window resize, container resize) */\n useEffect(() => {\n const el = waveformRef.current;\n if (!el) {\n return;\n }\n\n let rafId = 0;\n\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(measureBars);\n });\n\n observer.observe(el);\n\n return () => {\n cancelAnimationFrame(rafId);\n observer.disconnect();\n };\n }, []);\n\n const displayTime = (isPreview && isPlaying)\n ? formatTime(playbackTime)\n : formatTime(recordingTime || lastDurationRef.current);\n\n return (\n <Wrapper className={className}>\n <CancelButton type=\"button\" onClick={handleCancel} aria-label=\"Cancel\">\n <Icon28DeleteOutlineAndroid fill=\"var(--exode_red)\" width={28} height={28} style={{ minWidth: 28 }}/>\n </CancelButton>\n\n <RecordTrack>\n <ButtonSlot>\n {isPreview ? (\n <>\n <MicIndicator type=\"button\" onClick={handleResume} aria-label=\"Resume recording\">\n <Icon20Voice width={14} height={14}/>\n </MicIndicator>\n\n <PlayPauseButton type=\"button\"\n onClick={togglePlayback}\n aria-label={isPlaying ? 'Pause' : 'Play'}>\n {isPlaying\n ? <Icon16Pause width={14} height={14}/>\n : <Icon16Play width={14} height={14}/>\n }\n </PlayPauseButton>\n </>\n ) : (\n <StopButton type=\"button\" onClick={handlePause} aria-label=\"Pause recording\">\n <Icon16Pause width={14} height={14}/>\n </StopButton>\n )}\n </ButtonSlot>\n\n <WaveformArea ref={waveformRef}>\n {isPreview ? (\n <PreviewBars timelineLevels={timelineLevels}\n previewLevels={previewLevels}\n isPlaying={isPlaying}\n playbackTime={playbackTime}\n recordingTime={recordingTime}\n lastDuration={lastDurationRef.current}\n visibleBarsCount={visibleBarsCount}/>\n ) : (\n <TimelineBars timelineLevels={timelineLevels} visibleBarsCount={visibleBarsCount}/>\n )}\n </WaveformArea>\n\n <Timer>\n {displayTime}\n </Timer>\n </RecordTrack>\n\n <SendButton type=\"button\"\n onClick={handleSendRequest}\n disabled={isSending || (!hasRecording && !isRecording)}\n aria-label=\"Send\">\n {isSending ? (\n <SpinnerIcon/>\n ) : (\n <Icon28SendOutline/>\n )}\n </SendButton>\n </Wrapper>\n );\n};\n\n\nexport { VoiceRecorderInput };\n","/**\n * VoicePlaybackChain\n *\n * @description Sequential voice message playback chain (like Telegram).\n * Registers voice players by media ID and plays the next one when current ends.\n *\n * @author: exode <hello@exode.ru>\n */\n\n\ninterface ChainEntry {\n id: number;\n play: () => void;\n}\n\n\nclass VoicePlaybackChainClass {\n\n private entries: ChainEntry[] = [];\n\n /** Register a voice player. Returns cleanup function for useEffect. */\n register = (id: number, play: () => void) => {\n this.entries = this.entries.filter((e) => e.id !== id);\n this.entries.push({ id, play });\n this.entries.sort((a, b) => a.id - b.id);\n\n return () => this.unregister(id);\n };\n\n /** Unregister a voice player by media ID */\n unregister = (id: number) => {\n this.entries = this.entries.filter((e) => e.id !== id);\n };\n\n /** Play the next voice message after the given media ID */\n playNext = (currentId: number) => {\n const idx = this.entries.findIndex((e) => e.id === currentId);\n\n if (idx >= 0 && idx < this.entries.length - 1) {\n this.entries[idx + 1].play();\n }\n };\n\n /** Play the previous voice message before the given media ID */\n playPrevious = (currentId: number) => {\n const idx = this.entries.findIndex((e) => e.id === currentId);\n\n if (idx > 0) {\n this.entries[idx - 1].play();\n }\n };\n\n}\n\n\nexport const VoicePlaybackChain = new VoicePlaybackChainClass();\n","/**\n * VoiceMessagePlayer styles\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport styled from 'styled-components';\n\n\nexport const PlayerWrapper = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 200px;\n padding: 2px 0;\n user-select: none;\n`;\n\nexport const PlayButton = styled.button`\n width: 44px;\n height: 44px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 22px;\n border: 0;\n cursor: pointer;\n flex-shrink: 0;\n background: var(--white, #ffffff);\n color: var(--accent, #3f8ae0);\n transition: transform 140ms ease, box-shadow 140ms ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n padding: 0;\n\n &:hover:not(:disabled) {\n transform: scale(1.04);\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.14);\n }\n\n &:active:not(:disabled) {\n transform: scale(0.97);\n box-shadow: 0 0 2px rgba(0, 0, 0, 0.08);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n`;\n\nexport const ContentColumn = styled.div`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n gap: 4px;\n`;\n\nexport const WaveformTrack = styled.div`\n height: 28px;\n display: flex;\n align-items: center;\n gap: 2px;\n overflow: hidden;\n cursor: pointer;\n min-width: 0;\n`;\n\nexport const WaveformBar = styled.div`\n width: 3px;\n border-radius: 1.5px;\n flex-shrink: 0;\n transition: background 100ms ease;\n`;\n\nexport const Duration = styled.span`\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n color: color-mix(in srgb, var(--text_primary, #0a0a0a) 55%, transparent);\n font-variant-numeric: tabular-nums;\n`;\n\nexport const LoadingSpinner = styled.span`\n width: 18px;\n height: 18px;\n display: inline-block;\n border-radius: 50%;\n border: 2px solid color-mix(in srgb, var(--accent, #3f8ae0) 25%, transparent);\n border-top-color: var(--accent, #3f8ae0);\n animation: voicePlayerSpin 0.7s linear infinite;\n\n @keyframes voicePlayerSpin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n`;","/**\n * VoiceMessagePlayer\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport React, { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';\n\nimport { Icon24Pause, Icon24Play } from '@vkontakte/icons';\n\nimport { useVoiceMessagePlayer } from '../../hooks';\n\nimport { VoicePlaybackChain } from '../../utils/voice-playback-chain';\n\nimport {\n ContentColumn,\n Duration,\n LoadingSpinner,\n PlayButton,\n PlayerWrapper,\n WaveformBar,\n WaveformTrack,\n} from './VoiceMessagePlayer.styled';\n\n\nconst BAR_WIDTH = 3;\nconst BAR_GAP = 2;\nconst BAR_MIN_HEIGHT = 2;\nconst BAR_MAX_HEIGHT = 24;\n\nexport interface VoiceMessagePlayerRef {\n play: () => void;\n prefetch: () => void;\n seekToTime: (seconds: number) => void;\n}\n\ninterface Props {\n src: string;\n chainId?: number;\n duration?: number;\n autoPreload?: boolean;\n waveformData?: number[];\n className?: string;\n onEnded?: () => void;\n preloadedBlob?: Blob | null;\n onClick?: (e: React.MouseEvent) => void;\n}\n\n\nconst VoiceMessagePlayer = React.forwardRef<VoiceMessagePlayerRef, Props>((props, ref) => {\n\n const {\n src,\n onClick,\n onEnded,\n chainId,\n duration,\n className,\n waveformData,\n autoPreload = true,\n } = props;\n\n const trackRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const [ trackWidth, setTrackWidth ] = useState(0);\n\n const handleEnded = useCallback(() => {\n onEnded?.();\n\n if (chainId != null) {\n VoicePlaybackChain.playNext(chainId);\n }\n }, [ onEnded, chainId ]);\n\n const handleNextTrack = useCallback(() => {\n if (chainId != null) {\n VoicePlaybackChain.playNext(chainId);\n }\n }, [ chainId ]);\n\n const handlePreviousTrack = useCallback(() => {\n if (chainId != null) {\n VoicePlaybackChain.playPrevious(chainId);\n }\n }, [ chainId ]);\n\n const {\n play,\n progress,\n isLoaded,\n isPlaying,\n isLoading,\n currentTime,\n waveformLevels,\n seekTo,\n seekToTime,\n prefetch,\n preload,\n formatTime,\n togglePlayback,\n duration: resolvedDuration,\n } = useVoiceMessagePlayer({\n src,\n duration,\n waveformData,\n preloadedBlob: props.preloadedBlob,\n onEnded: handleEnded,\n onNextTrack: handleNextTrack,\n onPreviousTrack: handlePreviousTrack,\n });\n\n useImperativeHandle(\n ref,\n () => ({ play, prefetch, seekToTime }),\n [\n play,\n prefetch,\n seekToTime,\n ],\n );\n\n /** Auto-preload audio when player enters viewport */\n useEffect(() => {\n if (!autoPreload || isLoaded || isLoading) {\n return;\n }\n\n const el = wrapperRef.current;\n\n if (!el) {\n return;\n }\n\n const observer = new IntersectionObserver(\n ([ entry ]) => {\n if (entry.isIntersecting) {\n prefetch();\n observer.disconnect();\n }\n },\n { threshold: 0.1 },\n );\n\n observer.observe(el);\n\n return () => observer.disconnect();\n }, [\n isLoaded,\n prefetch,\n isLoading,\n autoPreload,\n ]);\n\n /** Register in playback chain for sequential playback */\n useEffect(() => {\n if (chainId != null) {\n return VoicePlaybackChain.register(chainId, () => play());\n }\n }, [ chainId, play ]);\n\n const measureTrackWidth = () => {\n if (trackRef.current) {\n setTrackWidth(trackRef.current.clientWidth);\n }\n };\n\n /** Sync recalc before paint — catches layout shifts */\n useLayoutEffect(measureTrackWidth);\n\n /** ResizeObserver for external size changes (window resize, container resize) */\n useEffect(() => {\n const el = trackRef.current;\n if (!el) {\n return;\n }\n\n let rafId = 0;\n\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(measureTrackWidth);\n });\n\n observer.observe(el);\n\n return () => {\n cancelAnimationFrame(rafId);\n observer.disconnect();\n };\n }, []);\n\n const displayTime = (isPlaying || currentTime > 0)\n ? formatTime(currentTime)\n : formatTime(resolvedDuration);\n\n const handleTrackClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n const track = trackRef.current;\n\n if (!track) {\n return;\n }\n\n const rect = track.getBoundingClientRect();\n const clickProgress = (e.clientX - rect.left) / rect.width;\n\n seekTo(Math.max(0, Math.min(1, clickProgress)));\n }, [ seekTo ]);\n\n /** Interpolate waveform levels to fill container */\n const interpolatedBars = useMemo(() => {\n const maxBars = trackWidth > 0\n ? Math.floor(trackWidth / (BAR_WIDTH + BAR_GAP))\n : 48;\n\n if (!waveformLevels.length) {\n return Array.from({ length: maxBars }, () => 0);\n }\n\n const raw: number[] = [];\n\n for (let i = 0; i < maxBars; i++) {\n const srcIndex = (i / maxBars) * waveformLevels.length;\n const low = Math.floor(srcIndex);\n const high = Math.min(low + 1, waveformLevels.length - 1);\n const frac = srcIndex - low;\n\n raw.push(\n (waveformLevels[low] ?? 0) * (1 - frac)\n + (waveformLevels[high] ?? 0) * frac,\n );\n }\n\n /** Normalize to 0-100 range so bars use full height */\n const peak = Math.max(...raw, 1);\n\n return raw.map((v) => (v / peak) * 100);\n }, [ waveformLevels, trackWidth ]);\n\n return (\n <PlayerWrapper ref={wrapperRef} onClick={onClick} className={className}>\n <PlayButton type=\"button\"\n disabled={isLoading || (!src && !props.preloadedBlob)}\n onClick={isLoaded ? togglePlayback : preload}\n aria-label={isPlaying ? 'Pause' : 'Play'}>\n {isLoading ? (\n <LoadingSpinner/>\n ) : isPlaying ? (\n <Icon24Pause/>\n ) : (\n <Icon24Play/>\n )}\n </PlayButton>\n\n <ContentColumn>\n <WaveformTrack ref={trackRef} onClick={handleTrackClick}>\n {interpolatedBars.map((level, i) => {\n const normalized = Math.min(100, level);\n const height = BAR_MIN_HEIGHT + (normalized / 100) * (BAR_MAX_HEIGHT - BAR_MIN_HEIGHT);\n const barProgress = interpolatedBars.length > 0\n ? i / interpolatedBars.length\n : 0;\n const isPlayed = progress > 0 && barProgress <= progress;\n\n return (\n <WaveformBar key={i} style={{\n height: `${height}px`,\n background: isPlayed\n ? 'color-mix(in srgb, var(--text_primary, #0a0a0a) 75%, transparent)'\n : 'color-mix(in srgb, var(--text_primary, #0a0a0a) 25%, transparent)',\n }}/>\n );\n })}\n </WaveformTrack>\n\n <Duration>{displayTime}</Duration>\n </ContentColumn>\n </PlayerWrapper>\n );\n});\n\n\nexport { VoiceMessagePlayer };\n","/**\n * VoiceBlobCache\n *\n * @description In-memory cache for voice message blobs.\n * Allows instant playback of just-sent voice messages\n * before the server URL becomes available.\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nclass VoiceBlobCacheClass {\n\n private cache = new Map<number, Blob>();\n\n set = (messageId: number, blob: Blob) => {\n this.cache.set(messageId, blob);\n };\n\n get = (messageId: number): Blob | undefined => {\n return this.cache.get(messageId);\n };\n\n delete = (messageId: number) => {\n this.cache.delete(messageId);\n };\n\n /** Transfer blob from optimistic ID to real server ID */\n transfer = (fromId: number, toId: number) => {\n const blob = this.cache.get(fromId);\n\n if (blob) {\n this.cache.delete(fromId);\n this.cache.set(toId, blob);\n }\n };\n\n}\n\n\nexport const VoiceBlobCache = new VoiceBlobCacheClass();\n"],"names":["_jsxs","_jsx","Wrapper","CancelButton","Timer","SendButton","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Animation frame platform adapter
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ const scheduleFrame = (callback) => {
7
+ return requestAnimationFrame(callback);
8
+ };
9
+ const cancelFrame = (id) => {
10
+ cancelAnimationFrame(id);
11
+ };
12
+
13
+ export { cancelFrame, scheduleFrame };
14
+ //# sourceMappingURL=animation-frame-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation-frame-adapter.js","sources":["../../src/platform/animation-frame-adapter.ts"],"sourcesContent":["/**\n * Animation frame platform adapter\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport const scheduleFrame = (callback: FrameRequestCallback): number => {\n return requestAnimationFrame(callback);\n};\n\nexport const cancelFrame = (id: number): void => {\n cancelAnimationFrame(id);\n};"],"names":[],"mappings":"AAAA;;;;AAIG;AAGI,MAAM,aAAa,GAAG,CAAC,QAA8B,KAAY;AACpE,IAAA,OAAO,qBAAqB,CAAC,QAAQ,CAAC;AAC1C;AAEO,MAAM,WAAW,GAAG,CAAC,EAAU,KAAU;IAC5C,oBAAoB,CAAC,EAAE,CAAC;AAC5B;;;;"}
@@ -0,0 +1,74 @@
1
+ import { AUDIO_LEVEL_BARS, WAVEFORM_SAMPLE_RATE } from '../constants.js';
2
+ import { findFirstFrameOffset } from './mpeg-frame.js';
3
+
4
+ /**
5
+ * Audio analyzer platform adapter
6
+ *
7
+ * @author: exode <hello@exode.ru>
8
+ */
9
+ const createStreamAnalyzer = (stream) => {
10
+ const context = new AudioContext();
11
+ const analyser = context.createAnalyser();
12
+ const source = context.createMediaStreamSource(stream);
13
+ source.connect(analyser);
14
+ analyser.fftSize = 256;
15
+ return { context, analyser };
16
+ };
17
+ const readFrequencyLevels = (analyser, barCount = AUDIO_LEVEL_BARS) => {
18
+ var _a;
19
+ const bufferLength = analyser.frequencyBinCount;
20
+ const dataArray = new Uint8Array(bufferLength);
21
+ analyser.getByteFrequencyData(dataArray);
22
+ const step = Math.max(1, Math.floor(bufferLength / barCount));
23
+ const levels = [];
24
+ for (let i = 0; i < barCount; i += 1) {
25
+ const value = (_a = dataArray[i * step]) !== null && _a !== void 0 ? _a : 0;
26
+ levels.push((value / 255) * 100);
27
+ }
28
+ return levels;
29
+ };
30
+ /** decodeAudioData detaches the buffer, so the retry re-reads the blob */
31
+ const decodeSkippingJunk = async (context, blob) => {
32
+ try {
33
+ return await context.decodeAudioData(await blob.arrayBuffer());
34
+ }
35
+ catch (error) {
36
+ const bytes = new Uint8Array(await blob.arrayBuffer());
37
+ const offset = findFirstFrameOffset(bytes);
38
+ if (!offset) {
39
+ throw error;
40
+ }
41
+ return context.decodeAudioData(bytes.buffer.slice(offset));
42
+ }
43
+ };
44
+ const decodeAudioLevels = async (blob, barCount = AUDIO_LEVEL_BARS) => {
45
+ /**
46
+ * Offline rendering keeps the audio hardware untouched. Runtimes that
47
+ * cannot decode at all (iPad apps on macOS reject every mp3) fall through
48
+ * to the caller, which draws a placeholder waveform instead.
49
+ */
50
+ const context = new OfflineAudioContext(1, 1, WAVEFORM_SAMPLE_RATE);
51
+ const audioBuffer = await decodeSkippingJunk(context, blob);
52
+ const channelData = audioBuffer.getChannelData(0);
53
+ if (!channelData.length) {
54
+ return Array.from({ length: barCount }, () => 0);
55
+ }
56
+ const levels = [];
57
+ const segmentLength = Math.max(1, Math.floor(channelData.length / barCount));
58
+ for (let i = 0; i < barCount; i += 1) {
59
+ const segmentStart = i * segmentLength;
60
+ let sum = 0;
61
+ for (let j = 0; j < segmentLength; j += 1) {
62
+ const sample = channelData[segmentStart + j];
63
+ if (sample !== undefined) {
64
+ sum += Math.abs(sample);
65
+ }
66
+ }
67
+ const average = sum / segmentLength;
68
+ levels.push(Math.min(100, average * 200));
69
+ }
70
+ return levels;
71
+ };
72
+
73
+ export { createStreamAnalyzer, decodeAudioLevels, readFrequencyLevels };
74
+ //# sourceMappingURL=audio-analyzer-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-analyzer-adapter.js","sources":["../../src/platform/audio-analyzer-adapter.ts"],"sourcesContent":["/**\n * Audio analyzer platform adapter\n *\n * @author: exode <hello@exode.ru>\n */\n\nimport { AUDIO_LEVEL_BARS, WAVEFORM_SAMPLE_RATE } from '../constants';\n\nimport { findFirstFrameOffset } from './mpeg-frame';\n\n\nexport interface StreamAnalyzer {\n context: AudioContext;\n analyser: AnalyserNode;\n}\n\nexport const createStreamAnalyzer = (stream: MediaStream): StreamAnalyzer => {\n const context = new AudioContext();\n const analyser = context.createAnalyser();\n const source = context.createMediaStreamSource(stream);\n\n source.connect(analyser);\n analyser.fftSize = 256;\n\n return { context, analyser };\n};\n\nexport const readFrequencyLevels = (analyser: AnalyserNode, barCount: number = AUDIO_LEVEL_BARS): number[] => {\n const bufferLength = analyser.frequencyBinCount;\n const dataArray = new Uint8Array(bufferLength);\n\n analyser.getByteFrequencyData(dataArray);\n\n const step = Math.max(1, Math.floor(bufferLength / barCount));\n const levels: number[] = [];\n\n for (let i = 0; i < barCount; i += 1) {\n const value = dataArray[i * step] ?? 0;\n levels.push((value / 255) * 100);\n }\n\n return levels;\n};\n\n/** decodeAudioData detaches the buffer, so the retry re-reads the blob */\nconst decodeSkippingJunk = async (context: BaseAudioContext, blob: Blob): Promise<AudioBuffer> => {\n try {\n return await context.decodeAudioData(await blob.arrayBuffer());\n } catch (error) {\n const bytes = new Uint8Array(await blob.arrayBuffer());\n const offset = findFirstFrameOffset(bytes);\n\n if (!offset) {\n throw error;\n }\n\n return context.decodeAudioData(bytes.buffer.slice(offset));\n }\n};\n\nexport const decodeAudioLevels = async (\n blob: Blob,\n barCount: number = AUDIO_LEVEL_BARS,\n): Promise<number[]> => {\n /**\n * Offline rendering keeps the audio hardware untouched. Runtimes that\n * cannot decode at all (iPad apps on macOS reject every mp3) fall through\n * to the caller, which draws a placeholder waveform instead.\n */\n const context = new OfflineAudioContext(1, 1, WAVEFORM_SAMPLE_RATE);\n\n const audioBuffer = await decodeSkippingJunk(context, blob);\n const channelData = audioBuffer.getChannelData(0);\n\n if (!channelData.length) {\n return Array.from({ length: barCount }, () => 0);\n }\n\n const levels: number[] = [];\n const segmentLength = Math.max(1, Math.floor(channelData.length / barCount));\n\n for (let i = 0; i < barCount; i += 1) {\n const segmentStart = i * segmentLength;\n let sum = 0;\n\n for (let j = 0; j < segmentLength; j += 1) {\n const sample = channelData[segmentStart + j];\n if (sample !== undefined) {\n sum += Math.abs(sample);\n }\n }\n\n const average = sum / segmentLength;\n levels.push(Math.min(100, average * 200));\n }\n\n return levels;\n};"],"names":[],"mappings":";;;AAAA;;;;AAIG;AAYI,MAAM,oBAAoB,GAAG,CAAC,MAAmB,KAAoB;AACxE,IAAA,MAAM,OAAO,GAAG,IAAI,YAAY,EAAE;AAClC,IAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,EAAE;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,MAAM,CAAC;AAEtD,IAAA,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;AACxB,IAAA,QAAQ,CAAC,OAAO,GAAG,GAAG;AAEtB,IAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;AAChC;AAEO,MAAM,mBAAmB,GAAG,CAAC,QAAsB,EAAE,QAAA,GAAmB,gBAAgB,KAAc;;AACzG,IAAA,MAAM,YAAY,GAAG,QAAQ,CAAC,iBAAiB;AAC/C,IAAA,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC;AAE9C,IAAA,QAAQ,CAAC,oBAAoB,CAAC,SAAS,CAAC;AAExC,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAa,EAAE;AAE3B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE;QAClC,MAAM,KAAK,GAAG,CAAA,EAAA,GAAA,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,EAAA,GAAI,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,GAAG,IAAI,GAAG,CAAC;IACpC;AAEA,IAAA,OAAO,MAAM;AACjB;AAEA;AACA,MAAM,kBAAkB,GAAG,OAAO,OAAyB,EAAE,IAAU,KAA0B;AAC7F,IAAA,IAAI;QACA,OAAO,MAAM,OAAO,CAAC,eAAe,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;IAClE;IAAE,OAAO,KAAK,EAAE;QACZ,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;AACtD,QAAA,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC;QAE1C,IAAI,CAAC,MAAM,EAAE;AACT,YAAA,MAAM,KAAK;QACf;AAEA,QAAA,OAAO,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9D;AACJ,CAAC;AAEM,MAAM,iBAAiB,GAAG,OAC7B,IAAU,EACV,QAAA,GAAmB,gBAAgB,KAChB;AACnB;;;;AAIG;IACH,MAAM,OAAO,GAAG,IAAI,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,oBAAoB,CAAC;IAEnE,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC;IAC3D,MAAM,WAAW,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC;AAEjD,IAAA,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;AACrB,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC;IACpD;IAEA,MAAM,MAAM,GAAa,EAAE;AAC3B,IAAA,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;AAE5E,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE;AAClC,QAAA,MAAM,YAAY,GAAG,CAAC,GAAG,aAAa;QACtC,IAAI,GAAG,GAAG,CAAC;AAEX,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,IAAI,CAAC,EAAE;YACvC,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,GAAG,CAAC,CAAC;AAC5C,YAAA,IAAI,MAAM,KAAK,SAAS,EAAE;AACtB,gBAAA,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YAC3B;QACJ;AAEA,QAAA,MAAM,OAAO,GAAG,GAAG,GAAG,aAAa;AACnC,QAAA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,CAAC,CAAC;IAC7C;AAEA,IAAA,OAAO,MAAM;AACjB;;;;"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Audio blob fetcher platform adapter
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ const fetchAudioBlob = async (url, signal) => {
7
+ const response = await fetch(url, {
8
+ signal,
9
+ mode: 'cors',
10
+ credentials: 'omit',
11
+ });
12
+ if (!response.ok) {
13
+ throw new Error(`Failed to fetch audio: ${response.status}`);
14
+ }
15
+ return response.blob();
16
+ };
17
+
18
+ export { fetchAudioBlob };
19
+ //# sourceMappingURL=audio-blob-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-blob-fetcher.js","sources":["../../src/platform/audio-blob-fetcher.ts"],"sourcesContent":["/**\n * Audio blob fetcher platform adapter\n *\n * @author: exode <hello@exode.ru>\n */\n\n\nexport const fetchAudioBlob = async (\n url: string,\n signal?: AbortSignal,\n): Promise<Blob> => {\n const response = await fetch(url, {\n signal,\n mode: 'cors',\n credentials: 'omit',\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch audio: ${response.status}`);\n }\n\n return response.blob();\n};\n"],"names":[],"mappings":"AAAA;;;;AAIG;AAGI,MAAM,cAAc,GAAG,OAC1B,GAAW,EACX,MAAoB,KACL;AACf,IAAA,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC9B,MAAM;AACN,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,WAAW,EAAE,MAAM;AACtB,KAAA,CAAC;AAEF,IAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;QACd,MAAM,IAAI,KAAK,CAAC,CAAA,uBAAA,EAA0B,QAAQ,CAAC,MAAM,CAAA,CAAE,CAAC;IAChE;AAEA,IAAA,OAAO,QAAQ,CAAC,IAAI,EAAE;AAC1B;;;;"}