diff --git a/example/src/App.tsx b/example/src/App.tsx index 2369424..fb85122 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -18,6 +18,7 @@ import React, { } from 'react'; import { ActivityIndicator, + Alert, Image, Linking, Pressable, @@ -35,11 +36,13 @@ import { Icons } from './assets'; import { generateAudioList, playbackSpeedSequence, + getRecordedAudios, type ListItem, } from './constants'; import stylesheet from './styles'; import { Colors } from './theme'; import FastImage from 'react-native-fast-image'; +import fs from 'react-native-fs'; const RenderListItem = React.memo( ({ @@ -224,6 +227,7 @@ const AppContainer = () => { const [shouldScroll, setShouldScroll] = useState(true); const [currentPlaying, setCurrentPlaying] = useState(''); const [list, setList] = useState([]); + const [nbOfRecording, setNumberOfRecording] = useState(0); const [currentPlaybackSpeed, setCurrentPlaybackSpeed] = useState(1.0); @@ -238,6 +242,12 @@ const AppContainer = () => { }); }, []); + useEffect(() => { + getRecordedAudios().then(recordedAudios => + setNumberOfRecording(recordedAudios.length) + ); + }, [list]); + const changeSpeed = () => { setCurrentPlaybackSpeed( prev => @@ -248,6 +258,35 @@ const AppContainer = () => { ); }; + const handleDeleteRecordings = async () => { + const recordings = await getRecordedAudios(); + + const deleteRecordings = async () => { + await Promise.all(recordings.map(async recording => fs.unlink(recording))) + .then(() => { + generateAudioList().then(audioListArray => { + setList(audioListArray); + }); + }) + .catch(error => { + Alert.alert( + 'Error deleting recordings', + 'Below error happened while deleting recordings:\n' + error, + [{ text: 'Dismiss' }] + ); + }); + }; + + Alert.alert( + 'Delete all recording', + `Continue to delete all ${recordings.length} recordings.`, + [ + { text: 'Cancel', style: 'cancel' }, + { text: 'OK', onPress: deleteRecordings }, + ] + ); + }; + return ( { - + + + + + {'Delete recorded audio files'} + + {list.map(item => ( diff --git a/example/src/assets/icons/delete.png b/example/src/assets/icons/delete.png new file mode 100644 index 0000000..68a0eb2 Binary files /dev/null and b/example/src/assets/icons/delete.png differ diff --git a/example/src/assets/icons/index.ts b/example/src/assets/icons/index.ts index c28aa2c..996a449 100644 --- a/example/src/assets/icons/index.ts +++ b/example/src/assets/icons/index.ts @@ -4,4 +4,5 @@ export const Icons = { simform: require('./simform.png'), mic: require('./mic.png'), logo: require('./logo.png'), + delete: require('./delete.png'), }; diff --git a/example/src/constants/Audios.ts b/example/src/constants/Audios.ts index 4ae6b64..daee5be 100644 --- a/example/src/constants/Audios.ts +++ b/example/src/constants/Audios.ts @@ -1,6 +1,7 @@ import fs from 'react-native-fs'; import RNFetchBlob from 'rn-fetch-blob'; import { globalMetrics } from '../../src/theme'; +import { Platform } from 'react-native'; export interface ListItem { fromCurrentUser: boolean; @@ -69,17 +70,30 @@ const audioAssetArray = [ 'file_example_mp3_15s.mp3', ]; +/** + * Retrieve previously recorded audio files from the cache/document directory. + * @returns + */ +export const getRecordedAudios = async (): Promise => { + const recordingSavingPath = Platform.select({ ios: fs.DocumentDirectoryPath, default: fs.CachesDirectoryPath }) + + const items = await fs.readDir(recordingSavingPath) + return items.filter(item => item.path.endsWith('.m4a')).map(item => item.path) +} + /** * Generate a list of file objects with information about successfully copied files (Android) * or all files (iOS). * @returns {Promise} A Promise that resolves to the list of file objects. */ export const generateAudioList = async (): Promise => { - const audioAssets = await copyFilesToNativeResources(); + const audioAssetPaths = (await copyFilesToNativeResources()).map(value => `${filePath}/${value}`); + const recordedAudios = await getRecordedAudios() // Generate the final list based on the copied or available files - return audioAssets?.map?.((value, index) => ({ + return [...audioAssetPaths, ...recordedAudios].map?.((value, index) => ({ fromCurrentUser: index % 2 !== 0, - path: `${filePath}/${value}`, + path: value, })); + }; diff --git a/example/src/styles.ts b/example/src/styles.ts index 088fbfc..8cb9eb3 100644 --- a/example/src/styles.ts +++ b/example/src/styles.ts @@ -54,6 +54,12 @@ const styles = (params: StyleSheetParams = {}) => tintColor: Colors.white, alignSelf: 'flex-end', }, + pinkButtonImage: { + height: scale(22), + width: scale(22), + tintColor: Colors.pink, + alignSelf: 'flex-end', + }, staticWaveformView: { flex: 1, height: scale(75), @@ -90,9 +96,18 @@ const styles = (params: StyleSheetParams = {}) => width: '100%', tintColor: Colors.pink, }, - simformImageContainer: { + headerContainer: { alignItems: 'center', - justifyContent: 'center', + }, + deleteRecordingContainer: { + alignItems: 'center', + flexDirection: 'row', + }, + deleteRecordingTitle: { + fontSize: scale(20), + fontWeight: 'bold', + color: Colors.pink, + paddingLeft: scale(8), }, loadingText: { color: Colors.black,