Skip to content

Commit

Permalink
refactor: make module monolothic and extend swipe
Browse files Browse the repository at this point in the history
  • Loading branch information
frknltrk committed Aug 14, 2023
1 parent e6ef243 commit ac0afde
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 130 deletions.
42 changes: 27 additions & 15 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,41 @@ import React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { SwipeableDeck } from '@frknltrk/react-native-swipeable-cards';

const data = [
<Text key="1">Card 1 Content</Text>,
<Text key="2">Card 2</Text>,
<View key="3">
<Text>Custom View</Text>
<Text>More Custom Content</Text>
</View>,
// Add more custom content as needed
];

const App: React.FC = () => {
return (
<View style={styles.container}>
<SwipeableDeck card_contents={data} />
</View>
);
const data = [
<View key="1" style={styles.card}>
<Text>Card 1 Content</Text>
</View>,
<View key="2" style={styles.card}>
<Text>Card 2 Content</Text>
</View>,
<View key="3" style={styles.card}>
<Text>Card 3 Content</Text>
</View>,
// Add more custom content as needed
];

return <SwipeableDeck data={data} />;
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
card: {
width: 300,
height: 200,
backgroundColor: 'lightgray',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
borderWidth: 1,
borderColor: 'gray',
marginVertical: 10,
},
});

export default App;
92 changes: 0 additions & 92 deletions src/Card.tsx

This file was deleted.

108 changes: 85 additions & 23 deletions src/Deck.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,116 @@
import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import CardView from './Card';
import {
View,
Animated,
PanResponder,
Dimensions,
StyleSheet,
} from 'react-native';

interface DeckProps {
card_contents: React.ReactNode[]; // Allow any ReactNode as content
const SCREEN_WIDTH = Dimensions.get('window').width;
const SWIPE_THRESHOLD = 0.25 * SCREEN_WIDTH;
const SWIPE_OUT_DURATION = 250;

interface SwipeableDeckProps {
data: React.ReactNode[];
}

const SwipeableDeck: React.FC<DeckProps> = ({ card_contents }) => {
const SwipeableDeck: React.FC<SwipeableDeckProps> = ({ data }) => {
const [currentIndex, setCurrentIndex] = useState(0);

const position = new Animated.ValueXY();

const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (_, gesture) => {
position.setValue({ x: gesture.dx, y: gesture.dy });
},
onPanResponderRelease: (_, gesture) => {
if (gesture.dx > SWIPE_THRESHOLD) {
forceSwipe('right');
} else if (gesture.dx < -SWIPE_THRESHOLD) {
forceSwipe('left');
} else {
resetPosition();
}
},
});

const forceSwipe = (direction: 'right' | 'left') => {
const x = direction === 'right' ? SCREEN_WIDTH : -SCREEN_WIDTH;
Animated.timing(position, {
toValue: { x, y: 0 },
duration: SWIPE_OUT_DURATION,
useNativeDriver: false,
}).start(() => onSwipeComplete(direction));
};

const onSwipeComplete = (direction: 'right' | 'left') => {
direction === 'right' ? onSwipeRight() : onSwipeLeft();
position.setValue({ x: 0, y: 0 });
};

const resetPosition = () => {
Animated.spring(position, {
toValue: { x: 0, y: 0 },
useNativeDriver: false,
}).start();
};

const getCardStyle = () => {
const rotate = position.x.interpolate({
inputRange: [-SCREEN_WIDTH, 0, SCREEN_WIDTH],
outputRange: ['-60deg', '0deg', '60deg'],
});

return {
...position.getLayout(),
transform: [{ rotate }],
};
};

const onSwipeLeft = () => {
if (currentIndex < card_contents.length - 1) {
setCurrentIndex((prevIndex: number) => prevIndex + 1);
console.log('Deck.onSwipeLeft works');
if (currentIndex < data.length - 1) {
setCurrentIndex((prevIndex) => prevIndex + 1);
} else {
// Optional: Implement what happens when you reach the end of the deck
// For example, you can reset the currentIndex to 0 to start over.
setCurrentIndex(0);
}
};

const onSwipeRight = () => {
if (currentIndex > 0) {
setCurrentIndex((prevIndex: number) => prevIndex - 1);
console.log('Deck.onSwipeRight works');
} else {
// Optional: Implement what happens when you reach the beginning of the deck
// For example, you can disable swiping to the left or show a message.
setCurrentIndex((prevIndex) => prevIndex - 1);
}
};

// avoid using Non-null assertion operator (!): line 36. find another way to overcome TS2322
return (
<View style={styles.deckContainer}>
<CardView
<View style={styles.deckContainer} {...panResponder.panHandlers}>
<Animated.View
key={currentIndex}
onSwipeLeft={onSwipeLeft}
onSwipeRight={onSwipeRight}
style={[styles.cardStyle, getCardStyle()]}
>
{card_contents[currentIndex]}
</CardView>
{data[currentIndex]}
</Animated.View>
</View>
);
};

const styles = StyleSheet.create({
deckContainer: {
flex: 1,
width: SCREEN_WIDTH,
height: '100%',
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
backgroundColor: 'yellow',
},
cardStyle: {
width: 'auto',
height: 'auto',
alignItems: 'center',
justifyContent: 'center',
userSelect: 'none',
backgroundColor: 'black',
},
});

Expand Down

0 comments on commit ac0afde

Please sign in to comment.