UNPKG

@sendbird/uikit-react-native

Version:

Sendbird UIKit for React Native: A feature-rich and customizable chat UI kit with messaging, channel management, and user authentication.

196 lines 6.51 kB
import { useRef, useState } from 'react'; import { useAlert } from '@sendbird/uikit-react-native-foundation'; import { Logger, getVoiceMessageFileObject, matchesOneOf } from '@sendbird/uikit-utils'; import SBUUtils from '../libs/SBUUtils'; import { useLocalization, usePlatformService } from './useContext'; const useVoiceMessageInput = ({ onSend, onClose }) => { const { alert } = useAlert(); const { STRINGS } = useLocalization(); const { recorderService, playerService, fileService } = usePlatformService(); const [status, setStatus] = useState('idle'); const [recordingTime, setRecordingTime] = useState({ currentTime: 0, minDuration: recorderService.options.minDuration, maxDuration: recorderService.options.maxDuration }); const [playingTime, setPlayingTime] = useState({ currentTime: 0, duration: 0 }); const recordingPath = useRef(); const getVoiceMessageRecordingPath = () => { if (!recordingPath.current) throw new Error('No recording path'); return recordingPath.current; }; const setVoiceMessageRecordingPath = path => { recordingPath.current = path; }; const clear = async () => { recordingPath.current = undefined; await playerService.reset(); await recorderService.reset(); setRecordingTime({ currentTime: 0, minDuration: recorderService.options.minDuration, maxDuration: recorderService.options.maxDuration }); setPlayingTime({ currentTime: 0, duration: 0 }); setStatus('idle'); }; return { state: { status, recordingTime, playingTime }, actions: { async cancel() { await clear(); }, async startRecording() { const granted = await recorderService.requestPermission(); if (!granted) { await onClose(); alert({ title: STRINGS.DIALOG.ALERT_PERMISSIONS_TITLE, message: STRINGS.DIALOG.ALERT_PERMISSIONS_MESSAGE(STRINGS.LABELS.PERMISSION_MICROPHONE, STRINGS.LABELS.PERMISSION_APP_NAME), buttons: [{ text: STRINGS.DIALOG.ALERT_PERMISSIONS_OK, onPress: () => SBUUtils.openSettings() }] }); Logger.error('Failed to request permission for recorder'); return; } if (matchesOneOf(status, ['idle'])) { // Before start recording, if player is not idle, reset it. if (playerService.state !== 'idle') { await playerService.reset(); } const unsubscribeRecording = recorderService.addRecordingListener(({ currentTime }) => { setRecordingTime({ currentTime, maxDuration: recorderService.options.maxDuration, minDuration: recorderService.options.minDuration }); setPlayingTime(prev => ({ ...prev, duration: currentTime })); }); const unsubscribeState = recorderService.addStateListener(state => { switch (state) { case 'recording': setStatus('recording'); break; case 'completed': setStatus('recording_completed'); unsubscribeRecording(); unsubscribeState(); break; } }); if (SBUUtils.isExpo()) { await recorderService.record(); if (recorderService.uri) { setVoiceMessageRecordingPath({ recordFilePath: recorderService.uri, uri: recorderService.uri }); } } else { setVoiceMessageRecordingPath(fileService.createRecordFilePath(recorderService.options.extension)); await recorderService.record(getVoiceMessageRecordingPath().recordFilePath); } } }, async stopRecording() { if (matchesOneOf(status, ['recording'])) { await recorderService.stop(); } }, async playPlayer() { const granted = await playerService.requestPermission(); if (!granted) { alert({ title: STRINGS.DIALOG.ALERT_PERMISSIONS_TITLE, message: STRINGS.DIALOG.ALERT_PERMISSIONS_MESSAGE(STRINGS.LABELS.PERMISSION_DEVICE_STORAGE, STRINGS.LABELS.PERMISSION_APP_NAME), buttons: [{ text: STRINGS.DIALOG.ALERT_PERMISSIONS_OK, onPress: () => SBUUtils.openSettings() }] }); Logger.error('Failed to request permission for player'); return; } if (matchesOneOf(status, ['recording_completed', 'playing_paused'])) { const unsubscribePlayback = playerService.addPlaybackListener(({ currentTime, duration }) => { setPlayingTime({ currentTime, duration }); }); const unsubscribeState = playerService.addStateListener(state => { switch (state) { case 'playing': setStatus('playing'); break; case 'paused': { setStatus('playing_paused'); unsubscribeState(); unsubscribePlayback(); break; } case 'stopped': { setStatus('playing_paused'); unsubscribeState(); unsubscribePlayback(); setPlayingTime(prev => ({ ...prev, currentTime: 0 })); break; } } }); await playerService.play(getVoiceMessageRecordingPath().recordFilePath); } }, async pausePlayer() { if (matchesOneOf(status, ['playing'])) { await playerService.pause(); } }, async send() { if (matchesOneOf(status, ['recording', 'recording_completed', 'playing', 'playing_paused']) && recordingPath.current) { const voiceFile = getVoiceMessageFileObject(recordingPath.current.uri, recorderService.options.extension); onSend(voiceFile, Math.floor(recordingTime.currentTime)); await clear(); } } } }; }; export default useVoiceMessageInput; //# sourceMappingURL=useVoiceMessageInput.js.map