Skip to content

Instantly share code, notes, and snippets.

@kedarshenoy
Created August 2, 2024 18:49
Show Gist options
  • Save kedarshenoy/cbc3097ec41706b0c19c58dd3523d567 to your computer and use it in GitHub Desktop.
Save kedarshenoy/cbc3097ec41706b0c19c58dd3523d567 to your computer and use it in GitHub Desktop.
this is main Stack
import React, { useState, useRef, useEffect, useCallback } from 'react';
import { View, StyleSheet, Animated, useWindowDimensions } from 'react-native';
import { PanGestureHandler, ScrollView, State } from 'react-native-gesture-handler';
const ROTATION = 60;
const SWIPE_VELOCITY = 800;
const QUICK_PUSH_VELOCITY = 1000;
const DealsAIStack = ({ data, renderItem, onSwipeRight, onSwipeLeft, onQuickPush }) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [nextIndex, setNextIndex] = useState(1);
const currentProfile = data[currentIndex];
const nextProfile = data[nextIndex];
const { width: screenWidth } = useWindowDimensions();
const hiddenTranslateX = 2 * screenWidth;
const translateX = useRef(new Animated.Value(0)).current;
const [top,setTop]=useState(false);
const rotate = translateX.interpolate({
inputRange: [-hiddenTranslateX, 0, hiddenTranslateX],
outputRange: [`-${ROTATION}deg`, '0deg', `${ROTATION}deg`],
});
const cardStyle = {
transform: [
{ translateX },
{ rotate },
],
};
const nextCardStyle = {
opacity: translateX.interpolate({
inputRange: [-hiddenTranslateX, 0, hiddenTranslateX],
outputRange: [1, 0.5, 1],
}),
transform: [
{
scale: translateX.interpolate({
inputRange: [-hiddenTranslateX, 0, hiddenTranslateX],
outputRange: [1, 0, 1],
extrapolate: 'clamp',
}),
},
],
};
const onGestureEvent = Animated.event(
[{ nativeEvent: { translationX: translateX } }],
{ useNativeDriver: true }
);
const onHandlerStateChange = useCallback((event) => {
if (event.nativeEvent.state === State.END) {
const { velocityX, velocityY, translationX } = event.nativeEvent;
if (Math.abs(velocityX) > QUICK_PUSH_VELOCITY && Math.abs(velocityX) > Math.abs(velocityY)) {
// Handle quick push horizontally
onQuickPush && onQuickPush(currentProfile);
Animated.spring(translateX, {
toValue: hiddenTranslateX * Math.sign(velocityX),
useNativeDriver: true,
}).start(() => {
setNextCard();
});
return;
}
if (Math.abs(velocityX) < SWIPE_VELOCITY || Math.abs(velocityY) > Math.abs(velocityX)) {
// Handle vertical scroll or slow swipe
Animated.spring(translateX, {
toValue: 0,
useNativeDriver: true,
}).start();
return;
}
Animated.spring(translateX, {
toValue: hiddenTranslateX * Math.sign(velocityX),
useNativeDriver: true,
}).start(() => {
const onSwipe = velocityX > 0 ? onSwipeRight : onSwipeLeft;
onSwipe && onSwipe(currentProfile);
setNextCard();
});
}
}, [currentProfile, hiddenTranslateX, onQuickPush, onSwipeLeft, onSwipeRight, translateX]);
const setNextCard = useCallback(() => {
setCurrentIndex((prevIndex) =>
{
return prevIndex + 1});
translateX.setValue(0);
}, [translateX]);
useEffect(() => {
setNextIndex(currentIndex + 1);
}, [currentIndex]);
return (
<View style={styles.root}>
{nextProfile && (
<View style={styles.nextCardContainer}>
<Animated.View style={[styles.animatedCard, nextCardStyle]}>
{renderItem({ item: nextProfile,top:top })}
</Animated.View>
</View>
)}
{currentProfile && (
<PanGestureHandler
onGestureEvent={onGestureEvent}
onHandlerStateChange={onHandlerStateChange}
activeOffsetY={[-20, 20]} // Adjust this to allow vertical quick pushes
activeOffsetX={[-10, 10]} // This ensures horizontal swipes are detected
>
<Animated.View style={[styles.animatedCard, cardStyle]}>
{/* <ScrollView ref={(ref) => (scrollViewRef.current[currentIndex] = ref)}> */}
{renderItem({ item: currentProfile,top:top})}
{/* </ScrollView> */}
</Animated.View>
</PanGestureHandler>
)}
</View>
);
};
const styles = StyleSheet.create({
root: {
flex: 1,
// width: '100%',
height: 700,
// borderWidth:2,
// borderColor:'black'
// top: 10
},
animatedCard: {
// justifyContent: 'center',
},
nextCardContainer: {
...StyleSheet.absoluteFillObject,
justifyContent: 'center',
// alignItems: 'center',
},
});
export default DealsAIStack;
--------------------------------------------------------------------------------------------------------------------------------
This is render item/card
import { StyleSheet, View, ScrollView } from 'react-native';
import React, { useRef, useEffect } from 'react';
import DealsAiProduct from './DealsAiProduct';
import DealsAiProductDesc from './DealsAiProductDesc';
import { FlatList } from 'react-native-gesture-handler';
export default function DealsAIWrapper({ product }) {
const scrollViewRef = useRef(null);
const products = [product];
const renderItem = ({ item }) => <DealsAiProduct product={item} />;
const flatListRef = useRef(null);
// Define the key extractor function
const keyExtractor = (item) => "fgrfdrh";
// useEffect(() => {
// // if (scrollViewRef.current) {
// scrollViewRef.current.scrollTo({ y: 0, animated: true });
// // }
// if(scrollViewRef.current.y >0 ){
// console.log("not at begining ")
// }
// }, [product]);
// useEffect(() => {
// // Scroll to the top whenever the product changes
// if (flatListRef.current) {
// flatListRef.current.scrollToOffset({ offset: 0, animated: true });
// }
// }, [product]);
useEffect(() => {
// Scroll to the top whenever the `top` prop changes
if (flatListRef.current && top) {
flatListRef.current.scrollToOffset({ offset: 0, animated: true });
}
}, [top]);
return (
<View style={styles.container}>
<ScrollView ref={scrollViewRef}>
<DealsAiProduct product={product} />
</ScrollView>
{/* <FlatList
ref={flatListRef}
data={products} // Pass the single item array
renderItem={renderItem} // Render function for each item
keyExtractor={keyExtractor} // Key extractor for each item
/> */}
</View>
);
}
const styles = StyleSheet.create({
container: {
// width: '100%',
height: '100%',
// borderRadius: 10,
// shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 5,
justifyContent: 'center',
alignItems: 'center',
// padding: 10,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment