NuvioStreaming/src/screens/PlayerSettingsScreen.tsx
tapframe d126d0ec40 Refactor PlayerSettingsScreen to integrate ThemeContext for dynamic theming
This update modifies the PlayerSettingsScreen component to utilize the ThemeContext, allowing for dynamic theming throughout the settings interface. Styles have been adjusted to reflect the current theme colors, enhancing visual consistency and user experience. Key changes include the removal of the isDarkMode prop, updates to text colors, and background settings, ensuring a cohesive interface that adapts to different themes.
2025-05-04 02:46:35 +05:30

310 lines
No EOL
7.1 KiB
TypeScript

import React from 'react';
import {
View,
Text,
StyleSheet,
ScrollView,
SafeAreaView,
Platform,
TouchableOpacity,
StatusBar,
} from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { useSettings, AppSettings } from '../hooks/useSettings';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { useTheme } from '../contexts/ThemeContext';
const ANDROID_STATUSBAR_HEIGHT = StatusBar.currentHeight || 0;
interface SettingItemProps {
title: string;
description?: string;
icon: string;
isSelected: boolean;
onPress: () => void;
isLast?: boolean;
}
const SettingItem: React.FC<SettingItemProps> = ({
title,
description,
icon,
isSelected,
onPress,
isLast,
}) => {
const { currentTheme } = useTheme();
return (
<TouchableOpacity
onPress={onPress}
activeOpacity={0.7}
style={[
styles.settingItem,
!isLast && styles.settingItemBorder,
{ borderBottomColor: 'rgba(255,255,255,0.08)' },
]}
>
<View style={styles.settingContent}>
<View style={[
styles.settingIconContainer,
{ backgroundColor: 'rgba(255,255,255,0.1)' }
]}>
<MaterialIcons
name={icon}
size={20}
color={currentTheme.colors.primary}
/>
</View>
<View style={styles.settingText}>
<Text
style={[
styles.settingTitle,
{ color: currentTheme.colors.text },
]}
>
{title}
</Text>
{description && (
<Text
style={[
styles.settingDescription,
{ color: currentTheme.colors.textMuted },
]}
>
{description}
</Text>
)}
</View>
{isSelected && (
<MaterialIcons
name="check"
size={24}
color={currentTheme.colors.primary}
style={styles.checkIcon}
/>
)}
</View>
</TouchableOpacity>
);
};
const PlayerSettingsScreen: React.FC = () => {
const { settings, updateSetting } = useSettings();
const { currentTheme } = useTheme();
const navigation = useNavigation();
const playerOptions = [
{
id: 'internal',
title: 'Built-in Player',
description: 'Use the app\'s default video player',
icon: 'play-circle-outline',
},
...(Platform.OS === 'ios' ? [
{
id: 'vlc',
title: 'VLC',
description: 'Open streams in VLC media player',
icon: 'video-library',
},
{
id: 'infuse',
title: 'Infuse',
description: 'Open streams in Infuse player',
icon: 'smart-display',
},
{
id: 'outplayer',
title: 'OutPlayer',
description: 'Open streams in OutPlayer',
icon: 'slideshow',
},
{
id: 'vidhub',
title: 'VidHub',
description: 'Open streams in VidHub player',
icon: 'ondemand-video',
},
] : [
{
id: 'external',
title: 'External Player',
description: 'Open streams in your preferred video player',
icon: 'open-in-new',
},
]),
];
const handleBack = () => {
navigation.goBack();
};
return (
<SafeAreaView
style={[
styles.container,
{ backgroundColor: currentTheme.colors.darkBackground },
]}
>
<StatusBar
translucent
backgroundColor="transparent"
barStyle="light-content"
/>
<View style={styles.header}>
<TouchableOpacity
onPress={handleBack}
style={styles.backButton}
activeOpacity={0.7}
>
<MaterialIcons
name="arrow-back"
size={24}
color={currentTheme.colors.text}
/>
</TouchableOpacity>
<Text
style={[
styles.headerTitle,
{ color: currentTheme.colors.text },
]}
>
Video Player
</Text>
</View>
<ScrollView
style={styles.scrollView}
contentContainerStyle={styles.scrollContent}
>
<View style={styles.section}>
<Text
style={[
styles.sectionTitle,
{ color: currentTheme.colors.textMuted },
]}
>
PLAYER SELECTION
</Text>
<View
style={[
styles.card,
{
backgroundColor: currentTheme.colors.elevation2,
},
]}
>
{playerOptions.map((option, index) => (
<SettingItem
key={option.id}
title={option.title}
description={option.description}
icon={option.icon}
isSelected={
Platform.OS === 'ios'
? settings.preferredPlayer === option.id
: settings.useExternalPlayer === (option.id === 'external')
}
onPress={() => {
if (Platform.OS === 'ios') {
updateSetting('preferredPlayer', option.id as AppSettings['preferredPlayer'], false);
} else {
updateSetting('useExternalPlayer', option.id === 'external', false);
}
}}
isLast={index === playerOptions.length - 1}
/>
))}
</View>
</View>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
header: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 16,
paddingTop: Platform.OS === 'android' ? ANDROID_STATUSBAR_HEIGHT + 16 : 16,
paddingBottom: 8,
},
backButton: {
padding: 8,
marginRight: 16,
borderRadius: 20,
},
headerTitle: {
fontSize: 20,
fontWeight: '600',
},
scrollView: {
flex: 1,
},
scrollContent: {
paddingBottom: 24,
},
section: {
paddingHorizontal: 16,
paddingTop: 24,
},
sectionTitle: {
fontSize: 13,
fontWeight: '600',
marginBottom: 8,
paddingHorizontal: 4,
letterSpacing: 0.5,
},
card: {
borderRadius: 12,
overflow: 'hidden',
marginBottom: 24,
shadowColor: 'rgba(0,0,0,0.1)',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 4,
elevation: 3,
},
settingItem: {
paddingVertical: 16,
paddingHorizontal: 16,
},
settingItemBorder: {
borderBottomWidth: 1,
},
settingContent: {
flexDirection: 'row',
alignItems: 'center',
},
settingIconContainer: {
width: 36,
height: 36,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
marginRight: 16,
},
settingText: {
flex: 1,
},
settingTitle: {
fontSize: 16,
fontWeight: '500',
marginBottom: 2,
},
settingDescription: {
fontSize: 14,
marginTop: 2,
},
checkIcon: {
marginLeft: 16,
},
});
export default PlayerSettingsScreen;