player UI update

This commit is contained in:
tapframe 2025-11-16 15:46:46 +05:30
parent 09e35d5a0c
commit 34f110f16a
2 changed files with 78 additions and 65 deletions

View file

@ -285,8 +285,12 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
tapToSeek={Platform.OS === 'ios'}
/>
<View style={[styles.timeDisplay, { paddingHorizontal: 14 }]}>
<Text style={styles.duration}>{formatTime(currentTime)}</Text>
<Text style={styles.duration}>{formatTime(duration)}</Text>
<View style={styles.timeContainer}>
<Text style={styles.duration}>{formatTime(currentTime)}</Text>
</View>
<View style={styles.timeContainer}>
<Text style={styles.duration}>{formatTime(duration)}</Text>
</View>
</View>
</View>
@ -368,7 +372,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
styles.buttonCircle,
{
opacity: backwardPressAnim,
width: seekButtonSize * 0.6, // 60% of seek button
width: seekButtonSize * 0.6,
height: seekButtonSize * 0.6,
borderRadius: (seekButtonSize * 0.6) / 2,
}
@ -381,7 +385,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
styles.seekNumber,
{
fontSize: seekNumberSize,
marginLeft: 7, // Opposite offset for flipped icon
marginLeft: 7,
transform: [{ translateX: backwardSlideAnim }]
}
]}>
@ -426,9 +430,9 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
styles.playPressCircle,
{
opacity: playPressAnim,
width: playButtonSize * 0.85, // ← 85% of button size
width: playButtonSize * 0.85,
height: playButtonSize * 0.85,
borderRadius: (playButtonSize * 0.85) / 2, // ← Half of width/height for circle
borderRadius: (playButtonSize * 0.85) / 2,
}
]} />
<Animated.View style={{
@ -466,7 +470,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
styles.buttonCircle,
{
opacity: forwardPressAnim,
width: seekButtonSize * 0.6, // 60% of seek button
width: seekButtonSize * 0.6,
height: seekButtonSize * 0.6,
borderRadius: (seekButtonSize * 0.6) / 2,
}
@ -525,81 +529,56 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
style={styles.bottomGradient}
>
<View style={styles.bottomControls}>
{/* Bottom Buttons Row */}
<View style={styles.bottomButtons}>
{/* Aspect Ratio Button - uses official resize modes */}
<TouchableOpacity style={styles.bottomButton} onPress={cycleAspectRatio}>
<Ionicons name="resize" size={20} color="white" />
<Text style={[styles.bottomButtonText, { fontSize: 14, textAlign: 'center' }]}>
{currentResizeMode
? (currentResizeMode === 'none'
? 'Original'
: currentResizeMode.charAt(0).toUpperCase() + currentResizeMode.slice(1))
: 'Contain'}
</Text>
{/* Center Buttons Container with rounded background - wraps all buttons */}
<View style={styles.centerControlsContainer}>
{/* Left Side: Aspect Ratio Button */}
<TouchableOpacity style={styles.iconButton} onPress={cycleAspectRatio}>
<Ionicons name="expand-outline" size={24} color="white" />
</TouchableOpacity>
{/* Playback Speed Button */}
<TouchableOpacity style={styles.bottomButton} onPress={() => setShowSpeedModal(true)}>
<Ionicons name="speedometer" size={20} color="white" />
<Text style={styles.bottomButtonText}>
Speed {currentPlaybackSpeed}x
</Text>
</TouchableOpacity>
{/* Audio Button - Updated to use ksAudioTracks */}
{/* Subtitle Button */}
<TouchableOpacity
style={styles.bottomButton}
onPress={() => setShowAudioModal(true)}
disabled={ksAudioTracks.length <= 1}
>
<Ionicons name="volume-high" size={20} color={ksAudioTracks.length <= 1 ? 'grey' : 'white'} />
<Text style={[styles.bottomButtonText, ksAudioTracks.length <= 1 && {color: 'grey'}]} numberOfLines={1}>
{(() => {
const trackName = getTrackDisplayName(
ksAudioTracks.find(t => t.id === selectedAudioTrack) || { id: -1, name: 'Default' }
);
// Truncate long audio track names to prevent UI cramping
const maxLength = 12; // Limit to 12 characters
return trackName.length > maxLength ? `${trackName.substring(0, maxLength)}...` : trackName;
})()}
</Text>
</TouchableOpacity>
{/* Subtitle Button - Always available for external subtitle search */}
<TouchableOpacity
style={styles.bottomButton}
style={styles.iconButton}
onPress={() => setShowSubtitleModal(!isSubtitleModalOpen)}
>
<Ionicons name="text" size={20} color="white" />
<Text style={styles.bottomButtonText}>
Subtitles
</Text>
<Ionicons name="text" size={24} color="white" />
</TouchableOpacity>
{/* Change Source Button */}
{setShowSourcesModal && (
<TouchableOpacity
style={styles.bottomButton}
style={styles.iconButton}
onPress={() => setShowSourcesModal(true)}
>
<Ionicons name="swap-horizontal" size={20} color="white" />
<Text style={styles.bottomButtonText}>
Change Source
</Text>
<Ionicons name="cloud-outline" size={24} color="white" />
</TouchableOpacity>
)}
{/* Episodes Button */}
{/* Playback Speed Button */}
<TouchableOpacity style={styles.iconButton} onPress={() => setShowSpeedModal(true)}>
<Ionicons name="speedometer-outline" size={24} color="white" />
</TouchableOpacity>
{/* Audio Button */}
<TouchableOpacity
style={styles.iconButton}
onPress={() => setShowAudioModal(true)}
disabled={ksAudioTracks.length <= 1}
>
<Ionicons
name="musical-notes-outline"
size={24}
color={ksAudioTracks.length <= 1 ? 'grey' : 'white'}
/>
</TouchableOpacity>
{/* Right Side: Episodes Button */}
{setShowEpisodesModal && (
<TouchableOpacity
style={styles.bottomButton}
style={styles.iconButton}
onPress={() => setShowEpisodesModal(true)}
>
<Ionicons name="list" size={20} color="white" />
<Text style={styles.bottomButtonText}>
Episodes
</Text>
<Ionicons name="list" size={24} color="white" />
</TouchableOpacity>
)}
</View>

View file

@ -26,7 +26,7 @@ const qualityTextFont = isTV ? 13 : isLargeTablet ? 12 : isTablet ? 11 : 11;
const controlsGap = isTV ? 56 : isLargeTablet ? 48 : isTablet ? 44 : 40;
const controlsTranslateY = isTV ? -48 : isLargeTablet ? -42 : isTablet ? -36 : -30;
const skipTextFont = isTV ? 14 : isLargeTablet ? 13 : isTablet ? 12 : 12;
const sliderBottom = isTV ? 80 : isLargeTablet ? 70 : isTablet ? 65 : 55;
const sliderBottom = isTV ? 60 : isLargeTablet ? 50 : isTablet ? 45 : 35;
const progressTouchHeight = isTV ? 48 : isLargeTablet ? 44 : isTablet ? 40 : 40;
const progressBarHeight = isTV ? 6 : isLargeTablet ? 5 : isTablet ? 5 : 4;
const progressThumbSize = isTV ? 24 : isLargeTablet ? 20 : isTablet ? 18 : 16;
@ -184,7 +184,7 @@ export const styles = StyleSheet.create({
fontWeight: '500',
opacity: 1,
textAlign: 'center',
marginLeft: -7, // Adjusted for better centering with icon
marginLeft: -7,
},
/* CloudStream Style - Play Button */
@ -303,6 +303,14 @@ export const styles = StyleSheet.create({
fontSize: durationFont,
fontWeight: '500',
},
timeContainer: {
paddingHorizontal: 10,
paddingVertical: 4,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
borderRadius: 12,
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.2)',
},
bottomButtons: {
flexDirection: 'row',
justifyContent: 'space-around',
@ -317,6 +325,32 @@ export const styles = StyleSheet.create({
color: 'white',
fontSize: bottomButtonTextFont,
},
bottomIconRow: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
gap: 24,
paddingVertical: 8,
},
iconButton: {
padding: 10,
alignItems: 'center',
justifyContent: 'center',
},
centerControlsContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: 8,
paddingHorizontal: 12,
paddingVertical: 6,
marginTop: 12,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
borderRadius: 24,
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.2)',
alignSelf: 'center',
},
modalOverlay: {
flex: 1,
backgroundColor: 'rgba(0, 0, 0, 0.9)',