diff --git a/apps/native-component-list/src/screens/Audio/AudioPlaylistScreen.tsx b/apps/native-component-list/src/screens/Audio/AudioPlaylistScreen.tsx new file mode 100644 index 00000000000000..ce11068c4b37ee --- /dev/null +++ b/apps/native-component-list/src/screens/Audio/AudioPlaylistScreen.tsx @@ -0,0 +1,328 @@ +import { AudioSource, useAudioPlaylist, useAudioPlaylistStatus } from 'expo-audio'; +import React, { useState } from 'react'; +import { View, Text, StyleSheet, ScrollView, Pressable } from 'react-native'; + +import HeadingText from '../../components/HeadingText'; +import Colors from '../../constants/Colors'; + +const INITIAL_SOURCES: AudioSource[] = [ + require('../../../assets/sounds/polonez.mp3'), + { + uri: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3', + name: 'Song 1', + }, + { + uri: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3', + name: 'Song 2', + }, +]; + +const ADDITIONAL_SOURCES: AudioSource[] = [ + { uri: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-4.mp3', name: 'Song 4' }, + { uri: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-5.mp3', name: 'Song 5' }, +]; + +function getTrackName(uri: string): string { + const filename = uri.split('/').pop()?.split('?')[0] ?? 'Unknown'; + return filename.replace(/\.[^/.]+$/, ''); +} + +function formatTime(seconds: number): string { + if (!isFinite(seconds) || isNaN(seconds)) return '0:00'; + const mins = Math.floor(seconds / 60); + const secs = Math.floor(seconds % 60); + return `${mins}:${secs.toString().padStart(2, '0')}`; +} + +function Button({ + title, + onPress, + disabled, +}: { + title: string; + onPress: () => void; + disabled?: boolean; +}) { + return ( + + {title} + + ); +} + +export default function AudioPlaylistScreen() { + const [addTrackIndex, setAddTrackIndex] = useState(0); + + const playlist = useAudioPlaylist({ + sources: INITIAL_SOURCES, + loop: 'none', + }); + + const status = useAudioPlaylistStatus(playlist); + + const sources = playlist.sources; + const currentSource = sources[status.currentIndex]; + const currentTrackName = currentSource + ? (currentSource.name ?? getTrackName(currentSource.uri ?? '')) + : 'No track'; + + const handleAddTrack = () => { + const sourceToAdd = ADDITIONAL_SOURCES[addTrackIndex % ADDITIONAL_SOURCES.length]; + playlist.add(sourceToAdd); + setAddTrackIndex((prev) => prev + 1); + }; + + const handleClear = () => { + playlist.clear(); + }; + + return ( + + + {currentTrackName} + + Track {status.currentIndex + 1} of {status.trackCount} + + + + + + 0 ? (status.currentTime / status.duration) * 100 : 0}%`, + }, + ]} + /> + + + {formatTime(status.currentTime)} + {formatTime(status.duration)} + + + + +