{"version":3,"file":"voice-recorder-DpegLnFK.js","sources":["../../../resources/js/voice-recorder.js"],"sourcesContent":["import WaveSurfer from 'wavesurfer.js';\nimport RecordPlugin from '/node_modules/wavesurfer.js/dist/plugins/record.esm.js';\nimport { ConvertToPersianNumbers } from './utils.js';\n\nconst createRecorder = (containerId) => {\n let wavesurfer, record;\n let scrollingWaveform = true;\n\n let containerSelector = '#recorder-container-' + containerId;\n let recorderContainer = document.querySelector(containerSelector);\n let mic = document.querySelector(containerSelector + ' .mic');\n let preview = document.querySelector(containerSelector + ' .preview');\n\n const previewControlButton = document.querySelector(\n containerSelector + ' .preview-control-button',\n );\n\n const createWaveSurfer = () => {\n // Create an instance of WaveSurfer\n if (wavesurfer) {\n wavesurfer.destroy();\n }\n wavesurfer = WaveSurfer.create({\n container: mic,\n height: 24,\n splitChannels: false,\n normalize: true,\n waveColor: '#8B8B8B',\n progressColor: '#48A700',\n cursorColor: '#ddd5e9',\n cursorWidth: 0,\n barWidth: 2,\n barGap: 4,\n barRadius: 10,\n barHeight: null,\n fillParent: true,\n autoplay: false,\n interact: true,\n dragToSeek: false,\n hideScrollbar: true,\n audioRate: 1,\n autoScroll: true,\n autoCenter: true,\n sampleRate: 4000,\n });\n\n // Initialize the Record plugin\n record = wavesurfer.registerPlugin(\n RecordPlugin.create({ scrollingWaveform, renderRecordedAudio: true }),\n );\n // Render recorded audio\n record.on('record-end', (blob) => {\n const recordedUrl = URL.createObjectURL(blob);\n // Create wavesurfer from the recorded audio\n const wavesurfer = WaveSurfer.create({\n container: preview,\n height: 24,\n splitChannels: false,\n normalize: true,\n waveColor: '#8B8B8B',\n progressColor: '#48A700',\n cursorColor: '#ddd5e9',\n cursorWidth: 0,\n barWidth: 2,\n barGap: 4,\n barRadius: 10,\n barHeight: 24,\n fillParent: true,\n autoplay: false,\n interact: true,\n dragToSeek: true,\n hideScrollbar: true,\n audioRate: 1,\n autoScroll: true,\n autoCenter: true,\n sampleRate: 4000,\n url: recordedUrl,\n });\n\n wavesurfer.on('timeupdate', (currentTime) => {\n updateProgress(currentTime * 1000);\n });\n // Play button\n\n const playIcon = document.querySelector(\n containerSelector + ' .recorder-play-icon',\n );\n\n const pauseIcon = document.querySelector(\n containerSelector + ' .recorder-pause-icon',\n );\n previewControlButton.onclick = () => wavesurfer.playPause();\n wavesurfer.on('pause', () => {\n playIcon.classList.remove('hidden');\n pauseIcon.classList.add('hidden');\n });\n wavesurfer.on('play', () => {\n playIcon.classList.add('hidden');\n pauseIcon.classList.remove('hidden');\n });\n\n document.dispatchEvent(\n new CustomEvent(containerId + '-recorder-record-ended', {\n detail: blob,\n }),\n );\n });\n\n record.on('record-progress', (time) => {\n updateProgress(time);\n });\n };\n const progress = document.querySelector(\n containerSelector + ' .recorder-progress',\n );\n const updateProgress = (time) => {\n // time will be in milliseconds, convert it to mm:ss format\n const formattedTime = [\n Math.floor((time % 3600000) / 60000), // minutes\n Math.floor((time % 60000) / 1000), // seconds\n ]\n .map((v) => (v < 10 ? '0' + v : v))\n .join(':');\n progress.textContent = ConvertToPersianNumbers(formattedTime);\n };\n\n const hideMice = () => {\n mic.classList.add('hidden');\n };\n\n const showMice = () => {\n mic.classList.remove('hidden');\n };\n\n const hidePreview = () => {\n preview.classList.add('hidden');\n };\n const showPreview = () => {\n preview.classList.remove('hidden');\n };\n\n const stopButton = document.querySelector(\n containerSelector + ' .recorder-stop-button',\n );\n\n stopButton.onclick = () => {\n if (record.isRecording() || record.isPaused()) {\n record.stopRecording();\n hideMice();\n showPreview();\n stopButton.classList.add('hidden');\n previewControlButton.classList.remove('hidden');\n }\n };\n\n document.addEventListener(\n containerId + '-recorder-record-voice',\n async () => {\n let hasMicrophonePermission = true;\n if (navigator.permissions) {\n try {\n const permissionStatus = await navigator.permissions.query({\n name: 'microphone',\n });\n hasMicrophonePermission = permissionStatus.state !== 'denied';\n } catch {}\n }\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n hasMicrophonePermission = false;\n } else {\n try {\n if (\n !(await navigator.mediaDevices.enumerateDevices()).some(\n ({ kind }) => kind === 'audioinput',\n )\n ) {\n hasMicrophonePermission = false;\n }\n } catch {}\n }\n if (hasMicrophonePermission) {\n // reset the wavesurfer instance\n record.startRecording().then(() => {\n recorderContainer.classList.remove('hidden');\n preview.replaceChildren();\n stopButton.classList.remove('hidden');\n previewControlButton.classList.add('hidden');\n showMice();\n hidePreview();\n document.dispatchEvent(\n new CustomEvent(containerId + '-recorder-record-started'),\n );\n });\n } else {\n Livewire.dispatch('show-toast', {\n data: {\n text: 'برای ضبط صدا، باید دسترسی صدا را از طریق تنظیمات مرورگر خود فعال کنید.',\n status: 'error',\n },\n });\n }\n },\n );\n\n document.addEventListener(\n containerId + '-recorder-finish-record-voice',\n () => {\n recorderContainer.classList.add('hidden');\n preview.replaceChildren();\n createWaveSurfer();\n },\n );\n\n const deleteButton = document.querySelector(\n containerSelector + ' .delete-button',\n );\n deleteButton.onclick = () => {\n updateProgress(0);\n if (record.isRecording() || record.isPaused()) {\n record.stopRecording();\n }\n preview.replaceChildren();\n recorderContainer.classList.add('hidden');\n stopButton.classList.remove('hidden');\n previewControlButton.classList.add('hidden');\n createWaveSurfer();\n\n document.dispatchEvent(\n new CustomEvent(containerId + '-recorder-record-cancelled'),\n );\n };\n createWaveSurfer();\n};\n\nwindow.createRecorder = createRecorder;\n"],"names":["createRecorder","containerId","wavesurfer","record","scrollingWaveform","containerSelector","recorderContainer","mic","preview","previewControlButton","createWaveSurfer","WaveSurfer","RecordPlugin","blob","recordedUrl","currentTime","updateProgress","playIcon","pauseIcon","time","progress","formattedTime","v","ConvertToPersianNumbers","hideMice","showMice","hidePreview","showPreview","stopButton","hasMicrophonePermission","kind","deleteButton"],"mappings":"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"}