-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGmailStyleSwipeableRow.tsx
118 lines (107 loc) · 3.25 KB
/
GmailStyleSwipeableRow.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { Ionicons } from "@expo/vector-icons";
import React, { Component, PropsWithChildren } from "react";
import { Animated, StyleSheet, I18nManager, View, Text } from "react-native";
import { RectButton } from "react-native-gesture-handler";
import Swipeable from "react-native-gesture-handler/Swipeable";
import { FavouritesPokemonsContext } from "./contexts/FavouritesContext";
import { Pokemon } from "./pokemons/Pokemons";
import { pokeGrey } from "./Styles";
const AnimatedView = Animated.createAnimatedComponent(View);
export default class GmailStyleSwipeableRow extends Component<
PropsWithChildren<{ pokemon: Pokemon }>
> {
context!: React.ContextType<typeof FavouritesPokemonsContext>;
static contextType = FavouritesPokemonsContext;
private renderLeftActions = (
_progress: Animated.AnimatedInterpolation,
dragX: Animated.AnimatedInterpolation
) => {
const scale = dragX.interpolate({
inputRange: [0, 80],
outputRange: [0, 1],
extrapolate: "clamp",
});
if (!this.context.isInFavourites(this.props.pokemon)) {
return undefined;
} else {
return (
<RectButton style={styles.leftAction} onPress={this.close}>
<AnimatedView style={[styles.actionIcon, { transform: [{ scale }] }]}>
<Text>
<Ionicons name={"ios-heart-outline"} size={30} color={pokeGrey} />
</Text>
</AnimatedView>
</RectButton>
);
}
};
private renderRightActions = (
_progress: Animated.AnimatedInterpolation,
dragX: Animated.AnimatedInterpolation
) => {
const scale = dragX.interpolate({
inputRange: [-80, 0],
outputRange: [1, 0],
extrapolate: "clamp",
});
if (this.context.isInFavourites(this.props.pokemon)) {
return undefined;
} else {
return (
<RectButton style={styles.rightAction} onPress={this.close}>
<AnimatedView style={[styles.actionIcon, { transform: [{ scale }] }]}>
<Text>
<Ionicons name={"ios-heart"} size={30} color={pokeGrey} />
</Text>
</AnimatedView>
</RectButton>
);
}
};
private swipeableRow?: Swipeable;
private updateRef = (ref: Swipeable) => {
this.swipeableRow = ref;
};
private close = () => {
this.swipeableRow?.close();
};
addOrRemoveFromFavourites = () => {
this.context.addOrRemoveFromFavourites(this.props.pokemon);
};
render() {
const { children } = this.props;
return (
<Swipeable
ref={this.updateRef}
friction={2}
leftThreshold={80}
enableTrackpadTwoFingerGesture
rightThreshold={40}
onSwipeableOpen={this.addOrRemoveFromFavourites}
renderLeftActions={this.renderLeftActions}
renderRightActions={this.renderRightActions}
>
{children}
</Swipeable>
);
}
}
const styles = StyleSheet.create({
leftAction: {
flex: 1,
justifyContent: "flex-end",
alignItems: "center",
flexDirection: I18nManager.isRTL ? "row" : "row-reverse",
},
actionIcon: {
width: 120,
marginHorizontal: 10,
height: 40,
},
rightAction: {
alignItems: "center",
flexDirection: I18nManager.isRTL ? "row-reverse" : "row",
flex: 1,
justifyContent: "flex-end",
},
});