feat: add a focus state to audio player (#5491)
* feat: add a focus state to audio player * update the rcactivity indicator --------- Co-authored-by: Gleidson Daniel Silva <gleidson10daniel@hotmail.com>
This commit is contained in:
parent
dc0f824638
commit
c2656459ea
File diff suppressed because one or more lines are too long
|
@ -20,7 +20,7 @@ const Icon = ({ audioState, disabled }: { audioState: TAudioState; disabled: boo
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
|
|
||||||
if (audioState === 'loading') {
|
if (audioState === 'loading') {
|
||||||
return <RCActivityIndicator />;
|
return <RCActivityIndicator size={24} color={colors.buttonFontPrimary} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
let customIconName: TCustomIconName = 'arrow-down';
|
let customIconName: TCustomIconName = 'arrow-down';
|
||||||
|
|
|
@ -4,11 +4,10 @@ import { Text } from 'react-native';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { useTheme } from '../../theme';
|
import { useTheme } from '../../theme';
|
||||||
import { AUDIO_PLAYBACK_SPEED, AVAILABLE_SPEEDS } from './constants';
|
import { AUDIO_PLAYBACK_SPEED, AVAILABLE_SPEEDS } from './constants';
|
||||||
import { TAudioState } from './types';
|
|
||||||
import { useUserPreferences } from '../../lib/methods';
|
import { useUserPreferences } from '../../lib/methods';
|
||||||
import NativeButton from '../NativeButton';
|
import NativeButton from '../NativeButton';
|
||||||
|
|
||||||
const PlaybackSpeed = ({ audioState }: { audioState: TAudioState }) => {
|
const PlaybackSpeed = () => {
|
||||||
const [playbackSpeed, setPlaybackSpeed] = useUserPreferences<number>(AUDIO_PLAYBACK_SPEED, AVAILABLE_SPEEDS[1]);
|
const [playbackSpeed, setPlaybackSpeed] = useUserPreferences<number>(AUDIO_PLAYBACK_SPEED, AVAILABLE_SPEEDS[1]);
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
|
|
||||||
|
@ -20,7 +19,6 @@ const PlaybackSpeed = ({ audioState }: { audioState: TAudioState }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NativeButton
|
<NativeButton
|
||||||
disabled={audioState !== 'playing'}
|
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
style={[styles.containerPlaybackSpeed, { backgroundColor: colors.buttonBackgroundSecondaryDefault }]}
|
style={[styles.containerPlaybackSpeed, { backgroundColor: colors.buttonBackgroundSecondaryDefault }]}
|
||||||
>
|
>
|
||||||
|
|
|
@ -10,7 +10,8 @@ import styles from './styles';
|
||||||
import Seek from './Seek';
|
import Seek from './Seek';
|
||||||
import PlaybackSpeed from './PlaybackSpeed';
|
import PlaybackSpeed from './PlaybackSpeed';
|
||||||
import PlayButton from './PlayButton';
|
import PlayButton from './PlayButton';
|
||||||
import audioPlayer from '../../lib/methods/audioPlayer';
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
|
import audioPlayer, { AUDIO_FOCUSED } from '../../lib/methods/audioPlayer';
|
||||||
import { AUDIO_PLAYBACK_SPEED, AVAILABLE_SPEEDS } from './constants';
|
import { AUDIO_PLAYBACK_SPEED, AVAILABLE_SPEEDS } from './constants';
|
||||||
import { TDownloadState } from '../../lib/methods/handleMediaDownload';
|
import { TDownloadState } from '../../lib/methods/handleMediaDownload';
|
||||||
import { TAudioState } from './types';
|
import { TAudioState } from './types';
|
||||||
|
@ -39,6 +40,7 @@ const AudioPlayer = ({
|
||||||
|
|
||||||
const [playbackSpeed] = useUserPreferences<number>(AUDIO_PLAYBACK_SPEED, AVAILABLE_SPEEDS[1]);
|
const [playbackSpeed] = useUserPreferences<number>(AUDIO_PLAYBACK_SPEED, AVAILABLE_SPEEDS[1]);
|
||||||
const [paused, setPaused] = useState(true);
|
const [paused, setPaused] = useState(true);
|
||||||
|
const [focused, setFocused] = useState(false);
|
||||||
const duration = useSharedValue(0);
|
const duration = useSharedValue(0);
|
||||||
const currentTime = useSharedValue(0);
|
const currentTime = useSharedValue(0);
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
|
@ -139,6 +141,15 @@ const AudioPlayer = ({
|
||||||
};
|
};
|
||||||
}, [navigation]);
|
}, [navigation]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const listener = EventEmitter.addEventListener(AUDIO_FOCUSED, ({ audioFocused }: { audioFocused: string }) => {
|
||||||
|
setFocused(audioFocused === audioUri.current);
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
EventEmitter.removeListener(AUDIO_FOCUSED, listener);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
let audioState: TAudioState = 'to-download';
|
let audioState: TAudioState = 'to-download';
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
audioState = 'loading';
|
audioState = 'loading';
|
||||||
|
@ -154,7 +165,7 @@ const AudioPlayer = ({
|
||||||
<View style={[styles.audioContainer, { backgroundColor: colors.surfaceTint, borderColor: colors.strokeExtraLight }]}>
|
<View style={[styles.audioContainer, { backgroundColor: colors.surfaceTint, borderColor: colors.strokeExtraLight }]}>
|
||||||
<PlayButton disabled={disabled} audioState={audioState} onPress={onPress} />
|
<PlayButton disabled={disabled} audioState={audioState} onPress={onPress} />
|
||||||
<Seek currentTime={currentTime} duration={duration} loaded={!disabled && isDownloaded} onChangeTime={setPosition} />
|
<Seek currentTime={currentTime} duration={duration} loaded={!disabled && isDownloaded} onChangeTime={setPosition} />
|
||||||
{audioState === 'playing' ? <PlaybackSpeed audioState={audioState} /> : null}
|
{audioState === 'playing' || focused ? <PlaybackSpeed /> : null}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import { AVPlaybackStatus, Audio, InterruptionModeAndroid, InterruptionModeIOS } from 'expo-av';
|
import { AVPlaybackStatus, Audio, InterruptionModeAndroid, InterruptionModeIOS } from 'expo-av';
|
||||||
|
|
||||||
|
import EventEmitter from './helpers/events';
|
||||||
|
|
||||||
|
export const AUDIO_FOCUSED = 'AUDIO_FOCUSED';
|
||||||
|
|
||||||
const AUDIO_MODE = {
|
const AUDIO_MODE = {
|
||||||
allowsRecordingIOS: false,
|
allowsRecordingIOS: false,
|
||||||
playsInSilentModeIOS: true,
|
playsInSilentModeIOS: true,
|
||||||
|
@ -42,6 +46,7 @@ class AudioPlayer {
|
||||||
try {
|
try {
|
||||||
await this.audioQueue[audioKey]?.stopAsync();
|
await this.audioQueue[audioKey]?.stopAsync();
|
||||||
this.audioPlaying = '';
|
this.audioPlaying = '';
|
||||||
|
EventEmitter.emit(AUDIO_FOCUSED, { audioFocused: '' });
|
||||||
} catch {
|
} catch {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -62,6 +67,7 @@ class AudioPlayer {
|
||||||
await Audio.setAudioModeAsync(AUDIO_MODE);
|
await Audio.setAudioModeAsync(AUDIO_MODE);
|
||||||
await this.audioQueue[audioKey]?.playAsync();
|
await this.audioQueue[audioKey]?.playAsync();
|
||||||
this.audioPlaying = audioKey;
|
this.audioPlaying = audioKey;
|
||||||
|
EventEmitter.emit(AUDIO_FOCUSED, { audioFocused: audioKey });
|
||||||
}
|
}
|
||||||
|
|
||||||
async pauseAudio(audioKey: string) {
|
async pauseAudio(audioKey: string) {
|
||||||
|
|
|
@ -12,7 +12,8 @@ type TEventEmitterEmmitArgs =
|
||||||
| { visible: boolean; onCancel?: null | Function }
|
| { visible: boolean; onCancel?: null | Function }
|
||||||
| { cancel: () => void }
|
| { cancel: () => void }
|
||||||
| { submit: (param: string) => void }
|
| { submit: (param: string) => void }
|
||||||
| IEmitUserInteraction;
|
| IEmitUserInteraction
|
||||||
|
| { audioFocused: string };
|
||||||
|
|
||||||
class EventEmitter {
|
class EventEmitter {
|
||||||
private events: { [key: string]: any };
|
private events: { [key: string]: any };
|
||||||
|
|
Loading…
Reference in New Issue