mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-03-11 17:45:38 +00:00
Introduce a new setting for logo source preference in the SettingsScreen, allowing users to choose between 'metahub' and 'tmdb' as the primary source for title logos. Update the MetadataScreen to utilize this preference, implementing logic to refresh logos based on the selected source. Enhance error handling and logging during logo fetching to improve user experience and debugging capabilities.
678 lines
No EOL
22 KiB
TypeScript
678 lines
No EOL
22 KiB
TypeScript
import React, { useCallback, useState, useEffect } from 'react';
|
|
import {
|
|
View,
|
|
Text,
|
|
StyleSheet,
|
|
TouchableOpacity,
|
|
Switch,
|
|
ScrollView,
|
|
useColorScheme,
|
|
SafeAreaView,
|
|
StatusBar,
|
|
Alert,
|
|
Platform,
|
|
Dimensions,
|
|
Image
|
|
} from 'react-native';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import { useNavigation } from '@react-navigation/native';
|
|
import { NavigationProp } from '@react-navigation/native';
|
|
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
|
|
import { Picker } from '@react-native-picker/picker';
|
|
import { colors } from '../styles/colors';
|
|
import { useSettings, DEFAULT_SETTINGS } from '../hooks/useSettings';
|
|
import { RootStackParamList } from '../navigation/AppNavigator';
|
|
import { stremioService } from '../services/stremioService';
|
|
import { useCatalogContext } from '../contexts/CatalogContext';
|
|
import { useTraktContext } from '../contexts/TraktContext';
|
|
import { catalogService, DataSource } from '../services/catalogService';
|
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
|
const { width } = Dimensions.get('window');
|
|
|
|
const ANDROID_STATUSBAR_HEIGHT = StatusBar.currentHeight || 0;
|
|
|
|
// Card component with modern style
|
|
interface SettingsCardProps {
|
|
children: React.ReactNode;
|
|
isDarkMode: boolean;
|
|
title?: string;
|
|
}
|
|
|
|
const SettingsCard: React.FC<SettingsCardProps> = ({ children, isDarkMode, title }) => (
|
|
<View style={[styles.cardContainer]}>
|
|
{title && (
|
|
<Text style={[
|
|
styles.cardTitle,
|
|
{ color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }
|
|
]}>
|
|
{title.toUpperCase()}
|
|
</Text>
|
|
)}
|
|
<View style={[
|
|
styles.card,
|
|
{ backgroundColor: isDarkMode ? colors.elevation2 : colors.white }
|
|
]}>
|
|
{children}
|
|
</View>
|
|
</View>
|
|
);
|
|
|
|
interface SettingItemProps {
|
|
title: string;
|
|
description?: string;
|
|
icon: string;
|
|
renderControl: () => React.ReactNode;
|
|
isLast?: boolean;
|
|
onPress?: () => void;
|
|
isDarkMode: boolean;
|
|
badge?: string | number;
|
|
}
|
|
|
|
const SettingItem: React.FC<SettingItemProps> = ({
|
|
title,
|
|
description,
|
|
icon,
|
|
renderControl,
|
|
isLast = false,
|
|
onPress,
|
|
isDarkMode,
|
|
badge
|
|
}) => {
|
|
return (
|
|
<TouchableOpacity
|
|
activeOpacity={0.7}
|
|
onPress={onPress}
|
|
style={[
|
|
styles.settingItem,
|
|
!isLast && styles.settingItemBorder,
|
|
{ borderBottomColor: isDarkMode ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.05)' }
|
|
]}
|
|
>
|
|
<View style={[
|
|
styles.settingIconContainer,
|
|
{ backgroundColor: isDarkMode ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.05)' }
|
|
]}>
|
|
<MaterialIcons name={icon} size={20} color={colors.primary} />
|
|
</View>
|
|
<View style={styles.settingContent}>
|
|
<View style={styles.settingTextContainer}>
|
|
<Text style={[styles.settingTitle, { color: isDarkMode ? colors.highEmphasis : colors.textDark }]}>
|
|
{title}
|
|
</Text>
|
|
{description && (
|
|
<Text style={[styles.settingDescription, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>
|
|
{description}
|
|
</Text>
|
|
)}
|
|
</View>
|
|
{badge && (
|
|
<View style={[styles.badge, { backgroundColor: colors.primary }]}>
|
|
<Text style={styles.badgeText}>{badge}</Text>
|
|
</View>
|
|
)}
|
|
</View>
|
|
<View style={styles.settingControl}>
|
|
{renderControl()}
|
|
</View>
|
|
</TouchableOpacity>
|
|
);
|
|
};
|
|
|
|
const SettingsScreen: React.FC = () => {
|
|
const { settings, updateSetting } = useSettings();
|
|
const systemColorScheme = useColorScheme();
|
|
const isDarkMode = systemColorScheme === 'dark' || settings.enableDarkMode;
|
|
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
|
const { lastUpdate } = useCatalogContext();
|
|
const { isAuthenticated, userProfile } = useTraktContext();
|
|
const insets = useSafeAreaInsets();
|
|
|
|
// States for dynamic content
|
|
const [addonCount, setAddonCount] = useState<number>(0);
|
|
const [catalogCount, setCatalogCount] = useState<number>(0);
|
|
const [mdblistKeySet, setMdblistKeySet] = useState<boolean>(false);
|
|
const [discoverDataSource, setDiscoverDataSource] = useState<DataSource>(DataSource.STREMIO_ADDONS);
|
|
|
|
// Force consistent status bar settings
|
|
useEffect(() => {
|
|
const applyStatusBarConfig = () => {
|
|
StatusBar.setBarStyle('light-content');
|
|
if (Platform.OS === 'android') {
|
|
StatusBar.setTranslucent(true);
|
|
StatusBar.setBackgroundColor('transparent');
|
|
}
|
|
};
|
|
|
|
applyStatusBarConfig();
|
|
|
|
// Re-apply on focus
|
|
const unsubscribe = navigation.addListener('focus', applyStatusBarConfig);
|
|
return unsubscribe;
|
|
}, [navigation]);
|
|
|
|
const loadData = useCallback(async () => {
|
|
try {
|
|
// Load addon count and get their catalogs
|
|
const addons = await stremioService.getInstalledAddonsAsync();
|
|
setAddonCount(addons.length);
|
|
|
|
// Count total available catalogs
|
|
let totalCatalogs = 0;
|
|
addons.forEach(addon => {
|
|
if (addon.catalogs && addon.catalogs.length > 0) {
|
|
totalCatalogs += addon.catalogs.length;
|
|
}
|
|
});
|
|
|
|
// Load saved catalog settings
|
|
const catalogSettingsJson = await AsyncStorage.getItem('catalog_settings');
|
|
if (catalogSettingsJson) {
|
|
const catalogSettings = JSON.parse(catalogSettingsJson);
|
|
// Filter out _lastUpdate key and count only explicitly disabled catalogs
|
|
const disabledCount = Object.entries(catalogSettings)
|
|
.filter(([key, value]) => key !== '_lastUpdate' && value === false)
|
|
.length;
|
|
// Since catalogs are enabled by default, subtract disabled ones from total
|
|
setCatalogCount(totalCatalogs - disabledCount);
|
|
} else {
|
|
// If no settings saved, all catalogs are enabled by default
|
|
setCatalogCount(totalCatalogs);
|
|
}
|
|
|
|
// Check MDBList API key status
|
|
const mdblistKey = await AsyncStorage.getItem('mdblist_api_key');
|
|
setMdblistKeySet(!!mdblistKey);
|
|
|
|
// Get discover data source preference
|
|
const dataSource = await catalogService.getDataSourcePreference();
|
|
setDiscoverDataSource(dataSource);
|
|
} catch (error) {
|
|
console.error('Error loading settings data:', error);
|
|
}
|
|
}, []);
|
|
|
|
// Load data initially and when catalogs are updated
|
|
useEffect(() => {
|
|
loadData();
|
|
}, [loadData, lastUpdate]);
|
|
|
|
// Add focus listener to reload data when screen comes into focus
|
|
useEffect(() => {
|
|
const unsubscribe = navigation.addListener('focus', () => {
|
|
loadData();
|
|
});
|
|
|
|
return unsubscribe;
|
|
}, [navigation, loadData]);
|
|
|
|
const handleResetSettings = useCallback(() => {
|
|
Alert.alert(
|
|
'Reset Settings',
|
|
'Are you sure you want to reset all settings to default values?',
|
|
[
|
|
{ text: 'Cancel', style: 'cancel' },
|
|
{
|
|
text: 'Reset',
|
|
style: 'destructive',
|
|
onPress: () => {
|
|
(Object.keys(DEFAULT_SETTINGS) as Array<keyof typeof DEFAULT_SETTINGS>).forEach(key => {
|
|
updateSetting(key, DEFAULT_SETTINGS[key]);
|
|
});
|
|
}
|
|
}
|
|
]
|
|
);
|
|
}, [updateSetting]);
|
|
|
|
const CustomSwitch = ({ value, onValueChange }: { value: boolean, onValueChange: (value: boolean) => void }) => (
|
|
<Switch
|
|
value={value}
|
|
onValueChange={onValueChange}
|
|
trackColor={{ false: isDarkMode ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)', true: colors.primary }}
|
|
thumbColor={Platform.OS === 'android' ? (value ? colors.white : colors.white) : ''}
|
|
ios_backgroundColor={isDarkMode ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)'}
|
|
/>
|
|
);
|
|
|
|
const ChevronRight = () => (
|
|
<MaterialIcons
|
|
name="chevron-right"
|
|
size={22}
|
|
color={isDarkMode ? 'rgba(255,255,255,0.3)' : 'rgba(0,0,0,0.3)'}
|
|
/>
|
|
);
|
|
|
|
// Handle data source change
|
|
const handleDiscoverDataSourceChange = useCallback(async (value: string) => {
|
|
const dataSource = value as DataSource;
|
|
setDiscoverDataSource(dataSource);
|
|
await catalogService.setDataSourcePreference(dataSource);
|
|
}, []);
|
|
|
|
const headerBaseHeight = Platform.OS === 'android' ? 80 : 60;
|
|
const topSpacing = Platform.OS === 'android' ? (StatusBar.currentHeight || 0) : insets.top;
|
|
const headerHeight = headerBaseHeight + topSpacing;
|
|
|
|
return (
|
|
<View style={[
|
|
styles.container,
|
|
{ backgroundColor: isDarkMode ? colors.darkBackground : '#F2F2F7' }
|
|
]}>
|
|
{/* Fixed position header background to prevent shifts */}
|
|
<View style={[
|
|
styles.headerBackground,
|
|
{ height: headerHeight, backgroundColor: isDarkMode ? colors.darkBackground : '#F2F2F7' }
|
|
]} />
|
|
|
|
<View style={{ flex: 1 }}>
|
|
{/* Header Section with proper top spacing */}
|
|
<View style={[styles.header, { height: headerHeight, paddingTop: topSpacing }]}>
|
|
<Text style={[styles.headerTitle, { color: isDarkMode ? colors.highEmphasis : colors.textDark }]}>
|
|
Settings
|
|
</Text>
|
|
<TouchableOpacity onPress={handleResetSettings} style={styles.resetButton}>
|
|
<Text style={[styles.resetButtonText, {color: colors.primary}]}>Reset</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
{/* Content Container */}
|
|
<View style={styles.contentContainer}>
|
|
<ScrollView
|
|
style={styles.scrollView}
|
|
showsVerticalScrollIndicator={false}
|
|
contentContainerStyle={styles.scrollContent}
|
|
>
|
|
<SettingsCard isDarkMode={isDarkMode} title="User & Account">
|
|
<SettingItem
|
|
title="Trakt"
|
|
description={isAuthenticated ? `Connected as ${userProfile?.username || 'User'}` : "Not Connected"}
|
|
icon="person"
|
|
isDarkMode={isDarkMode}
|
|
renderControl={ChevronRight}
|
|
onPress={() => navigation.navigate('TraktSettings')}
|
|
isLast={true}
|
|
/>
|
|
</SettingsCard>
|
|
|
|
<SettingsCard isDarkMode={isDarkMode} title="Features">
|
|
<SettingItem
|
|
title="Calendar"
|
|
description="Manage your show calendar settings"
|
|
icon="calendar-today"
|
|
renderControl={ChevronRight}
|
|
onPress={() => navigation.navigate('Calendar')}
|
|
isDarkMode={isDarkMode}
|
|
/>
|
|
<SettingItem
|
|
title="Notifications"
|
|
description="Configure episode notifications and reminders"
|
|
icon="notifications"
|
|
renderControl={ChevronRight}
|
|
onPress={() => navigation.navigate('NotificationSettings')}
|
|
isDarkMode={isDarkMode}
|
|
isLast={true}
|
|
/>
|
|
</SettingsCard>
|
|
|
|
<SettingsCard isDarkMode={isDarkMode} title="Content">
|
|
<SettingItem
|
|
title="Addons"
|
|
description="Manage your installed addons"
|
|
icon="extension"
|
|
isDarkMode={isDarkMode}
|
|
renderControl={ChevronRight}
|
|
onPress={() => navigation.navigate('Addons')}
|
|
badge={addonCount}
|
|
/>
|
|
<SettingItem
|
|
title="Catalogs"
|
|
description="Configure content sources"
|
|
icon="view-list"
|
|
isDarkMode={isDarkMode}
|
|
renderControl={ChevronRight}
|
|
onPress={() => navigation.navigate('CatalogSettings')}
|
|
badge={catalogCount}
|
|
/>
|
|
<SettingItem
|
|
title="Home Screen"
|
|
description="Customize layout and content"
|
|
icon="home"
|
|
isDarkMode={isDarkMode}
|
|
renderControl={ChevronRight}
|
|
onPress={() => navigation.navigate('HomeScreenSettings')}
|
|
/>
|
|
<SettingItem
|
|
title="Ratings Source"
|
|
description={mdblistKeySet ? "MDBList API Configured" : "Configure MDBList API"}
|
|
icon="info-outline"
|
|
isDarkMode={isDarkMode}
|
|
renderControl={ChevronRight}
|
|
onPress={() => navigation.navigate('MDBListSettings')}
|
|
/>
|
|
<SettingItem
|
|
title="Logo Source Preference"
|
|
description="Choose primary source for title logos"
|
|
icon="image"
|
|
isDarkMode={isDarkMode}
|
|
renderControl={() => (
|
|
<View style={styles.selectorContainer}>
|
|
<TouchableOpacity
|
|
style={[
|
|
styles.selectorButton,
|
|
settings.logoSourcePreference === 'metahub' && styles.selectorButtonActive
|
|
]}
|
|
onPress={() => {
|
|
console.log('Setting logo source preference to Metahub');
|
|
updateSetting('logoSourcePreference', 'metahub');
|
|
console.log('New logo source preference:', 'metahub');
|
|
|
|
// Clear any cached logo data in storage
|
|
try {
|
|
// This is just to help clear any cached state - the exact implementation may vary
|
|
AsyncStorage.removeItem('_last_logos_');
|
|
} catch (e) {
|
|
console.error('Error clearing logo cache:', e);
|
|
}
|
|
|
|
// Show alert that settings have been updated
|
|
Alert.alert(
|
|
'Settings Updated',
|
|
'Logo source preference set to Metahub. Changes will apply when you navigate to content.',
|
|
[{ text: 'OK' }]
|
|
);
|
|
}}
|
|
>
|
|
<Text style={[
|
|
styles.selectorText,
|
|
settings.logoSourcePreference === 'metahub' && styles.selectorTextActive
|
|
]}>Metahub</Text>
|
|
</TouchableOpacity>
|
|
<TouchableOpacity
|
|
style={[
|
|
styles.selectorButton,
|
|
settings.logoSourcePreference === 'tmdb' && styles.selectorButtonActive
|
|
]}
|
|
onPress={() => {
|
|
console.log('Setting logo source preference to TMDB');
|
|
updateSetting('logoSourcePreference', 'tmdb');
|
|
console.log('New logo source preference:', 'tmdb');
|
|
|
|
// Clear any cached logo data in storage
|
|
try {
|
|
// This is just to help clear any cached state - the exact implementation may vary
|
|
AsyncStorage.removeItem('_last_logos_');
|
|
} catch (e) {
|
|
console.error('Error clearing logo cache:', e);
|
|
}
|
|
|
|
// Show alert that settings have been updated
|
|
Alert.alert(
|
|
'Settings Updated',
|
|
'Logo source preference set to TMDB. Changes will apply when you navigate to content.',
|
|
[{ text: 'OK' }]
|
|
);
|
|
}}
|
|
>
|
|
<Text style={[
|
|
styles.selectorText,
|
|
settings.logoSourcePreference === 'tmdb' && styles.selectorTextActive
|
|
]}>TMDB</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
)}
|
|
/>
|
|
<SettingItem
|
|
title="TMDB"
|
|
description="API & Metadata Settings"
|
|
icon="movie-filter"
|
|
isDarkMode={isDarkMode}
|
|
renderControl={ChevronRight}
|
|
onPress={() => navigation.navigate('TMDBSettings')}
|
|
isLast={true}
|
|
/>
|
|
</SettingsCard>
|
|
|
|
<SettingsCard isDarkMode={isDarkMode} title="Playback">
|
|
<SettingItem
|
|
title="Video Player"
|
|
description={Platform.OS === 'ios'
|
|
? (settings.preferredPlayer === 'internal'
|
|
? 'Built-in Player'
|
|
: settings.preferredPlayer
|
|
? settings.preferredPlayer.toUpperCase()
|
|
: 'Built-in Player')
|
|
: (settings.useExternalPlayer ? 'External Player' : 'Built-in Player')
|
|
}
|
|
icon="play-arrow"
|
|
isDarkMode={isDarkMode}
|
|
renderControl={ChevronRight}
|
|
onPress={() => navigation.navigate('PlayerSettings')}
|
|
isLast={true}
|
|
/>
|
|
</SettingsCard>
|
|
|
|
<SettingsCard isDarkMode={isDarkMode} title="Discover">
|
|
<SettingItem
|
|
title="Content Source"
|
|
description="Choose where to get content for the Discover screen"
|
|
icon="explore"
|
|
isDarkMode={isDarkMode}
|
|
renderControl={() => (
|
|
<View style={styles.selectorContainer}>
|
|
<TouchableOpacity
|
|
style={[
|
|
styles.selectorButton,
|
|
discoverDataSource === DataSource.STREMIO_ADDONS && styles.selectorButtonActive
|
|
]}
|
|
onPress={() => handleDiscoverDataSourceChange(DataSource.STREMIO_ADDONS)}
|
|
>
|
|
<Text style={[
|
|
styles.selectorText,
|
|
discoverDataSource === DataSource.STREMIO_ADDONS && styles.selectorTextActive
|
|
]}>Addons</Text>
|
|
</TouchableOpacity>
|
|
<TouchableOpacity
|
|
style={[
|
|
styles.selectorButton,
|
|
discoverDataSource === DataSource.TMDB && styles.selectorButtonActive
|
|
]}
|
|
onPress={() => handleDiscoverDataSourceChange(DataSource.TMDB)}
|
|
>
|
|
<Text style={[
|
|
styles.selectorText,
|
|
discoverDataSource === DataSource.TMDB && styles.selectorTextActive
|
|
]}>TMDB</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
)}
|
|
/>
|
|
</SettingsCard>
|
|
|
|
<View style={styles.versionContainer}>
|
|
<Text style={[styles.versionText, {color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark}]}>
|
|
Version 1.0.0
|
|
</Text>
|
|
</View>
|
|
</ScrollView>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
},
|
|
headerBackground: {
|
|
position: 'absolute',
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
zIndex: 1,
|
|
},
|
|
contentContainer: {
|
|
flex: 1,
|
|
zIndex: 1,
|
|
width: '100%',
|
|
},
|
|
header: {
|
|
paddingHorizontal: 20,
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'flex-end',
|
|
paddingBottom: 8,
|
|
backgroundColor: 'transparent',
|
|
zIndex: 2,
|
|
},
|
|
headerTitle: {
|
|
fontSize: 32,
|
|
fontWeight: '800',
|
|
letterSpacing: 0.3,
|
|
},
|
|
resetButton: {
|
|
paddingVertical: 8,
|
|
paddingHorizontal: 12,
|
|
},
|
|
resetButtonText: {
|
|
fontSize: 16,
|
|
fontWeight: '600',
|
|
},
|
|
scrollView: {
|
|
flex: 1,
|
|
width: '100%',
|
|
},
|
|
scrollContent: {
|
|
flexGrow: 1,
|
|
width: '100%',
|
|
paddingBottom: 32,
|
|
},
|
|
cardContainer: {
|
|
width: '100%',
|
|
marginBottom: 20,
|
|
},
|
|
cardTitle: {
|
|
fontSize: 13,
|
|
fontWeight: '600',
|
|
letterSpacing: 0.8,
|
|
marginLeft: 16,
|
|
marginBottom: 8,
|
|
},
|
|
card: {
|
|
marginHorizontal: 16,
|
|
borderRadius: 16,
|
|
overflow: 'hidden',
|
|
shadowColor: '#000',
|
|
shadowOffset: { width: 0, height: 2 },
|
|
shadowOpacity: 0.1,
|
|
shadowRadius: 4,
|
|
elevation: 3,
|
|
width: undefined, // Let it fill the container width
|
|
},
|
|
settingItem: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
paddingVertical: 12,
|
|
paddingHorizontal: 16,
|
|
borderBottomWidth: 0.5,
|
|
minHeight: 58,
|
|
width: '100%',
|
|
},
|
|
settingItemBorder: {
|
|
// Border styling handled directly in the component with borderBottomWidth
|
|
},
|
|
settingIconContainer: {
|
|
marginRight: 16,
|
|
width: 36,
|
|
height: 36,
|
|
borderRadius: 10,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
settingContent: {
|
|
flex: 1,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
},
|
|
settingTextContainer: {
|
|
flex: 1,
|
|
},
|
|
settingTitleRow: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
},
|
|
settingTitle: {
|
|
fontSize: 16,
|
|
fontWeight: '500',
|
|
marginBottom: 3,
|
|
},
|
|
settingDescription: {
|
|
fontSize: 14,
|
|
opacity: 0.8,
|
|
},
|
|
settingControl: {
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
paddingLeft: 12,
|
|
},
|
|
badge: {
|
|
height: 22,
|
|
minWidth: 22,
|
|
borderRadius: 11,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
paddingHorizontal: 6,
|
|
marginRight: 8,
|
|
},
|
|
badgeText: {
|
|
color: 'white',
|
|
fontSize: 12,
|
|
fontWeight: '600',
|
|
},
|
|
versionContainer: {
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
marginTop: 10,
|
|
marginBottom: 20,
|
|
},
|
|
versionText: {
|
|
fontSize: 14,
|
|
},
|
|
pickerContainer: {
|
|
flex: 1,
|
|
},
|
|
picker: {
|
|
flex: 1,
|
|
},
|
|
selectorContainer: {
|
|
flexDirection: 'row',
|
|
borderRadius: 8,
|
|
overflow: 'hidden',
|
|
height: 36,
|
|
width: 160,
|
|
marginRight: 8,
|
|
},
|
|
selectorButton: {
|
|
flex: 1,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
paddingHorizontal: 12,
|
|
backgroundColor: 'rgba(255,255,255,0.08)',
|
|
},
|
|
selectorButtonActive: {
|
|
backgroundColor: colors.primary,
|
|
},
|
|
selectorText: {
|
|
fontSize: 14,
|
|
fontWeight: '500',
|
|
color: colors.mediumEmphasis,
|
|
},
|
|
selectorTextActive: {
|
|
color: colors.white,
|
|
fontWeight: '600',
|
|
},
|
|
});
|
|
|
|
export default SettingsScreen; |