mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 01:35:39 -04:00
fix(native): make person filmography grid responsive to screen width
Replace the hardcoded 2-column filmography grid with a responsive layout that uses 2, 3, or 4 columns based on screen width (600px and 900px breakpoints). Switch from per-item fixed widths to horizontal gutter padding so columns are evenly distributed across all screen sizes.
This commit is contained in:
@@ -33,6 +33,7 @@ import { addRecentlyViewed } from "@/lib/recently-viewed";
|
|||||||
|
|
||||||
const FILMOGRAPHY_GAP = 12;
|
const FILMOGRAPHY_GAP = 12;
|
||||||
const FILMOGRAPHY_PADDING = 16;
|
const FILMOGRAPHY_PADDING = 16;
|
||||||
|
const FILMOGRAPHY_GUTTER = FILMOGRAPHY_GAP / 2;
|
||||||
|
|
||||||
function calculateAge(birthday: string, deathday?: string | null): number {
|
function calculateAge(birthday: string, deathday?: string | null): number {
|
||||||
const birth = new Date(birthday);
|
const birth = new Date(birthday);
|
||||||
@@ -60,8 +61,14 @@ export default function PersonDetailScreen() {
|
|||||||
const { back } = useRouter();
|
const { back } = useRouter();
|
||||||
const { width: screenWidth } = useWindowDimensions();
|
const { width: screenWidth } = useWindowDimensions();
|
||||||
const useAutomaticInsets = process.env.EXPO_OS === "ios";
|
const useAutomaticInsets = process.env.EXPO_OS === "ios";
|
||||||
const columnWidth =
|
const filmographyColumns =
|
||||||
(screenWidth - FILMOGRAPHY_PADDING * 2 - FILMOGRAPHY_GAP) / 2;
|
screenWidth >= 900 ? 4 : screenWidth >= 600 ? 3 : 2;
|
||||||
|
const columnWidth = Math.floor(
|
||||||
|
(screenWidth -
|
||||||
|
FILMOGRAPHY_PADDING * 2 -
|
||||||
|
FILMOGRAPHY_GAP * (filmographyColumns - 1)) /
|
||||||
|
filmographyColumns,
|
||||||
|
);
|
||||||
|
|
||||||
const mutedForeground = useCSSVariable("--color-muted-foreground") as string;
|
const mutedForeground = useCSSVariable("--color-muted-foreground") as string;
|
||||||
const primaryColor = useCSSVariable("--color-primary") as string;
|
const primaryColor = useCSSVariable("--color-primary") as string;
|
||||||
@@ -117,7 +124,12 @@ export default function PersonDetailScreen() {
|
|||||||
|
|
||||||
const renderFilmographyItem = useCallback(
|
const renderFilmographyItem = useCallback(
|
||||||
({ item: credit }: { item: (typeof filmography)[number] }) => (
|
({ item: credit }: { item: (typeof filmography)[number] }) => (
|
||||||
<View style={{ width: columnWidth, paddingBottom: FILMOGRAPHY_GAP }}>
|
<View
|
||||||
|
style={{
|
||||||
|
paddingBottom: FILMOGRAPHY_GAP,
|
||||||
|
paddingHorizontal: FILMOGRAPHY_GUTTER,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<PosterCard
|
<PosterCard
|
||||||
id={credit.titleId}
|
id={credit.titleId}
|
||||||
tmdbId={credit.tmdbId}
|
tmdbId={credit.tmdbId}
|
||||||
@@ -128,7 +140,7 @@ export default function PersonDetailScreen() {
|
|||||||
releaseDate={credit.releaseDate ?? credit.firstAirDate}
|
releaseDate={credit.releaseDate ?? credit.firstAirDate}
|
||||||
voteAverage={credit.voteAverage}
|
voteAverage={credit.voteAverage}
|
||||||
userStatus={userStatuses[credit.titleId] ?? null}
|
userStatus={userStatuses[credit.titleId] ?? null}
|
||||||
width={undefined}
|
width={columnWidth}
|
||||||
onPress={handlePress}
|
onPress={handlePress}
|
||||||
onQuickAdd={handleQuickAdd}
|
onQuickAdd={handleQuickAdd}
|
||||||
isAdding={addingKey === `${credit.tmdbId}-${credit.type}`}
|
isAdding={addingKey === `${credit.tmdbId}-${credit.type}`}
|
||||||
@@ -360,13 +372,14 @@ export default function PersonDetailScreen() {
|
|||||||
data={filmography}
|
data={filmography}
|
||||||
keyExtractor={(item) => item.titleId}
|
keyExtractor={(item) => item.titleId}
|
||||||
renderItem={renderFilmographyItem}
|
renderItem={renderFilmographyItem}
|
||||||
numColumns={2}
|
numColumns={filmographyColumns}
|
||||||
|
showsVerticalScrollIndicator={false}
|
||||||
contentInsetAdjustmentBehavior={
|
contentInsetAdjustmentBehavior={
|
||||||
useAutomaticInsets ? "automatic" : "never"
|
useAutomaticInsets ? "automatic" : "never"
|
||||||
}
|
}
|
||||||
contentContainerStyle={{
|
contentContainerStyle={{
|
||||||
paddingBottom: useAutomaticInsets ? 32 : insets.bottom + 32,
|
paddingBottom: useAutomaticInsets ? 32 : insets.bottom + 32,
|
||||||
paddingHorizontal: FILMOGRAPHY_PADDING,
|
paddingHorizontal: FILMOGRAPHY_PADDING - FILMOGRAPHY_GUTTER,
|
||||||
}}
|
}}
|
||||||
ListHeaderComponent={listHeader}
|
ListHeaderComponent={listHeader}
|
||||||
onEndReached={() => {
|
onEndReached={() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user