{isRecording && ( )} {actionPauseAudio && ( )} {hasRecordingAndPaused && ( )} {hasRecording && ( )} {actionDefault && }
{hasRecording && !isRecording ? (
{displayTimeString + remainingTimeString}
) : null} {isRecording ? (
{displayTimeString}
) : null} {!isRecording && (
)}
); } private async timerUpdate() { const { nowTimestamp, startTimestamp } = this.state; const elapsedTime = nowTimestamp - startTimestamp; // Prevent voice messages exceeding max length. if (elapsedTime >= Constants.CONVERSATION.MAX_VOICE_MESSAGE_DURATION) { await this.stopRecordingStream(); } this.setState({ nowTimestamp: getTimestamp(), }); } private stopRecordingState() { this.setState({ isRecording: false, isPaused: true, }); } private async playAudio() { // Generate audio element if it doesn't exist const { recordDuration } = this.state; if (!this.audioBlobMp3) { return; } if (this.audioElement) { window?.log?.info('Audio element already init'); } else { const audioURL = window.URL.createObjectURL(this.audioBlobMp3); this.audioElement = new Audio(audioURL); this.audioElement.loop = false; this.audioElement.onended = () => { this.pauseAudio(); }; this.audioElement.oncanplaythrough = async () => { const duration = recordDuration; if (duration && this.audioElement && this.audioElement.currentTime < duration) { await this.audioElement?.play(); } }; } this.setState({ isRecording: false, isPaused: false, isPlaying: true, }); await this.audioElement.play(); } private pauseAudio() { if (this.audioElement) { this.audioElement.pause(); } this.setState({ isPlaying: false, isPaused: true, }); } private async onDeleteVoiceMessage() { this.pauseAudio(); await this.stopRecordingStream(); this.audioBlobMp3 = undefined; this.audioElement = null; this.props.onExitVoiceNoteView(); } /** * Sends the recorded voice message */ private async onSendVoiceMessage() { if (!this.audioBlobMp3 || !this.audioBlobMp3.size) { window?.log?.info('Empty audio blob'); return; } // Is the audio file > attachment filesize limit if (this.audioBlobMp3.size > MAX_ATTACHMENT_FILESIZE_BYTES) { ToastUtils.pushFileSizeErrorAsByte(MAX_ATTACHMENT_FILESIZE_BYTES); return; } void this.props.sendVoiceMessage(this.audioBlobMp3); } private async initiateRecordingStream() { // Start recording. Browser will request permission to use your microphone. if (this.recorder) { await this.stopRecordingStream(); } this.recorder = new MicRecorder({ bitRate: 128, }); this.recorder .start() .then(() => { // something else }) .catch((e: any) => { window?.log?.error(e); }); } /** * Stops recording audio, sets recording state to stopped. */ private async stopRecordingStream() { if (!this.recorder) { return; } const [_, blob] = await this.recorder.stop().getMp3(); this.recorder = undefined; this.audioBlobMp3 = blob; this.updateAudioElementAndDuration(); // Stop recording this.stopRecordingState(); } /** * Creates an audio element using the recorded audio blob. * Updates the duration for displaying audio duration. */ private updateAudioElementAndDuration() { // init audio element if (!this.audioBlobMp3) { return; } const audioURL = window.URL.createObjectURL(this.audioBlobMp3); this.audioElement = new Audio(audioURL); this.setState({ recordDuration: this.audioElement.duration, }); this.audioElement.loop = false; this.audioElement.onended = () => { this.pauseAudio(); }; this.audioElement.oncanplaythrough = async () => { const duration = this.state.recordDuration; if (duration && this.audioElement && this.audioElement.currentTime < duration) { await this.audioElement?.play(); } }; } private async onKeyDown(event: any) { if (event.key === 'Escape') { await this.onDeleteVoiceMessage(); } } }