update morelikethis sizing

This commit is contained in:
tapframe 2025-10-19 20:34:37 +05:30
parent 175d47f71f
commit 68340eac9e

View file

@ -20,32 +20,13 @@ import CustomAlert from '../../components/CustomAlert';
const { width } = Dimensions.get('window'); const { width } = Dimensions.get('window');
// Dynamic poster calculation based on screen width for More Like This section // Breakpoints for responsive sizing
const calculatePosterLayout = (screenWidth: number) => { const BREAKPOINTS = {
const MIN_POSTER_WIDTH = 100; // Slightly smaller for more items in this section phone: 0,
const MAX_POSTER_WIDTH = 130; // Maximum poster width tablet: 768,
const HORIZONTAL_PADDING = 48; // Total horizontal padding/margins largeTablet: 1024,
tv: 1440,
// Calculate how many posters can fit (aim for slightly more items than main sections) } as const;
const availableWidth = screenWidth - HORIZONTAL_PADDING;
const maxColumns = Math.floor(availableWidth / MIN_POSTER_WIDTH);
// Limit to reasonable number of columns (3-7 for this section)
const numColumns = Math.min(Math.max(maxColumns, 3), 7);
// Calculate actual poster width
const posterWidth = Math.min(availableWidth / numColumns, MAX_POSTER_WIDTH);
return {
numColumns,
posterWidth,
spacing: 12 // Space between posters
};
};
const posterLayout = calculatePosterLayout(width);
const POSTER_WIDTH = posterLayout.posterWidth;
const POSTER_HEIGHT = POSTER_WIDTH * 1.5;
interface MoreLikeThisSectionProps { interface MoreLikeThisSectionProps {
recommendations: StreamingContent[]; recommendations: StreamingContent[];
@ -59,6 +40,48 @@ export const MoreLikeThisSection: React.FC<MoreLikeThisSectionProps> = ({
const { currentTheme } = useTheme(); const { currentTheme } = useTheme();
const navigation = useNavigation<NavigationProp<RootStackParamList>>(); const navigation = useNavigation<NavigationProp<RootStackParamList>>();
// Determine device type
const deviceWidth = Dimensions.get('window').width;
const getDeviceType = React.useCallback(() => {
if (deviceWidth >= BREAKPOINTS.tv) return 'tv';
if (deviceWidth >= BREAKPOINTS.largeTablet) return 'largeTablet';
if (deviceWidth >= BREAKPOINTS.tablet) return 'tablet';
return 'phone';
}, [deviceWidth]);
const deviceType = getDeviceType();
const isTablet = deviceType === 'tablet';
const isLargeTablet = deviceType === 'largeTablet';
const isTV = deviceType === 'tv';
// Responsive spacing & sizes
const horizontalPadding = React.useMemo(() => {
switch (deviceType) {
case 'tv': return 32;
case 'largeTablet': return 28;
case 'tablet': return 24;
default: return 16;
}
}, [deviceType]);
const itemSpacing = React.useMemo(() => {
switch (deviceType) {
case 'tv': return 14;
case 'largeTablet': return 12;
case 'tablet': return 12;
default: return 12;
}
}, [deviceType]);
const posterWidth = React.useMemo(() => {
switch (deviceType) {
case 'tv': return 180;
case 'largeTablet': return 160;
case 'tablet': return 140;
default: return 120;
}
}, [deviceType]);
const posterHeight = React.useMemo(() => posterWidth * 1.5, [posterWidth]);
const [alertVisible, setAlertVisible] = React.useState(false); const [alertVisible, setAlertVisible] = React.useState(false);
const [alertTitle, setAlertTitle] = React.useState(''); const [alertTitle, setAlertTitle] = React.useState('');
const [alertMessage, setAlertMessage] = React.useState(''); const [alertMessage, setAlertMessage] = React.useState('');
@ -94,15 +117,15 @@ export const MoreLikeThisSection: React.FC<MoreLikeThisSectionProps> = ({
const renderItem = ({ item }: { item: StreamingContent }) => ( const renderItem = ({ item }: { item: StreamingContent }) => (
<TouchableOpacity <TouchableOpacity
style={styles.itemContainer} style={[styles.itemContainer, { width: posterWidth, marginRight: itemSpacing }]}
onPress={() => handleItemPress(item)} onPress={() => handleItemPress(item)}
> >
<FastImage <FastImage
source={{ uri: item.poster }} source={{ uri: item.poster }}
style={[styles.poster, { backgroundColor: currentTheme.colors.elevation1 }]} style={[styles.poster, { backgroundColor: currentTheme.colors.elevation1, width: posterWidth, height: posterHeight, borderRadius: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 10 : 8 }]}
resizeMode={FastImage.resizeMode.cover} resizeMode={FastImage.resizeMode.cover}
/> />
<Text style={[styles.title, { color: currentTheme.colors.mediumEmphasis }]} numberOfLines={2}> <Text style={[styles.title, { color: currentTheme.colors.mediumEmphasis, fontSize: isTV ? 14 : isLargeTablet ? 13 : isTablet ? 13 : 13, lineHeight: isTV ? 20 : 18 }]} numberOfLines={2}>
{item.name} {item.name}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
@ -121,15 +144,15 @@ export const MoreLikeThisSection: React.FC<MoreLikeThisSectionProps> = ({
} }
return ( return (
<View style={styles.container}> <View style={[styles.container, { paddingLeft: 0 }] }>
<Text style={[styles.sectionTitle, { color: currentTheme.colors.highEmphasis }]}>More Like This</Text> <Text style={[styles.sectionTitle, { color: currentTheme.colors.highEmphasis, fontSize: isTV ? 24 : isLargeTablet ? 22 : isTablet ? 20 : 20, paddingHorizontal: horizontalPadding }]}>More Like This</Text>
<FlatList <FlatList
data={recommendations} data={recommendations}
renderItem={renderItem} renderItem={renderItem}
keyExtractor={(item) => item.id} keyExtractor={(item) => item.id}
horizontal horizontal
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.listContentContainer} contentContainerStyle={[styles.listContentContainer, { paddingHorizontal: horizontalPadding, paddingRight: horizontalPadding + itemSpacing }]}
/> />
<CustomAlert <CustomAlert
visible={alertVisible} visible={alertVisible}
@ -146,36 +169,30 @@ const styles = StyleSheet.create({
container: { container: {
marginTop: 16, marginTop: 16,
marginBottom: 16, marginBottom: 16,
paddingLeft: 0,
}, },
sectionTitle: { sectionTitle: {
fontSize: 20, fontSize: 20,
fontWeight: '800', fontWeight: '800',
marginBottom: 12, marginBottom: 12,
marginTop: 8, marginTop: 8,
paddingHorizontal: 16,
}, },
listContentContainer: { listContentContainer: {
paddingHorizontal: 16, paddingRight: 32, // Will be overridden responsively
paddingRight: 32, // Ensure last item has padding
}, },
itemContainer: { itemContainer: {
marginRight: 12, marginRight: 12, // will be overridden responsively
width: POSTER_WIDTH,
}, },
poster: { poster: {
width: POSTER_WIDTH, borderRadius: 8, // overridden responsively
height: POSTER_HEIGHT,
borderRadius: 8,
marginBottom: 8, marginBottom: 8,
}, },
title: { title: {
fontSize: 13, fontSize: 13, // overridden responsively
fontWeight: '500', fontWeight: '500',
lineHeight: 18, lineHeight: 18, // overridden responsively
}, },
loadingContainer: { loadingContainer: {
height: POSTER_HEIGHT + 40, // Approximate height to prevent layout shifts // Approximate height to prevent layout shifts; not used in responsive version
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
}, },