Ios #14
8 changed files with 265 additions and 8 deletions
|
|
@ -14,7 +14,32 @@ interface CatalogSectionProps {
|
|||
}
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
const POSTER_WIDTH = (width - 50) / 3;
|
||||
|
||||
// Dynamic poster calculation based on screen width
|
||||
const calculatePosterLayout = (screenWidth: number) => {
|
||||
const MIN_POSTER_WIDTH = 110; // Minimum poster width for readability
|
||||
const MAX_POSTER_WIDTH = 140; // Maximum poster width to prevent oversized posters
|
||||
const HORIZONTAL_PADDING = 50; // Total horizontal padding/margins
|
||||
|
||||
// Calculate how many posters can fit
|
||||
const availableWidth = screenWidth - HORIZONTAL_PADDING;
|
||||
const maxColumns = Math.floor(availableWidth / MIN_POSTER_WIDTH);
|
||||
|
||||
// Limit to reasonable number of columns (3-6)
|
||||
const numColumns = Math.min(Math.max(maxColumns, 3), 6);
|
||||
|
||||
// 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 CatalogSection = ({ catalog }: CatalogSectionProps) => {
|
||||
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,32 @@ interface ContentItemProps {
|
|||
}
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
const POSTER_WIDTH = (width - 50) / 3;
|
||||
|
||||
// Dynamic poster calculation based on screen width
|
||||
const calculatePosterLayout = (screenWidth: number) => {
|
||||
const MIN_POSTER_WIDTH = 110; // Minimum poster width for readability
|
||||
const MAX_POSTER_WIDTH = 140; // Maximum poster width to prevent oversized posters
|
||||
const HORIZONTAL_PADDING = 50; // Total horizontal padding/margins
|
||||
|
||||
// Calculate how many posters can fit
|
||||
const availableWidth = screenWidth - HORIZONTAL_PADDING;
|
||||
const maxColumns = Math.floor(availableWidth / MIN_POSTER_WIDTH);
|
||||
|
||||
// Limit to reasonable number of columns (3-6)
|
||||
const numColumns = Math.min(Math.max(maxColumns, 3), 6);
|
||||
|
||||
// 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 ContentItem = ({ item: initialItem, onPress }: ContentItemProps) => {
|
||||
const [menuVisible, setMenuVisible] = useState(false);
|
||||
|
|
|
|||
|
|
@ -33,8 +33,32 @@ interface ContinueWatchingRef {
|
|||
refresh: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
// Dynamic poster calculation based on screen width for Continue Watching section
|
||||
const calculatePosterLayout = (screenWidth: number) => {
|
||||
const MIN_POSTER_WIDTH = 120; // Slightly larger for continue watching items
|
||||
const MAX_POSTER_WIDTH = 160; // Maximum poster width for this section
|
||||
const HORIZONTAL_PADDING = 40; // Total horizontal padding/margins
|
||||
|
||||
// Calculate how many posters can fit (fewer items for continue watching)
|
||||
const availableWidth = screenWidth - HORIZONTAL_PADDING;
|
||||
const maxColumns = Math.floor(availableWidth / MIN_POSTER_WIDTH);
|
||||
|
||||
// Limit to reasonable number of columns (2-5 for continue watching)
|
||||
const numColumns = Math.min(Math.max(maxColumns, 2), 5);
|
||||
|
||||
// Calculate actual poster width
|
||||
const posterWidth = Math.min(availableWidth / numColumns, MAX_POSTER_WIDTH);
|
||||
|
||||
return {
|
||||
numColumns,
|
||||
posterWidth,
|
||||
spacing: 12 // Space between posters
|
||||
};
|
||||
};
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
const POSTER_WIDTH = (width - 40) / 2.7;
|
||||
const posterLayout = calculatePosterLayout(width);
|
||||
const POSTER_WIDTH = posterLayout.posterWidth;
|
||||
|
||||
// Create a proper imperative handle with React.forwardRef and updated type
|
||||
const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, ref) => {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,32 @@ import { TMDBService } from '../../services/tmdbService';
|
|||
import { catalogService } from '../../services/catalogService';
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
const POSTER_WIDTH = (width - 48) / 3.5; // Adjust number for desired items visible
|
||||
|
||||
// Dynamic poster calculation based on screen width for More Like This section
|
||||
const calculatePosterLayout = (screenWidth: number) => {
|
||||
const MIN_POSTER_WIDTH = 100; // Slightly smaller for more items in this section
|
||||
const MAX_POSTER_WIDTH = 130; // Maximum poster width
|
||||
const HORIZONTAL_PADDING = 48; // Total horizontal padding/margins
|
||||
|
||||
// Calculate how many posters can fit (aim for slightly more items than main sections)
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -41,9 +41,35 @@ const ANDROID_STATUSBAR_HEIGHT = StatusBar.currentHeight || 0;
|
|||
|
||||
// Screen dimensions and grid layout
|
||||
const { width } = Dimensions.get('window');
|
||||
const NUM_COLUMNS = 3;
|
||||
|
||||
// Dynamic column calculation based on screen width
|
||||
const calculateCatalogLayout = (screenWidth: number) => {
|
||||
const MIN_ITEM_WIDTH = 110; // Minimum item width for readability
|
||||
const MAX_ITEM_WIDTH = 150; // Maximum item width
|
||||
const HORIZONTAL_PADDING = SPACING.lg * 2; // Total horizontal padding
|
||||
const ITEM_MARGIN_TOTAL = SPACING.sm * 2; // Total margin per item
|
||||
|
||||
// Calculate how many columns can fit
|
||||
const availableWidth = screenWidth - HORIZONTAL_PADDING;
|
||||
const maxColumns = Math.floor(availableWidth / (MIN_ITEM_WIDTH + ITEM_MARGIN_TOTAL));
|
||||
|
||||
// Limit to reasonable number of columns (2-6)
|
||||
const numColumns = Math.min(Math.max(maxColumns, 2), 6);
|
||||
|
||||
// Calculate actual item width
|
||||
const totalMargins = ITEM_MARGIN_TOTAL * numColumns;
|
||||
const itemWidth = Math.min((availableWidth - totalMargins) / numColumns, MAX_ITEM_WIDTH);
|
||||
|
||||
return {
|
||||
numColumns,
|
||||
itemWidth
|
||||
};
|
||||
};
|
||||
|
||||
const catalogLayout = calculateCatalogLayout(width);
|
||||
const NUM_COLUMNS = catalogLayout.numColumns;
|
||||
const ITEM_MARGIN = SPACING.sm;
|
||||
const ITEM_WIDTH = (width - (SPACING.lg * 2) - (ITEM_MARGIN * 2 * NUM_COLUMNS)) / NUM_COLUMNS;
|
||||
const ITEM_WIDTH = catalogLayout.itemWidth;
|
||||
|
||||
// Create a styles creator function that accepts the theme colors
|
||||
const createStyles = (colors: any) => StyleSheet.create({
|
||||
|
|
|
|||
|
|
@ -679,7 +679,32 @@ const HomeScreen = () => {
|
|||
};
|
||||
|
||||
const { width, height } = Dimensions.get('window');
|
||||
const POSTER_WIDTH = (width - 50) / 3;
|
||||
|
||||
// Dynamic poster calculation based on screen width
|
||||
const calculatePosterLayout = (screenWidth: number) => {
|
||||
const MIN_POSTER_WIDTH = 110; // Minimum poster width for readability
|
||||
const MAX_POSTER_WIDTH = 140; // Maximum poster width to prevent oversized posters
|
||||
const HORIZONTAL_PADDING = 50; // Total horizontal padding/margins
|
||||
|
||||
// Calculate how many posters can fit
|
||||
const availableWidth = screenWidth - HORIZONTAL_PADDING;
|
||||
const maxColumns = Math.floor(availableWidth / MIN_POSTER_WIDTH);
|
||||
|
||||
// Limit to reasonable number of columns (3-6)
|
||||
const numColumns = Math.min(Math.max(maxColumns, 3), 6);
|
||||
|
||||
// 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 styles = StyleSheet.create<any>({
|
||||
container: {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,32 @@
|
|||
import { StyleSheet, Dimensions, Platform } from 'react-native';
|
||||
|
||||
const { width, height } = Dimensions.get('window');
|
||||
export const POSTER_WIDTH = (width - 50) / 3;
|
||||
|
||||
// Dynamic poster calculation based on screen width
|
||||
const calculatePosterLayout = (screenWidth: number) => {
|
||||
const MIN_POSTER_WIDTH = 110; // Minimum poster width for readability
|
||||
const MAX_POSTER_WIDTH = 140; // Maximum poster width to prevent oversized posters
|
||||
const HORIZONTAL_PADDING = 50; // Total horizontal padding/margins
|
||||
|
||||
// Calculate how many posters can fit
|
||||
const availableWidth = screenWidth - HORIZONTAL_PADDING;
|
||||
const maxColumns = Math.floor(availableWidth / MIN_POSTER_WIDTH);
|
||||
|
||||
// Limit to reasonable number of columns (3-6)
|
||||
const numColumns = Math.min(Math.max(maxColumns, 3), 6);
|
||||
|
||||
// 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);
|
||||
export const POSTER_WIDTH = posterLayout.posterWidth;
|
||||
export const POSTER_HEIGHT = POSTER_WIDTH * 1.5;
|
||||
export const HORIZONTAL_PADDING = 16;
|
||||
|
||||
|
|
|
|||
82
src/utils/posterUtils.ts
Normal file
82
src/utils/posterUtils.ts
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import { Dimensions } from 'react-native';
|
||||
|
||||
export interface PosterLayoutConfig {
|
||||
minPosterWidth: number;
|
||||
maxPosterWidth: number;
|
||||
horizontalPadding: number;
|
||||
minColumns: number;
|
||||
maxColumns: number;
|
||||
spacing: number;
|
||||
}
|
||||
|
||||
export interface PosterLayout {
|
||||
numColumns: number;
|
||||
posterWidth: number;
|
||||
spacing: number;
|
||||
}
|
||||
|
||||
// Default configuration for main home sections
|
||||
export const DEFAULT_POSTER_CONFIG: PosterLayoutConfig = {
|
||||
minPosterWidth: 110,
|
||||
maxPosterWidth: 140,
|
||||
horizontalPadding: 50,
|
||||
minColumns: 3,
|
||||
maxColumns: 6,
|
||||
spacing: 12
|
||||
};
|
||||
|
||||
// Configuration for More Like This section (smaller posters, more items)
|
||||
export const MORE_LIKE_THIS_CONFIG: PosterLayoutConfig = {
|
||||
minPosterWidth: 100,
|
||||
maxPosterWidth: 130,
|
||||
horizontalPadding: 48,
|
||||
minColumns: 3,
|
||||
maxColumns: 7,
|
||||
spacing: 12
|
||||
};
|
||||
|
||||
// Configuration for Continue Watching section (larger posters, fewer items)
|
||||
export const CONTINUE_WATCHING_CONFIG: PosterLayoutConfig = {
|
||||
minPosterWidth: 120,
|
||||
maxPosterWidth: 160,
|
||||
horizontalPadding: 40,
|
||||
minColumns: 2,
|
||||
maxColumns: 5,
|
||||
spacing: 12
|
||||
};
|
||||
|
||||
export const calculatePosterLayout = (
|
||||
screenWidth: number,
|
||||
config: PosterLayoutConfig = DEFAULT_POSTER_CONFIG
|
||||
): PosterLayout => {
|
||||
const {
|
||||
minPosterWidth,
|
||||
maxPosterWidth,
|
||||
horizontalPadding,
|
||||
minColumns,
|
||||
maxColumns,
|
||||
spacing
|
||||
} = config;
|
||||
|
||||
// Calculate how many posters can fit
|
||||
const availableWidth = screenWidth - horizontalPadding;
|
||||
const maxColumnsBasedOnWidth = Math.floor(availableWidth / minPosterWidth);
|
||||
|
||||
// Limit to reasonable number of columns
|
||||
const numColumns = Math.min(Math.max(maxColumnsBasedOnWidth, minColumns), maxColumns);
|
||||
|
||||
// Calculate actual poster width
|
||||
const posterWidth = Math.min(availableWidth / numColumns, maxPosterWidth);
|
||||
|
||||
return {
|
||||
numColumns,
|
||||
posterWidth,
|
||||
spacing
|
||||
};
|
||||
};
|
||||
|
||||
// Helper function to get current screen dimensions
|
||||
export const getCurrentPosterLayout = (config?: PosterLayoutConfig): PosterLayout => {
|
||||
const { width } = Dimensions.get('window');
|
||||
return calculatePosterLayout(width, config);
|
||||
};
|
||||
Loading…
Reference in a new issue