import React, { useState, useEffect } from 'react'; import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView, Animated, Dimensions } from 'react-native'; import { Audio } from 'expo-av'; import { LinearGradient } from 'expo-linear-gradient'; import { Ionicons, FontAwesome5, MaterialIcons } from '@expo/vector-icons'; // Mock radio stream URL (in a real app, this would be a real streaming URL) const RADIO_STREAM_URL = "https://stream.dj512.ai/live"; const artists = [ { id: 1, name: "AI SZA", image: "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=200&h=200&auto=format&fit=crop" }, { id: 2, name: "AI Ed Sheeran", image: "https://images.unsplash.com/photo-1511671782779-c97d3d27a1d4?q=80&w=200&h=200&auto=format&fit=crop" }, { id: 3, name: "AI Nicki Minaj", image: "https://images.unsplash.com/photo-1618005198919-d3d4b5a92ead?q=80&w=200&h=200&auto=format&fit=crop" }, { id: 4, name: "AI Ice Spice", image: "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=200&h=200&auto=format&fit=crop" }, { id: 5, name: "AI Drake", image: "https://images.unsplash.com/photo-1493225457124-a3eb161ffa5f?q=80&w=200&h=200&auto=format&fit=crop" }, { id: 6, name: "AI Beyoncé", image: "https://images.unsplash.com/photo-1618005198919-d3d4b5a92ead?q=80&w=200&h=200&auto=format&fit=crop" }, ]; const currentlyPlaying = [ { type: "SONG", artist: "AI SZA", title: "Digital Love", duration: "3:42" }, { type: "AD", title: "TechFuture AI Assistants", duration: "0:30" }, { type: "NEWS", title: "AI Music Industry Update", duration: "2:15" }, { type: "SONG", artist: "AI Ed Sheeran", title: "Algorithm Heart", duration: "4:12" }, { type: "HOST", name: "DJ Neural", segment: "Evening Mix", duration: "1:45" }, ]; export default function App() { const [sound, setSound] = useState(); const [isPlaying, setIsPlaying] = useState(false); const [volume, setVolume] = useState(0.5); const [currentTrackIndex, setCurrentTrackIndex] = useState(0); const [animation] = useState(new Animated.Value(0)); // Animated bars for visualizer const bars = Array(12).fill(0).map(() => new Animated.Value(0)); // Start the audio stream async function playSound() { console.log('Loading Sound'); try { // In a real app, you would use the actual stream URL const { sound } = await Audio.Sound.createAsync( { uri: RADIO_STREAM_URL }, { shouldPlay: true, volume: volume } ); setSound(sound); setIsPlaying(true); // For demo purposes, we'll just animate the visualizer startVisualizer(); } catch (error) { console.error('Error loading sound', error); // Fallback for demo - pretend it's playing setIsPlaying(true); startVisualizer(); } } // Stop the audio stream async function stopSound() { if (sound) { await sound.stopAsync(); setIsPlaying(false); stopVisualizer(); } else { // For demo setIsPlaying(false); stopVisualizer(); } } // Toggle play/pause function togglePlayback() { if (isPlaying) { stopSound(); } else { playSound(); } } // Adjust volume function adjustVolume(newVolume) { setVolume(newVolume); if (sound) { sound.setVolumeAsync(newVolume); } } // Animate the visualizer bars function startVisualizer() { // Cycle through tracks for demo purposes const interval = setInterval(() => { setCurrentTrackIndex(prev => (prev + 1) % currentlyPlaying.length); }, 15000); // Animate each bar with random heights bars.forEach((bar, i) => { animateBar(bar, i); }); return () => clearInterval(interval); } function animateBar(bar, index) { const randomHeight = Math.random() * 0.8 + 0.2; // Between 0.2 and 1.0 const duration = 300 + Math.random() * 700; // Random duration Animated.sequence([ Animated.timing(bar, { toValue: randomHeight, duration: duration, useNativeDriver: false, }), Animated.timing(bar, { toValue: 0.2, duration: duration, useNativeDriver: false, }) ]).start(() => { if (isPlaying) { animateBar(bar, index); } }); } function stopVisualizer() { bars.forEach(bar => { Animated.timing(bar).stop(); bar.setValue(0); }); } // Clean up on unmount useEffect(() => { return sound ? () => { console.log('Unloading Sound'); sound.unloadAsync(); } : undefined; }, [sound]); // Start playing automatically on load for demo useEffect(() => { playSound(); return () => stopSound(); }, []); // Get current track info const currentTrack = currentlyPlaying[currentTrackIndex]; return ( {/* Header */} DJ 512 in the mix {/* Player */} {/* Visualizer */} {bars.map((bar, index) => ( ))} {/* Now Playing */} {currentTrack.type === "SONG" ? "NOW PLAYING" : currentTrack.type === "AD" ? "ADVERTISEMENT" : currentTrack.type === "NEWS" ? "NEWS UPDATE" : "HOST SEGMENT"} {currentTrack.type === "SONG" ? currentTrack.title : currentTrack.type === "AD" ? currentTrack.title : currentTrack.type === "NEWS" ? currentTrack.title : `${currentTrack.name} - ${currentTrack.segment}`} {currentTrack.type === "SONG" && ( {currentTrack.artist} )} {currentTrack.duration} {/* On Air Indicator */} ON AIR {/* Controls */} {/* Featured Artists */} Featured AI Artists {artists.map(artist => ( {artist.name} ))} {/* Station Features */} Station Features AI Radio Hosts Our AI DJs keep the energy high 24/7 with personality and flair AI-Generated Music Exclusive tracks from AI versions of your favorite artists AI News Updates Stay informed with the latest news synthesized by our AI anchors {/* Footer */} DJ 512 in the mix • AI-Powered Radio Stream URL: {RADIO_STREAM_URL} ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#121212', }, scrollView: { flex: 1, }, header: { alignItems: 'center', paddingTop: 60, paddingBottom: 20, }, stationName: { fontSize: 42, fontWeight: 'bold', color: '#F72585', textShadowColor: 'rgba(247, 37, 133, 0.6)', textShadowOffset: { width: 0, height: 0 }, textShadowRadius: 10, }, stationTagline: { fontSize: 18, color: '#fff', marginTop: -5, }, playerContainer: { margin: 20, borderRadius: 20, overflow: 'hidden', elevation: 5, shadowColor: '#F72585', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.3, shadowRadius: 10, }, playerGradient: { padding: 20, borderRadius: 20, }, visualizer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-end', height: 40, marginBottom: 20, }, visualizerBar: { width: 6, backgroundColor: '#F72585', borderRadius: 3, marginHorizontal: 2, }, nowPlayingContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20, }, nowPlayingInfo: { flex: 1, }, nowPlayingLabel: { fontSize: 12, color: '#F72585', fontWeight: 'bold', }, trackTitle: { fontSize: 18, fontWeight: 'bold', color: '#fff', marginTop: 5, }, artistName: { fontSize: 16, color: '#ccc', marginTop: 2, }, duration: { fontSize: 12, color: '#aaa', marginTop: 5, }, onAirContainer: { alignItems: 'center', justifyContent: 'center', }, onAirIndicator: { width: 12, height: 12, borderRadius: 6, backgroundColor: '#444', marginBottom: 5, }, onAirActive: { backgroundColor: '#F72585', shadowColor: '#F72585', shadowOffset: { width: 0, height: 0 }, shadowOpacity: 0.8, shadowRadius: 6, }, onAirText: { fontSize: 10, color: '#fff', fontWeight: 'bold', }, controls: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginTop: 10, }, playButton: { width: 60, height: 60, borderRadius: 30, backgroundColor: 'rgba(255, 255, 255, 0.1)', alignItems: 'center', justifyContent: 'center', borderWidth: 1, borderColor: '#F72585', }, volumeContainer: { flex: 1, flexDirection: 'row', alignItems: 'center', marginLeft: 20, }, volumeSlider: { flex: 1, height: 4, backgroundColor: 'rgba(255, 255, 255, 0.2)', borderRadius: 2, marginHorizontal: 10, }, volumeTrack: { height: 4, backgroundColor: '#F72585', borderRadius: 2, }, featuredSection: { marginTop: 20, paddingHorizontal: 20, }, sectionTitle: { fontSize: 20, fontWeight: 'bold', color: '#fff', marginBottom: 15, }, artistsScroll: { flexDirection: 'row', marginBottom: 20, }, artistCard: { marginRight: 15, alignItems: 'center', width: 120, }, artistImage: { width: 100, height: 100, borderRadius: 50, borderWidth: 2, borderColor: '#F72585', }, artistCardName: { marginTop: 10, color: '#fff', textAlign: 'center', fontSize: 14, }, featuresSection: { marginTop: 10, paddingHorizontal: 20, }, featureCard: { flexDirection: 'row', backgroundColor: 'rgba(67, 97, 238, 0.1)', borderRadius: 10, padding: 15, marginBottom: 15, borderLeftWidth: 3, borderLeftColor: '#F72585', }, featureIcon: { marginRight: 15, }, featureContent: { flex: 1, }, featureTitle: { fontSize: 16, fontWeight: 'bold', color: '#fff', marginBottom: 5, }, featureDescription: { fontSize: 14, color: '#ccc', }, footer: { marginTop: 30, marginBottom: 30, alignItems: 'center', paddingHorizontal: 20, }, footerText: { color: '#aaa', fontSize: 12, marginBottom: 5, textAlign: 'center', }, });