Skip to content

Instantly share code, notes, and snippets.

@ntta
Created June 28, 2020 08:40
Show Gist options
  • Save ntta/4e3e88aee49517438954d12a7894b26c to your computer and use it in GitHub Desktop.
Save ntta/4e3e88aee49517438954d12a7894b26c to your computer and use it in GitHub Desktop.
import React from 'react';
import { StyleSheet, View, Dimensions } from 'react-native';
import { Thumbnail } from 'native-base';
import Animated, {
abs,
add,
call,
clockRunning,
cond,
eq,
not,
set,
useCode,
} from 'react-native-reanimated';
import {
PanGestureHandler,
State,
TouchableWithoutFeedback,
TouchableOpacity,
} from 'react-native-gesture-handler';
import {
snapPoint,
timing,
useClock,
usePanGestureHandler,
useValue,
min,
} from 'react-native-redash';
import CustomText from '../basic/CustomText';
import Action from './Action';
const HEIGHT = Dimensions.get('window').height < 600 ? 70 : 80;
const { width } = Dimensions.get('window');
const snapPoints = [-100, 0];
const ShoppingListProductCard = ({
product,
removeFromWishlist,
navigation,
}) => {
const {
gestureHandler,
translation,
velocity,
state,
} = usePanGestureHandler();
const translateX = useValue(0);
const offsetX = useValue(0);
const height = useValue(HEIGHT);
const deleteOpacity = useValue(1);
const clock = useClock();
const to = snapPoint(translateX, velocity.x, snapPoints);
const shouldRemove = useValue(0);
useCode(
() => [
cond(
eq(state, State.ACTIVE),
set(translateX, add(offsetX, min(translation.x, 0)))
),
cond(eq(state, State.END), [
set(translateX, timing({ clock, from: translateX, to })),
set(offsetX, translateX),
cond(eq(to, -width), set(shouldRemove, 1)),
]),
cond(shouldRemove, [
set(height, timing({ from: HEIGHT, to: 0 })),
set(deleteOpacity, 0),
cond(
not(clockRunning(clock)),
call([], () => {
removeFromWishlist(product.id);
})
),
]),
],
[]
);
return (
<Animated.View>
<View style={styles.background}>
<TouchableWithoutFeedback onPress={() => shouldRemove.setValue(1)}>
<Action x={abs(translateX)} {...{ deleteOpacity }} />
</TouchableWithoutFeedback>
</View>
<PanGestureHandler {...gestureHandler}>
<Animated.View style={{ height, transform: [{ translateX }] }}>
<TouchableOpacity
onPress={() => {
navigation.navigate('Product Detail', { product });
}}
>
<View style={styles.view}>
<View style={styles.viewThumbnail}>
<Thumbnail small source={{ uri: product.imagePath }} />
</View>
<View style={styles.viewQuantity}>
<CustomText style={styles.textName}>1 x</CustomText>
</View>
<View style={styles.viewName}>
<CustomText
textType="medium"
style={styles.textName}
numberOfLines={3}
>
{product.name}
</CustomText>
</View>
<View style={styles.viewPrice}>
<CustomText textType="medium" style={styles.textPrice}>
${product.price.toFixed(2)}
</CustomText>
</View>
</View>
</TouchableOpacity>
</Animated.View>
</PanGestureHandler>
</Animated.View>
);
};
const styles = StyleSheet.create({
background: {
...StyleSheet.absoluteFillObject,
backgroundColor: '#000',
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
overflow: 'hidden',
},
view: {
flex: 1,
height: HEIGHT,
flexDirection: 'row',
alignItems: 'center',
marginHorizontal: 10,
},
viewThumbnail: {
flex: 1,
alignItems: 'center',
},
viewQuantity: {
alignItems: 'center',
flex: 1,
},
viewName: {
marginRight: 5,
flex: 5,
},
viewPrice: {
flex: 2,
alignItems: 'center',
},
textName: {
color: '#fff',
fontSize: 15,
},
textPrice: {
color: 'grey',
},
});
export default ShoppingListProductCard;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment