removed the sound manipulation from Slider to manipulate only in the index

This commit is contained in:
Reinaldo Neto 2023-08-10 17:36:26 -03:00
parent 9c00ce08f4
commit 9066432ca2
3 changed files with 76 additions and 78 deletions

View File

@ -5,7 +5,7 @@ import styles from './styles';
import { useTheme } from '../../../../theme';
import Touchable from '../../Touchable';
const AudioRate = ({ onChange }: { onChange: (value: number) => void }) => {
const AudioRate = ({ onChange, loaded = false }: { onChange: (value: number) => void; loaded: boolean }) => {
const [rate, setRate] = useState(1.0);
const { colors } = useTheme();
@ -16,7 +16,11 @@ const AudioRate = ({ onChange }: { onChange: (value: number) => void }) => {
};
return (
<Touchable onPress={onPress} style={[styles.containerAudioRate, { backgroundColor: colors.audioRateBackground }]}>
<Touchable
disabled={!loaded}
onPress={onPress}
style={[styles.containerAudioRate, { backgroundColor: colors.audioRateBackground }]}
>
<Text style={[styles.audioRateText, { color: colors.audioRateText }]}>{rate}x</Text>
</Touchable>
);

View File

@ -1,7 +1,8 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import { LayoutChangeEvent, View, TextInput } from 'react-native';
import { PanGestureHandler } from 'react-native-gesture-handler';
import Animated, {
SharedValue,
runOnJS,
useAnimatedGestureHandler,
useAnimatedProps,
@ -9,8 +10,6 @@ import Animated, {
useDerivedValue,
useSharedValue
} from 'react-native-reanimated';
import { Sound } from 'expo-av/build/Audio/Sound';
import { AVPlaybackStatus } from 'expo-av';
import styles from './styles';
import { useTheme } from '../../../../theme';
@ -18,18 +17,15 @@ import { useTheme } from '../../../../theme';
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
interface ISlider {
thumbColor: string;
sound: Sound | null;
onEndCallback: () => void;
duration: SharedValue<number>;
currentTime: SharedValue<number>;
loaded: boolean;
onChangeTime: (time: number) => Promise<void>;
}
const Slider = ({ thumbColor = '', sound, onEndCallback }: ISlider) => {
const [loaded, setLoaded] = useState(false);
const Slider = ({ currentTime, duration, loaded = false, onChangeTime }: ISlider) => {
const { colors } = useTheme();
const duration = useSharedValue(0);
const currentTime = useSharedValue(0);
const maxWidth = useSharedValue(1);
const x = useSharedValue(0);
const current = useSharedValue('00:00');
@ -37,46 +33,6 @@ const Slider = ({ thumbColor = '', sound, onEndCallback }: ISlider) => {
const isHandlePan = useSharedValue(false);
const onEndGestureHandler = useSharedValue(false);
const onPlaybackStatusUpdate = (status: AVPlaybackStatus) => {
if (status) {
onLoad(status);
onProgress(status);
onEnd(status);
}
};
useEffect(() => {
if (sound) {
sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
}
}, [sound]);
const onLoad = (data: AVPlaybackStatus) => {
if (data.isLoaded && data.durationMillis) {
const durationSeconds = data.durationMillis / 1000;
duration.value = durationSeconds > 0 ? durationSeconds : 0;
setLoaded(true);
}
};
const onProgress = (data: AVPlaybackStatus) => {
if (data.isLoaded) {
const currentSecond = data.positionMillis / 1000;
if (currentSecond <= duration.value) {
currentTime.value = currentSecond;
}
}
};
const onEnd = (data: AVPlaybackStatus) => {
if (data.isLoaded) {
if (data.didJustFinish) {
onEndCallback();
currentTime.value = 0;
}
}
};
const styleLine = useAnimatedStyle(() => ({
width: x.value,
zIndex: 2
@ -116,7 +72,7 @@ const Slider = ({ thumbColor = '', sound, onEndCallback }: ISlider) => {
});
const wrapper = async (time: number) => {
await sound?.setPositionAsync(Math.round(time * 1000));
await onChangeTime(Math.round(time * 1000));
onEndGestureHandler.value = false;
};
@ -153,6 +109,8 @@ const Slider = ({ thumbColor = '', sound, onEndCallback }: ISlider) => {
[current]
);
const thumbColor = loaded ? colors.audioPlayerPrimary : colors.tintDisabled;
return (
<View style={styles.sliderContainer}>
<AnimatedTextInput

View File

@ -1,8 +1,9 @@
import React, { useContext, useEffect, useRef, useState } from 'react';
import { StyleProp, TextStyle, View } from 'react-native';
import { Audio, InterruptionModeAndroid, InterruptionModeIOS } from 'expo-av';
import { AVPlaybackStatus, Audio, InterruptionModeAndroid, InterruptionModeIOS } from 'expo-av';
import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake';
import { Sound } from 'expo-av/build/Audio/Sound';
import { useSharedValue } from 'react-native-reanimated';
import Touchable from '../../Touchable';
import Markdown from '../../../markdown';
@ -79,12 +80,65 @@ const MessageAudio = ({ file, getCustomEmoji, author, isReply, style }: IMessage
const [paused, setPaused] = useState(true);
const [cached, setCached] = useState(false);
const duration = useSharedValue(0);
const currentTime = useSharedValue(0);
const { baseUrl, user } = useContext(MessageContext);
const { colors } = useTheme();
const sound = useRef<Sound | null>(null);
const onPlaybackStatusUpdate = (status: AVPlaybackStatus) => {
if (status) {
onLoad(status);
onProgress(status);
onEnd(status);
}
};
const loadAudio = async (audio: string) => {
const { sound: soundLoaded } = await Audio.Sound.createAsync({ uri: audio });
sound.current = soundLoaded;
sound.current.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
};
const onLoad = (data: AVPlaybackStatus) => {
if (data.isLoaded && data.durationMillis) {
const durationSeconds = data.durationMillis / 1000;
duration.value = durationSeconds > 0 ? durationSeconds : 0;
}
};
const onProgress = (data: AVPlaybackStatus) => {
if (data.isLoaded) {
const currentSecond = data.positionMillis / 1000;
if (currentSecond <= duration.value) {
currentTime.value = currentSecond;
}
}
};
const onEnd = async (data: AVPlaybackStatus) => {
if (data.isLoaded) {
if (data.didJustFinish) {
try {
await sound.current?.stopAsync();
setPaused(true);
EventEmitter.removeListener(PAUSE_AUDIO, pauseSound);
currentTime.value = 0;
} catch {
// do nothing
}
}
}
};
const setPosition = async (time: number) => {
await sound.current?.setPositionAsync(time);
};
const pauseSound = () => {
console.log('🚀🚀🚀🚀🚀🚀🚀 ~ file: index.tsx:141 ~ pauseSound ~ pauseSound:');
EventEmitter.removeListener(PAUSE_AUDIO, pauseSound);
setPaused(true);
playPause(true);
@ -98,17 +152,8 @@ const MessageAudio = ({ file, getCustomEmoji, author, isReply, style }: IMessage
return url;
};
const onEnd = async () => {
try {
await sound.current?.stopAsync();
setPaused(true);
EventEmitter.removeListener(PAUSE_AUDIO, pauseSound);
} catch {
// do nothing
}
};
const togglePlayPause = () => {
console.log('🚀 ~ file: index.tsx:156 ~ togglePlayPause ~ paused:', paused);
setPaused(!paused);
playPause(!paused);
};
@ -143,7 +188,7 @@ const MessageAudio = ({ file, getCustomEmoji, author, isReply, style }: IMessage
type: 'audio',
mimeType: file.audio_type
});
await sound.current?.loadAsync({ uri: audio });
await loadAudio(audio);
setLoading(false);
setCached(true);
}
@ -190,8 +235,7 @@ const MessageAudio = ({ file, getCustomEmoji, author, isReply, style }: IMessage
urlToCache: getUrl()
});
if (cachedAudioResult?.exists) {
const { sound: soundLoaded } = await Audio.Sound.createAsync({ uri: cachedAudioResult.uri });
sound.current = soundLoaded;
await loadAudio(cachedAudioResult.uri);
setLoading(false);
setCached(true);
return;
@ -228,14 +272,6 @@ const MessageAudio = ({ file, getCustomEmoji, author, isReply, style }: IMessage
if (!baseUrl) {
return null;
}
let thumbColor;
if (isReply) {
thumbColor = colors.tintDisabled;
} else {
thumbColor = colors.audioPlayerPrimary;
}
return (
<>
<Markdown msg={file.description} style={[isReply && style]} username={user.username} getCustomEmoji={getCustomEmoji} />
@ -246,8 +282,8 @@ const MessageAudio = ({ file, getCustomEmoji, author, isReply, style }: IMessage
]}
>
<Button disabled={isReply} loading={loading} paused={paused} cached={cached} onPress={onPress} />
<Slider sound={sound.current} thumbColor={thumbColor} onEndCallback={onEnd} />
<AudioRate onChange={setRate} />
<Slider currentTime={currentTime} duration={duration} loaded={!isReply && cached} onChangeTime={setPosition} />
<AudioRate onChange={setRate} loaded={!isReply && cached} />
</View>
</>
);