diff --git a/src/components/player/modals/AudioTrackModal.tsx b/src/components/player/modals/AudioTrackModal.tsx
index d35e4b694..c8ec13f1b 100644
--- a/src/components/player/modals/AudioTrackModal.tsx
+++ b/src/components/player/modals/AudioTrackModal.tsx
@@ -1,6 +1,28 @@
import React from 'react';
-import { View, Text, TouchableOpacity, ScrollView } from 'react-native';
-import { Ionicons } from '@expo/vector-icons';
+import { View, Text, TouchableOpacity, ScrollView, Dimensions } from 'react-native';
+import { Ionicons, MaterialIcons } from '@expo/vector-icons';
+import { BlurView } from 'expo-blur';
+import Animated, {
+ FadeIn,
+ FadeOut,
+ SlideInDown,
+ SlideOutDown,
+ FadeInDown,
+ FadeInUp,
+ Layout,
+ withSpring,
+ withTiming,
+ useAnimatedStyle,
+ useSharedValue,
+ interpolate,
+ Easing,
+ withDelay,
+ withSequence,
+ runOnJS,
+ BounceIn,
+ ZoomIn
+} from 'react-native-reanimated';
+import { LinearGradient } from 'expo-linear-gradient';
import { styles } from '../utils/playerStyles';
import { getTrackDisplayName } from '../utils/playerUtils';
@@ -12,6 +34,53 @@ interface AudioTrackModalProps {
selectAudioTrack: (trackId: number) => void;
}
+const { width, height } = Dimensions.get('window');
+
+const AudioBadge = ({
+ text,
+ color,
+ bgColor,
+ icon,
+ delay = 0
+}: {
+ text: string;
+ color: string;
+ bgColor: string;
+ icon?: string;
+ delay?: number;
+}) => (
+
+ {icon && (
+
+ )}
+
+ {text}
+
+
+);
+
export const AudioTrackModal: React.FC = ({
showAudioModal,
setShowAudioModal,
@@ -19,56 +88,405 @@ export const AudioTrackModal: React.FC = ({
selectedAudioTrack,
selectAudioTrack,
}) => {
+ const modalScale = useSharedValue(0.9);
+ const modalOpacity = useSharedValue(0);
+
+ React.useEffect(() => {
+ if (showAudioModal) {
+ modalScale.value = withSpring(1, {
+ damping: 20,
+ stiffness: 300,
+ mass: 0.8,
+ });
+ modalOpacity.value = withTiming(1, {
+ duration: 200,
+ easing: Easing.out(Easing.quad),
+ });
+ }
+ }, [showAudioModal]);
+
+ const modalStyle = useAnimatedStyle(() => ({
+ transform: [{ scale: modalScale.value }],
+ opacity: modalOpacity.value,
+ }));
+
+ const handleClose = () => {
+ modalScale.value = withTiming(0.9, { duration: 150 });
+ modalOpacity.value = withTiming(0, { duration: 150 });
+ setTimeout(() => setShowAudioModal(false), 150);
+ };
+
if (!showAudioModal) return null;
return (
-
-
-
- Audio
- setShowAudioModal(false)}
+
+ {/* Backdrop */}
+
+
+ {/* Modal Content */}
+
+ {/* Glassmorphism Background */}
+
+ {/* Header */}
+
-
-
-
-
-
-
- {vlcAudioTracks.length > 0 ? vlcAudioTracks.map(track => (
- {
- selectAudioTrack(track.id);
- setShowAudioModal(false);
+
+
+ Audio Tracks
+
+
+ Choose from {vlcAudioTracks.length} available track{vlcAudioTracks.length !== 1 ? 's' : ''}
+
+
+
+
+
-
-
- {getTrackDisplayName(track)}
-
- {(track.name && track.language) && (
- {track.name}
- )}
-
- {selectedAudioTrack === track.id && (
-
-
-
- )}
+
- )) : (
-
-
- No audio tracks available
+
+
+
+ {/* Content */}
+
+ {/* Audio Tracks Section */}
+
+
+
+
+
+ Available Audio Tracks
+
+
+ Select your preferred audio language
+
+
- )}
-
-
-
-
+
+ {/* Audio Tracks List */}
+ {vlcAudioTracks.length > 0 ? vlcAudioTracks.map((track, index) => {
+ const isSelected = selectedAudioTrack === track.id;
+
+ return (
+
+ {
+ selectAudioTrack(track.id);
+ handleClose();
+ }}
+ activeOpacity={0.85}
+ >
+
+
+
+
+ {getTrackDisplayName(track)}
+
+
+ {isSelected && (
+
+
+
+ ACTIVE
+
+
+ )}
+
+
+ {(track.name && track.language) && (
+
+ {track.name}
+
+ )}
+
+
+
+ {track.language && (
+
+ )}
+
+
+
+
+ {isSelected ? (
+
+
+
+ ) : (
+
+ )}
+
+
+
+
+ );
+ }) : (
+
+
+
+ No audio tracks available
+
+
+ This content doesn't have multiple audio tracks.{'\n'}The default audio will be used.
+
+
+ )}
+
+
+
+
+
);
};