From 91a42e6e293f9e7d4fd8dcfbbe4db5d98b481a4a Mon Sep 17 00:00:00 2001 From: tapframe Date: Wed, 5 Nov 2025 20:08:12 +0530 Subject: [PATCH] ui fix --- src/components/home/HeroCarousel.tsx | 60 ++++++++++++++++------------ src/screens/HomeScreenSettings.tsx | 10 +++++ 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/components/home/HeroCarousel.tsx b/src/components/home/HeroCarousel.tsx index 4a5f3c9f..468b7fe4 100644 --- a/src/components/home/HeroCarousel.tsx +++ b/src/components/home/HeroCarousel.tsx @@ -68,6 +68,9 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = const interval = useMemo(() => cardWidth + 16, [cardWidth]); + // Reduce top padding on phones while keeping tablets unchanged + const effectiveTopOffset = useMemo(() => (isTablet ? TOP_TABS_OFFSET : 8), [isTablet]); + const data = useMemo(() => (items && items.length ? items.slice(0, 10) : []), [items]); const loopingEnabled = data.length > 1; // Duplicate head/tail for seamless looping @@ -241,7 +244,7 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = if (loading) { return ( - }> + }> = ({ items, loading = false }) = pointerEvents="none" > {Platform.OS === 'android' ? ( @@ -351,7 +353,7 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = return ( - + {/* Removed preload images for performance - let FastImage cache handle it naturally */} {settings.enableHomeHeroBackground && data[activeIndex] && ( = ({ items, loading = false }) = pagingEnabled={false} bounces={false} overScrollMode="never" - onMomentumScrollEnd={() => { + onMomentumScrollEnd={(e) => { if (!loopingEnabled) return; // Determine current page index in cloned space - const page = Math.round(scrollX.value / interval); + const x = e?.nativeEvent?.contentOffset?.x ?? 0; + const page = Math.round(x / interval); // If at leading clone (0), jump to last real item if (page === 0) { scrollToLogicalIndex(data.length - 1, false); @@ -398,7 +401,7 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = > {(loopingEnabled ? loopData : data).map((item, index) => ( = ({ items, loading = false }) = ))} - {/* Pagination below the card row (animated like FeaturedContent) */} + {/* Pagination below the card row (library-based, worklet-driven) */} - = ({ items, loading = false }) = height: 8, borderRadius: 999, backgroundColor: currentTheme.colors.elevation3, - opacity: 0.9, }} activeDotStyle={{ width: 10, @@ -440,15 +442,6 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = onPress={(index: number) => { scrollToLogicalIndex(index, true); }} - customReanimatedStyle={(p: number, index: number, length: number) => { - 'worklet'; - let v = Math.abs(p - index); - if (index === 0 && p > length - 1) { - v = Math.abs(p - length); - } - const scale = interpolate(v, [0, 1], [1.2, 1], Extrapolation.CLAMP); - return { transform: [{ scale }] }; - }} /> @@ -570,8 +563,8 @@ const CarouselCard: React.FC = memo(({ item, colors, logoFail // AGGRESSIVE early exit for cards far from center if (distance > interval * 1.5) { return { - transform: [{ scale: 0.9 }], - opacity: 0.7 + transform: [{ scale: isTablet ? 0.95 : 0.9 }], + opacity: isTablet ? 0.85 : 0.7 }; } @@ -579,11 +572,11 @@ const CarouselCard: React.FC = memo(({ item, colors, logoFail // Scale animation based on distance from center const scale = 1 - (distance / maxDistance) * 0.1; - const clampedScale = Math.max(0.9, Math.min(1, scale)); + const clampedScale = Math.max(isTablet ? 0.95 : 0.9, Math.min(1, scale)); // Opacity animation for cards that are far from center const opacity = 1 - (distance / maxDistance) * 0.3; - const clampedOpacity = Math.max(0.7, Math.min(1, opacity)); + const clampedOpacity = Math.max(isTablet ? 0.85 : 0.7, Math.min(1, opacity)); return { transform: [{ scale: clampedScale }], @@ -677,7 +670,7 @@ const CarouselCard: React.FC = memo(({ item, colors, logoFail /> @@ -703,7 +696,16 @@ const CarouselCard: React.FC = memo(({ item, colors, logoFail )} - + {item.description || 'No description available'} @@ -811,7 +813,15 @@ const CarouselCard: React.FC = memo(({ item, colors, logoFail )} - + {item.description || 'No description available'} diff --git a/src/screens/HomeScreenSettings.tsx b/src/screens/HomeScreenSettings.tsx index 20150634..77e5fb48 100644 --- a/src/screens/HomeScreenSettings.tsx +++ b/src/screens/HomeScreenSettings.tsx @@ -115,6 +115,7 @@ const HomeScreenSettings: React.FC = () => { const navigation = useNavigation>(); const [showSavedIndicator, setShowSavedIndicator] = useState(false); const fadeAnim = React.useRef(new Animated.Value(0)).current; + const isTabletDevice = Platform.OS !== 'web' && (Dimensions.get('window').width >= 768); // Prevent iOS entrance flicker by restoring a non-translucent StatusBar useFocusEffect( @@ -162,6 +163,15 @@ const HomeScreenSettings: React.FC = () => { setShowSavedIndicator(true); }, [updateSetting]); + // Ensure carousel is the default hero layout on tablets for all users + useEffect(() => { + try { + if (isTabletDevice && settings.heroStyle !== 'carousel') { + updateSetting('heroStyle', 'carousel' as any); + } + } catch {} + }, [isTabletDevice, settings.heroStyle, updateSetting]); + const CustomSwitch = ({ value, onValueChange }: { value: boolean, onValueChange: (value: boolean) => void }) => (