This commit is contained in:
tapframe 2025-09-03 15:46:24 +05:30
parent 213fbbbb4e
commit e3b86bcc90
3 changed files with 84 additions and 8 deletions

View file

@ -3,6 +3,7 @@ import { View, TouchableOpacity, ActivityIndicator, StyleSheet, Dimensions, Plat
import { Image as ExpoImage } from 'expo-image';
import { MaterialIcons } from '@expo/vector-icons';
import { useTheme } from '../../contexts/ThemeContext';
import { useSettings } from '../../hooks/useSettings';
import { catalogService, StreamingContent } from '../../services/catalogService';
import { DropUpMenu } from './DropUpMenu';
@ -63,6 +64,18 @@ const ContentItem = ({ item, onPress }: ContentItemProps) => {
const [shouldLoadImage, setShouldLoadImage] = useState(false);
const [retryCount, setRetryCount] = useState(0);
const { currentTheme } = useTheme();
const { settings } = useSettings();
const posterRadius = typeof settings.posterBorderRadius === 'number' ? settings.posterBorderRadius : 12;
const posterWidth = React.useMemo(() => {
switch (settings.posterSize) {
case 'small':
return Math.max(100, Math.min(POSTER_WIDTH - 10, POSTER_WIDTH));
case 'large':
return Math.min(POSTER_WIDTH + 20, POSTER_WIDTH + 30);
default:
return POSTER_WIDTH;
}
}, [settings.posterSize]);
// Intersection observer simulation for lazy loading
const itemRef = useRef<View>(null);
@ -135,20 +148,20 @@ const ContentItem = ({ item, onPress }: ContentItemProps) => {
return (
<>
<View style={styles.itemContainer}>
<View style={[styles.itemContainer, { width: posterWidth }]}>
<TouchableOpacity
style={styles.contentItem}
style={[styles.contentItem, { width: posterWidth, borderRadius: posterRadius }]}
activeOpacity={0.7}
onPress={handlePress}
onLongPress={handleLongPress}
delayLongPress={300}
>
<View ref={itemRef} style={styles.contentItemContainer}>
<View ref={itemRef} style={[styles.contentItemContainer, { borderRadius: posterRadius }] }>
{/* Only load image when shouldLoadImage is true (lazy loading) */}
{shouldLoadImage && item.poster ? (
<ExpoImage
source={{ uri: getOptimizedPosterUrl(item.poster) }}
style={[styles.poster, { backgroundColor: currentTheme.colors.elevation1 }]}
style={[styles.poster, { backgroundColor: currentTheme.colors.elevation1, borderRadius: posterRadius }]}
contentFit="cover"
cachePolicy="memory-disk" // Use both memory and disk cache
transition={200} // Add smooth transition
@ -175,7 +188,7 @@ const ContentItem = ({ item, onPress }: ContentItemProps) => {
/>
) : (
// Show placeholder until lazy load triggers
<View style={[styles.poster, { backgroundColor: currentTheme.colors.elevation1, justifyContent: 'center', alignItems: 'center' }]}>
<View style={[styles.poster, { backgroundColor: currentTheme.colors.elevation1, justifyContent: 'center', alignItems: 'center', borderRadius: posterRadius }] }>
<Text style={{ color: currentTheme.colors.textMuted, fontSize: 10, textAlign: 'center' }}>
{item.name.substring(0, 20)}...
</Text>
@ -198,9 +211,11 @@ const ContentItem = ({ item, onPress }: ContentItemProps) => {
)}
</View>
</TouchableOpacity>
<Text style={[styles.title, { color: currentTheme.colors.text }]} numberOfLines={2}>
{item.name}
</Text>
{settings.showPosterTitles && (
<Text style={[styles.title, { color: currentTheme.colors.text }]} numberOfLines={2}>
{item.name}
</Text>
)}
</View>
<DropUpMenu

View file

@ -65,6 +65,8 @@ export interface AppSettings {
posterSize: 'small' | 'medium' | 'large'; // Predefined sizes
posterBorderRadius: number; // 0-20 range for border radius
postersPerRow: number; // 3-6 range for number of posters per row
// Home screen content item
showPosterTitles: boolean; // Show text titles under posters
// Trailer settings
showTrailers: boolean; // Enable/disable trailer playback in hero section
trailerMuted: boolean; // Default to muted for better user experience
@ -107,6 +109,7 @@ export const DEFAULT_SETTINGS: AppSettings = {
posterSize: 'medium',
posterBorderRadius: 12,
postersPerRow: 4,
showPosterTitles: true,
// Trailer settings
showTrailers: true, // Enable trailers by default
trailerMuted: true, // Default to muted for better user experience

View file

@ -346,6 +346,34 @@ const HomeScreenSettings: React.FC = () => {
</>
)}
<SettingsCard isDarkMode={isDarkMode} colors={colors}>
<Text style={[styles.cardHeader, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>Posters</Text>
<View style={styles.settingsRowInline}>
<Text style={[styles.rowLabel, { color: isDarkMode ? colors.highEmphasis : colors.textDark }]}>Show Titles</Text>
<CustomSwitch
value={settings.showPosterTitles}
onValueChange={(value) => handleUpdateSetting('showPosterTitles', value)}
/>
</View>
<View style={styles.settingsRow}>
<Text style={[styles.rowLabel, { color: isDarkMode ? colors.highEmphasis : colors.textDark }]}>Poster Size</Text>
<SegmentedControl
options={[{ label: 'Small', value: 'small' }, { label: 'Medium', value: 'medium' }, { label: 'Large', value: 'large' }]}
value={settings.posterSize}
onChange={(val) => handleUpdateSetting('posterSize', val as any)}
/>
</View>
<View style={styles.settingsRow}>
<Text style={[styles.rowLabel, { color: isDarkMode ? colors.highEmphasis : colors.textDark }]}>Poster Corners</Text>
<SegmentedControl
options={[{ label: 'Square', value: '0' }, { label: 'Rounded', value: '12' }, { label: 'Pill', value: '20' }]}
value={String(settings.posterBorderRadius)}
onChange={(val) => handleUpdateSetting('posterBorderRadius', Number(val) as any)}
/>
</View>
</SettingsCard>
<SectionHeader title="ABOUT THESE SETTINGS" isDarkMode={isDarkMode} colors={colors} />
<View style={[styles.infoCard, { backgroundColor: isDarkMode ? colors.elevation1 : 'rgba(0,0,0,0.03)' }]}>
<Text style={[styles.infoText, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>
@ -385,6 +413,7 @@ const styles = StyleSheet.create({
},
sectionHeader: {
paddingHorizontal: 16,
marginHorizontal: 16,
paddingTop: 20,
paddingBottom: 8,
},
@ -395,6 +424,8 @@ const styles = StyleSheet.create({
},
card: {
marginHorizontal: 16,
marginTop: 12,
marginBottom: 12,
borderRadius: 12,
overflow: 'hidden',
shadowColor: '#000',
@ -515,6 +546,7 @@ const styles = StyleSheet.create({
segmentCard: {
marginHorizontal: 16,
marginTop: 12,
marginBottom: 12,
padding: 16,
borderRadius: 12,
backgroundColor: 'rgba(255,255,255,0.05)'
@ -539,6 +571,32 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'space-between',
},
settingsRow: {
paddingHorizontal: 16,
paddingVertical: 12,
gap: 8,
},
settingsRowInline: {
paddingHorizontal: 16,
paddingVertical: 12,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
rowLabel: {
fontSize: 14,
fontWeight: '600',
marginBottom: 4,
opacity: 0.9,
},
cardHeader: {
fontSize: 12,
fontWeight: '700',
letterSpacing: 0.6,
paddingHorizontal: 16,
paddingTop: 12,
opacity: 0.9,
},
savedIndicator: {
position: 'absolute',
top: Platform.OS === 'android' ? (StatusBar.currentHeight || 0) + 60 : 90,