From 2b379ee281fb636627163224966a3e2b13ae41ea Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Tue, 3 Oct 2023 19:05:24 -0300 Subject: [PATCH] refactor audio component --- app/containers/AudioPlayer/PlayButton.tsx | 6 +- app/containers/AudioPlayer/index.tsx | 118 ++++-------------- .../message/Components/Audio/index.tsx | 84 ++++++++++++- 3 files changed, 109 insertions(+), 99 deletions(-) diff --git a/app/containers/AudioPlayer/PlayButton.tsx b/app/containers/AudioPlayer/PlayButton.tsx index 80501596e..7b2c0a0e0 100644 --- a/app/containers/AudioPlayer/PlayButton.tsx +++ b/app/containers/AudioPlayer/PlayButton.tsx @@ -11,18 +11,18 @@ interface IButton { paused: boolean; disabled?: boolean; onPress: () => void; - cached: boolean; + isReadyToPlay: boolean; } const BUTTON_HIT_SLOP = { top: 12, right: 12, bottom: 12, left: 12 }; type TCustomIconName = 'arrow-down' | 'play-shape-filled' | 'pause-shape-filled'; -const PlayButton = React.memo(({ loading, paused, onPress, disabled, cached }: IButton) => { +const PlayButton = React.memo(({ loading, paused, onPress, disabled, isReadyToPlay }: IButton) => { const { colors } = useTheme(); let customIconName: TCustomIconName = 'arrow-down'; - if (cached) { + if (isReadyToPlay) { customIconName = paused ? 'play-shape-filled' : 'pause-shape-filled'; } return ( diff --git a/app/containers/AudioPlayer/index.tsx b/app/containers/AudioPlayer/index.tsx index 459dfff39..cc88079e8 100644 --- a/app/containers/AudioPlayer/index.tsx +++ b/app/containers/AudioPlayer/index.tsx @@ -1,13 +1,10 @@ import React, { useEffect, useRef, useState } from 'react'; -import { StyleProp, TextStyle, View } from 'react-native'; +import { View } from 'react-native'; import { AVPlaybackStatus } from 'expo-av'; import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake'; import { useSharedValue } from 'react-native-reanimated'; -import { IAttachment, IUserMessage } from '../../definitions'; import { useTheme } from '../../theme'; -import { downloadMediaFile, getMediaCache } from '../../lib/methods/handleMediaDownload'; -import { fetchAutoDownloadEnabled } from '../../lib/methods/autoDownloadPreference'; import styles from './styles'; import Seek from './Seek'; import PlaybackSpeed from './PlaybackSpeed'; @@ -15,19 +12,21 @@ import PlayButton from './PlayButton'; import audioPlayer from '../../lib/methods/audioPlayer'; interface IAudioPlayerProps { - file: IAttachment; - isReply?: boolean; - style?: StyleProp[]; - author?: IUserMessage; - msg?: string; - baseUrl: string; - user: any; + fileUri: string; + loading: boolean; + isReadyToPlay: boolean; + disabled?: boolean; + onPressCallback?: Function; } -const AudioPlayer = ({ file, author, isReply = false, baseUrl, user }: IAudioPlayerProps) => { - const [loading, setLoading] = useState(true); +const AudioPlayer = ({ + fileUri, + disabled = false, + loading = true, + isReadyToPlay = false, + onPressCallback = () => {} +}: IAudioPlayerProps) => { const [paused, setPaused] = useState(true); - const [cached, setCached] = useState(false); const [rate, setRate] = useState(1); const duration = useSharedValue(0); @@ -45,12 +44,6 @@ const AudioPlayer = ({ file, author, isReply = false, baseUrl, user }: IAudioPla } }; - const loadAudio = async (audio: string) => { - await audioPlayer.loadAudio(audio); - audioUri.current = audio; - audioPlayer.setOnPlaybackStatusUpdate(audio, onPlaybackStatusUpdate); - }; - const onPlaying = (data: AVPlaybackStatus) => { if (data.isLoaded && data.isPlaying) { setPaused(false); @@ -88,14 +81,6 @@ const AudioPlayer = ({ file, author, isReply = false, baseUrl, user }: IAudioPla await audioPlayer.setPositionAsync(audioUri.current, time); }; - const getUrl = () => { - let url = file.audio_url; - if (url && !url.startsWith('http')) { - url = `${baseUrl}${file.audio_url}`; - } - return url; - }; - const togglePlayPause = async () => { try { if (!paused) { @@ -112,76 +97,24 @@ const AudioPlayer = ({ file, author, isReply = false, baseUrl, user }: IAudioPla await audioPlayer.setRateAsync(audioUri.current, value); }; - const handleDownload = async () => { - setLoading(true); - try { - const url = getUrl(); - if (url) { - const audio = await downloadMediaFile({ - downloadUrl: `${url}?rc_uid=${user.id}&rc_token=${user.token}`, - type: 'audio', - mimeType: file.audio_type - }); - await loadAudio(audio); - setLoading(false); - setCached(true); - } - } catch { - setLoading(false); - setCached(false); - } - }; - - const handleAutoDownload = async () => { - const url = getUrl(); - try { - if (url) { - const isCurrentUserAuthor = author?._id === user.id; - const isAutoDownloadEnabled = fetchAutoDownloadEnabled('audioPreferenceDownload'); - if (isAutoDownloadEnabled || isCurrentUserAuthor) { - await handleDownload(); - return; - } - setLoading(false); - setCached(false); - } - } catch { - // Do nothing - } - }; - const onPress = () => { + onPressCallback(); if (loading) { return; } - if (cached) { + if (isReadyToPlay) { togglePlayPause(); - return; } - handleDownload(); }; useEffect(() => { - const handleCache = async () => { - const cachedAudioResult = await getMediaCache({ - type: 'audio', - mimeType: file.audio_type, - urlToCache: getUrl() - }); - if (cachedAudioResult?.exists) { - await loadAudio(cachedAudioResult.uri); - setLoading(false); - setCached(true); - return; - } - if (isReply) { - setLoading(false); - return; - } - await handleAutoDownload(); + const loadAudio = async (audio: string) => { + await audioPlayer.loadAudio(audio); + audioUri.current = audio; + audioPlayer.setOnPlaybackStatusUpdate(audio, onPlaybackStatusUpdate); }; - handleCache(); - }, []); + loadAudio(fileUri); + }, [fileUri]); useEffect(() => { if (paused) { @@ -191,15 +124,12 @@ const AudioPlayer = ({ file, author, isReply = false, baseUrl, user }: IAudioPla } }, [paused]); - if (!baseUrl) { - return null; - } return ( <> - - - + + + ); diff --git a/app/containers/message/Components/Audio/index.tsx b/app/containers/message/Components/Audio/index.tsx index 5425105f8..266581738 100644 --- a/app/containers/message/Components/Audio/index.tsx +++ b/app/containers/message/Components/Audio/index.tsx @@ -1,10 +1,12 @@ -import React, { useContext } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { StyleProp, TextStyle } from 'react-native'; import Markdown from '../../../markdown'; import MessageContext from '../../Context'; import { TGetCustomEmoji } from '../../../../definitions/IEmoji'; import { IAttachment, IUserMessage } from '../../../../definitions'; +import { downloadMediaFile, getMediaCache } from '../../../../lib/methods/handleMediaDownload'; +import { fetchAutoDownloadEnabled } from '../../../../lib/methods/autoDownloadPreference'; import AudioPlayer from '../../../AudioPlayer'; interface IMessageAudioProps { @@ -17,15 +19,93 @@ interface IMessageAudioProps { } const MessageAudio = ({ file, getCustomEmoji, author, isReply, style, msg }: IMessageAudioProps) => { + const [loading, setLoading] = useState(true); + const [cached, setCached] = useState(false); + const [fileUri, setFileUri] = useState(''); + const { baseUrl, user } = useContext(MessageContext); + const getUrl = () => { + let url = file.audio_url; + if (url && !url.startsWith('http')) { + url = `${baseUrl}${file.audio_url}`; + } + return url; + }; + + const onPress = () => { + if (!cached) { + handleDownload(); + } + }; + + const handleDownload = async () => { + setLoading(true); + try { + const url = getUrl(); + if (url) { + const audio = await downloadMediaFile({ + downloadUrl: `${url}?rc_uid=${user.id}&rc_token=${user.token}`, + type: 'audio', + mimeType: file.audio_type + }); + setFileUri(audio); + setLoading(false); + setCached(true); + } + } catch { + setLoading(false); + setCached(false); + } + }; + + const handleAutoDownload = async () => { + const url = getUrl(); + try { + if (url) { + const isCurrentUserAuthor = author?._id === user.id; + const isAutoDownloadEnabled = fetchAutoDownloadEnabled('audioPreferenceDownload'); + if (isAutoDownloadEnabled || isCurrentUserAuthor) { + await handleDownload(); + return; + } + setLoading(false); + setCached(false); + } + } catch { + // Do nothing + } + }; + + useEffect(() => { + const handleCache = async () => { + const cachedAudioResult = await getMediaCache({ + type: 'audio', + mimeType: file.audio_type, + urlToCache: getUrl() + }); + if (cachedAudioResult?.exists) { + setFileUri(cachedAudioResult.uri); + setLoading(false); + setCached(true); + return; + } + if (isReply) { + setLoading(false); + return; + } + await handleAutoDownload(); + }; + handleCache(); + }, []); + if (!baseUrl) { return null; } return ( <> - + ); };