Add onSlidingStart and onSLidingEnd callbacks
This commit is contained in:
parent
0f8920203d
commit
4cb6674eb4
|
@ -10,7 +10,9 @@ import { useTheme } from '../../../../theme';
|
||||||
interface ISliderProps {
|
interface ISliderProps {
|
||||||
value: number;
|
value: number;
|
||||||
maximumValue: number;
|
maximumValue: number;
|
||||||
onValueChange: (value: number) => Promise<void>;
|
onValueChange: (value: number) => void;
|
||||||
|
onSlidingStart: () => void;
|
||||||
|
onSlidingEnd: (value: number) => void;
|
||||||
thumbTintColor?: string;
|
thumbTintColor?: string;
|
||||||
minimumTrackTintColor?: string;
|
minimumTrackTintColor?: string;
|
||||||
maximumTrackTintColor?: string;
|
maximumTrackTintColor?: string;
|
||||||
|
@ -25,6 +27,8 @@ const Slider = React.memo(
|
||||||
value,
|
value,
|
||||||
maximumValue,
|
maximumValue,
|
||||||
onValueChange,
|
onValueChange,
|
||||||
|
onSlidingStart,
|
||||||
|
onSlidingEnd,
|
||||||
thumbTintColor,
|
thumbTintColor,
|
||||||
minimumTrackTintColor,
|
minimumTrackTintColor,
|
||||||
maximumTrackTintColor,
|
maximumTrackTintColor,
|
||||||
|
@ -68,6 +72,7 @@ const Slider = React.memo(
|
||||||
.hitSlop({ horizontal: 5, vertical: 20 })
|
.hitSlop({ horizontal: 5, vertical: 20 })
|
||||||
.onStart(() => {
|
.onStart(() => {
|
||||||
setSliding(true);
|
setSliding(true);
|
||||||
|
onSlidingStart();
|
||||||
sliderThumbWidth.value = withTiming(3 * SLIDER_THUMB_RADIUS, { duration: 100 });
|
sliderThumbWidth.value = withTiming(3 * SLIDER_THUMB_RADIUS, { duration: 100 });
|
||||||
})
|
})
|
||||||
.onChange(e => {
|
.onChange(e => {
|
||||||
|
@ -78,6 +83,7 @@ const Slider = React.memo(
|
||||||
sliderThumbWidth.value = withTiming(2 * SLIDER_THUMB_RADIUS, { duration: 100 });
|
sliderThumbWidth.value = withTiming(2 * SLIDER_THUMB_RADIUS, { duration: 100 });
|
||||||
currentValue.value = equivalentValue(clamp(e.x, 0, sliderWidth));
|
currentValue.value = equivalentValue(clamp(e.x, 0, sliderWidth));
|
||||||
onValueChange(equivalentValue(clamp(e.x, 0, sliderWidth)));
|
onValueChange(equivalentValue(clamp(e.x, 0, sliderWidth)));
|
||||||
|
onSlidingEnd(equivalentValue(clamp(e.x, 0, sliderWidth)));
|
||||||
setSliding(false);
|
setSliding(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,9 @@ import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { StyleProp, StyleSheet, Text, TextStyle, View } from 'react-native';
|
import { StyleProp, StyleSheet, Text, TextStyle, View } from 'react-native';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake';
|
import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake';
|
||||||
// import Slider from '@react-native-community/slider';
|
import { Audio, AVPlaybackStatus } from 'expo-av';
|
||||||
import TrackPlayer, { Event, useTrackPlayerEvents, State, useProgress } from 'react-native-track-player';
|
import TrackPlayer, { Event, useTrackPlayerEvents, State, useProgress } from 'react-native-track-player';
|
||||||
import { Easing } from 'react-native-reanimated';
|
import { Easing } from 'react-native-reanimated';
|
||||||
import { useMMKVStorage } from 'react-native-mmkv-storage';
|
|
||||||
|
|
||||||
import Touchable from '../../Touchable';
|
import Touchable from '../../Touchable';
|
||||||
import Markdown from '../../../markdown';
|
import Markdown from '../../../markdown';
|
||||||
|
@ -23,7 +22,7 @@ import { IAttachment } from '../../../../definitions';
|
||||||
import { TSupportedThemes } from '../../../../theme';
|
import { TSupportedThemes } from '../../../../theme';
|
||||||
import { setupService } from './services';
|
import { setupService } from './services';
|
||||||
import Slider from './Slider';
|
import Slider from './Slider';
|
||||||
import { TracksStorage, addTrack, clearTracks, getCurrentTrack, setCurrentTrack } from './tracks';
|
import { useTracks } from './tracksStorage';
|
||||||
|
|
||||||
interface IButton {
|
interface IButton {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
@ -103,15 +102,16 @@ const MessageAudio = ({
|
||||||
getCustomEmoji
|
getCustomEmoji
|
||||||
}: // scale
|
}: // scale
|
||||||
IMessageAudioProps) => {
|
IMessageAudioProps) => {
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [paused, setPaused] = useState(true);
|
|
||||||
const [currentTime, setCurrentTime] = useState(0);
|
|
||||||
|
|
||||||
const { baseUrl, user } = useContext(MessageContext);
|
const { baseUrl, user } = useContext(MessageContext);
|
||||||
|
|
||||||
const { duration } = useProgress();
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [paused, setPaused] = useState(true);
|
||||||
|
const [currentPosition, setCurrentPosition] = useState(0);
|
||||||
|
const [duration, setDuration] = useState(0);
|
||||||
|
const [isSliding, setIsSliding] = useState(false);
|
||||||
|
const { position } = useProgress();
|
||||||
|
|
||||||
const [tracks] = useMMKVStorage('tracks', TracksStorage);
|
const [currentTrackId, setCurrentTrackId] = useTracks('currentTrackId');
|
||||||
|
|
||||||
let url = file.audio_url;
|
let url = file.audio_url;
|
||||||
if (url && !url.startsWith('http')) {
|
if (url && !url.startsWith('http')) {
|
||||||
|
@ -122,34 +122,48 @@ IMessageAudioProps) => {
|
||||||
id: `${url}?rc_uid=${user.id}&rc_token=${user.token}`,
|
id: `${url}?rc_uid=${user.id}&rc_token=${user.token}`,
|
||||||
url: `${url}?rc_uid=${user.id}&rc_token=${user.token}`,
|
url: `${url}?rc_uid=${user.id}&rc_token=${user.token}`,
|
||||||
title: file.title,
|
title: file.title,
|
||||||
artist: file.author_name,
|
artist: file.author_name
|
||||||
duration
|
};
|
||||||
|
|
||||||
|
const updateTrackDuration = (status: AVPlaybackStatus) => {
|
||||||
|
if (status.isLoaded && status.durationMillis) {
|
||||||
|
const trackDuration = status.durationMillis / 1000;
|
||||||
|
setDuration(trackDuration > 0 ? trackDuration : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const setup = async () => {
|
const setup = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
try {
|
||||||
await setupService();
|
await setupService();
|
||||||
addTrack({ trackId: track.id, title: file.title, artist: file.author_name, isPlaying: false });
|
const sound = new Audio.Sound();
|
||||||
|
sound.setOnPlaybackStatusUpdate(updateTrackDuration);
|
||||||
|
await sound.loadAsync({ uri: `${url}?rc_uid=${user.id}&rc_token=${user.token}` });
|
||||||
|
} catch {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
setup();
|
setup();
|
||||||
return () => {
|
return () => {
|
||||||
TrackPlayer.reset();
|
TrackPlayer.destroy();
|
||||||
clearTracks();
|
setCurrentTrackId(null);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentTrack = getCurrentTrack();
|
if (currentTrackId && currentTrackId !== track.id) {
|
||||||
if (currentTrack && currentTrack.trackId !== track.id) {
|
setCurrentPosition(0);
|
||||||
setPaused(true);
|
setPaused(true);
|
||||||
}
|
}
|
||||||
}, [tracks]);
|
}, [currentTrackId]);
|
||||||
|
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
// setCurrentTime(position);
|
if (currentTrackId === track.id && !isSliding) {
|
||||||
// }, [position]);
|
setCurrentPosition(position);
|
||||||
|
}
|
||||||
|
}, [position]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
playPause();
|
playPause();
|
||||||
|
@ -161,7 +175,7 @@ IMessageAudioProps) => {
|
||||||
} else {
|
} else {
|
||||||
activateKeepAwake();
|
activateKeepAwake();
|
||||||
}
|
}
|
||||||
}, [paused, currentTime, duration, file, loading, theme]);
|
}, [paused, currentPosition, duration, file, loading, theme]);
|
||||||
|
|
||||||
useTrackPlayerEvents([Event.PlaybackState], ({ state }) => {
|
useTrackPlayerEvents([Event.PlaybackState], ({ state }) => {
|
||||||
if (state === State.Stopped) {
|
if (state === State.Stopped) {
|
||||||
|
@ -172,51 +186,72 @@ IMessageAudioProps) => {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (state === State.Paused) {
|
||||||
|
setPaused(true);
|
||||||
|
}
|
||||||
|
if (state === State.Playing && currentTrackId?.trackId === track.id) {
|
||||||
|
setPaused(false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const getDuration = () => formatTime(currentTime || duration);
|
const getDuration = () => formatTime(currentPosition || duration);
|
||||||
|
|
||||||
const togglePlayPause = () => {
|
const togglePlayPause = () => {
|
||||||
setPaused(!paused);
|
setPaused(!paused);
|
||||||
};
|
};
|
||||||
|
|
||||||
const playPause = () => {
|
const playPause = async () => {
|
||||||
const currentPlaying = getCurrentTrack();
|
|
||||||
try {
|
try {
|
||||||
if (paused) {
|
if (paused) {
|
||||||
if (currentPlaying?.trackId === track.id) {
|
if (currentTrackId === track.id) {
|
||||||
TrackPlayer.pause();
|
TrackPlayer.pause();
|
||||||
}
|
}
|
||||||
} else if (currentPlaying?.trackId === track.id) {
|
} else if (currentTrackId === track.id) {
|
||||||
TrackPlayer.play();
|
TrackPlayer.play();
|
||||||
} else {
|
} else {
|
||||||
TrackPlayer.reset();
|
TrackPlayer.reset();
|
||||||
TrackPlayer.add(track);
|
await TrackPlayer.add(track);
|
||||||
TrackPlayer.play();
|
TrackPlayer.play();
|
||||||
setCurrentTrack(track.id);
|
setCurrentTrackId(track.id);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onValueChange = async (value: number) => {
|
const onValueChange = (value: number) => {
|
||||||
const currentTrack = getCurrentTrack();
|
setCurrentPosition(value);
|
||||||
try {
|
try {
|
||||||
setCurrentTime(value);
|
if (currentTrackId === track.id && !paused && isSliding) {
|
||||||
if (currentTrack && currentTrack.trackId === track.id) {
|
setPaused(true);
|
||||||
await TrackPlayer.seekTo(value);
|
TrackPlayer.pause();
|
||||||
} else {
|
|
||||||
TrackPlayer.reset();
|
|
||||||
TrackPlayer.add(track);
|
|
||||||
TrackPlayer.seekTo(value);
|
|
||||||
setCurrentTrack(track.id);
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onSlidingEnd = async (value: number) => {
|
||||||
|
setCurrentPosition(value);
|
||||||
|
try {
|
||||||
|
if (currentTrackId === track.id) {
|
||||||
|
await TrackPlayer.seekTo(value);
|
||||||
|
} else {
|
||||||
|
TrackPlayer.reset();
|
||||||
|
await TrackPlayer.add(track);
|
||||||
|
await TrackPlayer.seekTo(value);
|
||||||
|
setCurrentTrackId(track.id);
|
||||||
|
}
|
||||||
|
if (paused) {
|
||||||
|
TrackPlayer.play();
|
||||||
|
setPaused(false);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
setIsSliding(false);
|
||||||
|
};
|
||||||
|
|
||||||
const { description } = file;
|
const { description } = file;
|
||||||
|
|
||||||
if (!baseUrl) {
|
if (!baseUrl) {
|
||||||
|
@ -252,7 +287,7 @@ IMessageAudioProps) => {
|
||||||
]}>
|
]}>
|
||||||
<Button disabled={isReply} loading={loading} paused={paused} onPress={togglePlayPause} theme={theme} />
|
<Button disabled={isReply} loading={loading} paused={paused} onPress={togglePlayPause} theme={theme} />
|
||||||
<Slider
|
<Slider
|
||||||
value={currentTime}
|
value={currentPosition}
|
||||||
maximumValue={duration}
|
maximumValue={duration}
|
||||||
onValueChange={onValueChange}
|
onValueChange={onValueChange}
|
||||||
thumbTintColor={thumbColor}
|
thumbTintColor={thumbColor}
|
||||||
|
@ -260,20 +295,10 @@ IMessageAudioProps) => {
|
||||||
disabled={isReply}
|
disabled={isReply}
|
||||||
maximumTrackTintColor={themes[theme].auxiliaryText}
|
maximumTrackTintColor={themes[theme].auxiliaryText}
|
||||||
animationConfig={sliderAnimatedConfig}
|
animationConfig={sliderAnimatedConfig}
|
||||||
|
onSlidingStart={() => setIsSliding(true)}
|
||||||
|
onSlidingEnd={onSlidingEnd}
|
||||||
// thumbImage={isIOS ? { uri: 'audio_thumb', scale } : undefined}
|
// thumbImage={isIOS ? { uri: 'audio_thumb', scale } : undefined}
|
||||||
/>
|
/>
|
||||||
{/* <Slider
|
|
||||||
disabled={isReply}
|
|
||||||
style={styles.slider}
|
|
||||||
value={position}
|
|
||||||
maximumValue={duration}
|
|
||||||
minimumValue={0}
|
|
||||||
thumbTintColor={thumbColor}
|
|
||||||
minimumTrackTintColor={themes[theme].tintColor}
|
|
||||||
maximumTrackTintColor={themes[theme].auxiliaryText}
|
|
||||||
onValueChange={onValueChange}
|
|
||||||
thumbImage={isIOS ? { uri: 'audio_thumb', scale } : undefined}
|
|
||||||
/> */}
|
|
||||||
<Text style={[styles.duration, { color: themes[theme].auxiliaryText }]}>{getDuration()}</Text>
|
<Text style={[styles.duration, { color: themes[theme].auxiliaryText }]}>{getDuration()}</Text>
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import TrackPlayer, { Event, State, Capability } from 'react-native-track-player';
|
import TrackPlayer, { Event, State, Capability } from 'react-native-track-player';
|
||||||
// import type { ProgressUpdateEvent } from 'react-native-track-player';
|
|
||||||
|
import { clearCurrentTrack } from './tracksStorage';
|
||||||
|
|
||||||
let wasPausedByDuck = false;
|
let wasPausedByDuck = false;
|
||||||
|
|
||||||
|
@ -14,6 +15,11 @@ export const playbackService = async () => {
|
||||||
TrackPlayer.play();
|
TrackPlayer.play();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TrackPlayer.addEventListener(Event.RemoteStop, () => {
|
||||||
|
clearCurrentTrack();
|
||||||
|
TrackPlayer.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
TrackPlayer.addEventListener(Event.RemoteDuck, async e => {
|
TrackPlayer.addEventListener(Event.RemoteDuck, async e => {
|
||||||
if (e.permanent === true) {
|
if (e.permanent === true) {
|
||||||
TrackPlayer.stop();
|
TrackPlayer.stop();
|
||||||
|
@ -26,47 +32,13 @@ export const playbackService = async () => {
|
||||||
wasPausedByDuck = false;
|
wasPausedByDuck = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TrackPlayer.addEventListener(Event.PlaybackQueueEnded, data => {
|
|
||||||
// console.log('Event.PlaybackQueueEnded', data);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// TrackPlayer.addEventListener(Event.PlaybackTrackChanged, data => {
|
|
||||||
// console.log('Event.PlaybackTrackChanged', data);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// TrackPlayer.addEventListener(Event.PlaybackProgressUpdated, (data: ProgressUpdateEvent) => {
|
|
||||||
// console.log('Event.PlaybackProgressUpdated', data);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// TrackPlayer.addEventListener(Event.RemoteNext, () => {
|
|
||||||
// TrackPlayer.skipToNext();
|
|
||||||
// });
|
|
||||||
|
|
||||||
// TrackPlayer.addEventListener(Event.RemotePrevious, () => {
|
|
||||||
// TrackPlayer.skipToPrevious();
|
|
||||||
// });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setupService = async () => {
|
export const setupService = async () => {
|
||||||
try {
|
|
||||||
await TrackPlayer.getCurrentTrack();
|
|
||||||
} catch {
|
|
||||||
await TrackPlayer.setupPlayer();
|
await TrackPlayer.setupPlayer();
|
||||||
await TrackPlayer.updateOptions({
|
await TrackPlayer.updateOptions({
|
||||||
stopWithApp: false,
|
stopWithApp: false,
|
||||||
capabilities: [
|
capabilities: [Capability.Play, Capability.Pause, Capability.Stop],
|
||||||
Capability.Play,
|
compactCapabilities: [Capability.Play, Capability.Pause]
|
||||||
Capability.Pause,
|
|
||||||
Capability.Stop
|
|
||||||
// Capability.SkipToNext,
|
|
||||||
// Capability.SkipToPrevious
|
|
||||||
],
|
|
||||||
compactCapabilities: [
|
|
||||||
Capability.Play,
|
|
||||||
Capability.Pause
|
|
||||||
// Capability.SkipToNext
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
import MMKVStorage from 'react-native-mmkv-storage';
|
|
||||||
|
|
||||||
export const TracksStorage = new MMKVStorage.Loader().withInstanceID('tracks').initialize();
|
|
||||||
|
|
||||||
interface Track {
|
|
||||||
trackId: string;
|
|
||||||
isPlaying: boolean;
|
|
||||||
title?: string;
|
|
||||||
artist?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const initializeTracks = () => {
|
|
||||||
const tracks = TracksStorage.getArray('tracks');
|
|
||||||
if (!tracks) TracksStorage.setArray('tracks', []);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const addTrack = (track: Track) => {
|
|
||||||
initializeTracks();
|
|
||||||
const tracks: Track[] = TracksStorage.getArray('tracks') || [];
|
|
||||||
if (tracks.find((t: Track) => t.trackId === track.trackId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TracksStorage.setArray('tracks', [...tracks, track]);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getTrack = (track: Track) => {
|
|
||||||
const tracks: Track[] = TracksStorage.getArray('tracks') || [];
|
|
||||||
return tracks.find((t: Track) => t.trackId === track.trackId);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const updateTrack = (track: Track) => {
|
|
||||||
const tracks: Track[] = TracksStorage.getArray('tracks') || [];
|
|
||||||
const index = tracks.findIndex((t: Track) => t.trackId === track.trackId);
|
|
||||||
if (index !== -1) {
|
|
||||||
tracks[index] = track;
|
|
||||||
}
|
|
||||||
TracksStorage.setArray('tracks', tracks);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const clearTracks = () => {
|
|
||||||
TracksStorage.setArray('tracks', []);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getCurrentTrack: () => Track | undefined = () => {
|
|
||||||
const tracks: Track[] = TracksStorage.getArray('tracks') || [];
|
|
||||||
const currentTrack = tracks.find((t: Track) => t.isPlaying);
|
|
||||||
return currentTrack;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setCurrentTrack = (trackId: string) => {
|
|
||||||
const tracks: Track[] = TracksStorage.getArray('tracks') || [];
|
|
||||||
const currentTrack = tracks.find((t: Track) => t.isPlaying);
|
|
||||||
const trackToToggle = tracks.find((t: Track) => t.trackId === trackId);
|
|
||||||
currentTrack && updateTrack({ ...currentTrack, isPlaying: false });
|
|
||||||
if (trackToToggle) {
|
|
||||||
updateTrack({ ...trackToToggle, isPlaying: true });
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import MMKVStorage, { create } from 'react-native-mmkv-storage';
|
||||||
|
|
||||||
|
const TracksStorage = new MMKVStorage.Loader().withInstanceID('tracks').initialize();
|
||||||
|
|
||||||
|
export const useTracks = create(TracksStorage);
|
||||||
|
|
||||||
|
export const clearCurrentTrack = () => {
|
||||||
|
TracksStorage.removeItem('currentTrack');
|
||||||
|
};
|
|
@ -8,6 +8,21 @@ jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock
|
||||||
|
|
||||||
jest.mock('@react-native-clipboard/clipboard', () => mockClipboard);
|
jest.mock('@react-native-clipboard/clipboard', () => mockClipboard);
|
||||||
|
|
||||||
|
jest.mock('react-native-mmkv-storage', () => ({
|
||||||
|
Loader: jest.fn().mockImplementation(() => ({
|
||||||
|
setProcessingMode: jest.fn().mockImplementation(() => ({
|
||||||
|
withEncryption: jest.fn().mockImplementation(() => ({
|
||||||
|
initialize: jest.fn()
|
||||||
|
}))
|
||||||
|
})),
|
||||||
|
withInstanceID: jest.fn().mockImplementation(() => ({
|
||||||
|
initialize: jest.fn()
|
||||||
|
}))
|
||||||
|
})),
|
||||||
|
create: jest.fn(),
|
||||||
|
MODES: { MULTI_PROCESS: '' }
|
||||||
|
}));
|
||||||
|
|
||||||
jest.mock('rn-fetch-blob', () => ({
|
jest.mock('rn-fetch-blob', () => ({
|
||||||
fs: {
|
fs: {
|
||||||
dirs: {
|
dirs: {
|
||||||
|
@ -67,3 +82,47 @@ jest.mock('react-native-math-view', () => {
|
||||||
MathText: react.View // {...} Named export
|
MathText: react.View // {...} Named export
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
jest.mock('react-native-track-player', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: {
|
||||||
|
addEventListener: () => ({
|
||||||
|
remove: jest.fn()
|
||||||
|
}),
|
||||||
|
registerEventHandler: jest.fn(),
|
||||||
|
registerPlaybackService: jest.fn(),
|
||||||
|
setupPlayer: jest.fn(),
|
||||||
|
destroy: jest.fn(),
|
||||||
|
updateOptions: jest.fn(),
|
||||||
|
reset: jest.fn(),
|
||||||
|
add: jest.fn(),
|
||||||
|
remove: jest.fn(),
|
||||||
|
skip: jest.fn(),
|
||||||
|
skipToNext: jest.fn(),
|
||||||
|
skipToPrevious: jest.fn(),
|
||||||
|
removeUpcomingTracks: jest.fn(),
|
||||||
|
play: jest.fn(),
|
||||||
|
pause: jest.fn(),
|
||||||
|
stop: jest.fn(),
|
||||||
|
seekTo: jest.fn(),
|
||||||
|
setVolume: jest.fn(),
|
||||||
|
setRate: jest.fn(),
|
||||||
|
getQueue: jest.fn(),
|
||||||
|
getTrack: jest.fn(),
|
||||||
|
getCurrentTrack: jest.fn(),
|
||||||
|
getVolume: jest.fn(),
|
||||||
|
getDuration: jest.fn(),
|
||||||
|
getPosition: jest.fn(),
|
||||||
|
getBufferedPosition: jest.fn(),
|
||||||
|
getState: jest.fn(),
|
||||||
|
getRate: jest.fn()
|
||||||
|
},
|
||||||
|
useProgress: () => ({
|
||||||
|
position: 100
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('./app/containers/message/Components/Audio/tracksStorage.ts', () => ({
|
||||||
|
useTracks: () => ({
|
||||||
|
currentTrack: ''
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
Loading…
Reference in New Issue