UNPKG

@cometchat/chat-uikit-react-native

Version:

Ready-to-use Chat UI Components for React Native

146 lines (145 loc) 5.94 kB
import React, { useCallback, useEffect, useRef, useState } from "react"; import { NativeEventEmitter, NativeModules, Platform, Text, View, } from "react-native"; import { Icon } from "../../../icons/Icon"; import { AnimatedAudioWaves } from "../../CometChatAudioBubble/AnimatedAudioWaves"; const { SoundPlayer } = NativeModules; const eventEmitter = new NativeEventEmitter(SoundPlayer); let listener; let interval; export const CometChatAudioPreview = ({ audioUrl, onPress, playIcon, pauseIcon, playViewContainerStyle = {}, playIconStyle = {}, playIconContainerStyle = {}, waveStyle = {}, waveContainerStyle = {}, playProgressTextStyle = {}, }) => { const [status, setStatus] = useState(""); const [duration, setDuration] = useState(0); const [currentTime, setCurrentTime] = useState(0); useEffect(() => { if (audioUrl) { SoundPlayer.prepareMediaPlayer(audioUrl, (s) => { setDuration(JSON.parse(s).duration); }); } return () => { Platform.OS == "android" && SoundPlayer.releaseMediaPlayer(); }; }, [audioUrl]); useEffect(() => { listener = eventEmitter.addListener("soundPlayStatus", (data) => { if (audioUrl === data.url) { setStatus("paused"); clearInterval(interval); setCurrentTime(duration); } }); return () => { listener.remove(); clearInterval(interval); }; }, [audioUrl]); const playPauseAudio = () => { if (onPress) { onPress(audioUrl); return; } if (status === "playing") { SoundPlayer.pause((s) => { try { const json = JSON.parse(s); if (json["success"] === true) { setStatus("paused"); clearInterval(interval); } } catch (ex) { console.log(ex); } }); return; } if (status === "paused") { SoundPlayer.resume(); if (Platform.OS == "ios") { setStatus("playing"); } // Get total duration when audio starts playing SoundPlayer.getPosition((info) => { if (info) { if (Platform.OS == "android") { setStatus("playing"); } setCurrentTime(JSON.parse(info).position); } }); // Start tracking the current time interval = setInterval(() => { SoundPlayer.getPosition((info) => { if (info) { setCurrentTime(JSON.parse(info).position); } }); }, 500); return; } if (audioUrl) { setStatus("loading"); SoundPlayer.play(audioUrl, (s) => { try { const json = JSON.parse(s); if (json["success"] == true) { setStatus("playing"); // Get total duration when audio starts playing SoundPlayer.getPosition((info) => { if (info) { setCurrentTime(JSON.parse(info).position); } }); // Start tracking the current time interval = setInterval(() => { SoundPlayer.getPosition((info) => { try { if (info) { setCurrentTime(JSON.parse(info).position); } } catch (e) { } }); }, 500); } } catch (ex) { console.log(ex); } }); } }; const pressTime = useRef(0); const handleTouchStart = () => { pressTime.current = Date.now(); }; const handleTouchEnd = () => { if (pressTime.current === null && Platform.OS === "ios") return; const endTime = Date.now(); const pressDuration = endTime - (pressTime.current ?? 0); if (pressDuration < 500) { playPauseAudio(); } }; const onTouchMove = () => { if (Platform.OS === "ios") { pressTime.current = null; } }; const displayDuration = useCallback(() => (<Text style={playProgressTextStyle}> {`${String(Math.floor((currentTime || 0) / 60)).padStart(2, "0")}:${String(Math.floor((currentTime || 0) % 60)).padStart(2, "0")}`} / {`${String(Math.floor((duration || 0) / 60)).padStart(2, "0")}:${String(Math.floor((duration || 0) % 60)).padStart(2, "0")}`} </Text>), [currentTime, duration]); return (<View style={playViewContainerStyle}> <View style={playIconContainerStyle} onTouchStart={handleTouchStart} onTouchEnd={handleTouchEnd} onTouchMove={onTouchMove}> <Icon name={status === "playing" ? "pause-fill" : "play-arrow-fill"} height={playIconStyle?.height} width={playIconStyle?.width} color={playIconStyle?.tintColor} imageStyle={playIconStyle} icon={status === "playing" ? pauseIcon : playIcon}/> </View> <View style={{ flex: 1, flexDirection: "row", alignItems: "center", width: "100%" }}> <AnimatedAudioWaves waveStyle={waveStyle} waveContainerStyle={waveContainerStyle} isAnimating={status === "playing"}/> {displayDuration()} </View> </View>); }; //# sourceMappingURL=CometChatAudioPreview.js.map