-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReactIconButton.tsx
132 lines (123 loc) · 3.56 KB
/
ReactIconButton.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* eslint-disable indent */
import React, { useState, useRef, useEffect, useMemo } from 'react';
import { Animated, Easing } from 'react-native';
import { SvgXml } from 'react-native-svg';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Pressable, Text, StyleSheet } from 'react-native';
import { InsightAPI } from '../../utils/api/InsightAPI';
import { FlyingView, ObjectConfig } from 'react-native-flying-objects';
import theme from '../../theme/light';
interface ReactIconButtonProps {
xml: string;
color: string;
taps?: number;
name: string;
clicked: boolean;
insightId: number;
}
const ReactIconButton = ({ xml, color, taps, name, clicked, insightId }: ReactIconButtonProps) => {
const opacityValue = useRef(new Animated.Value(0)).current;
const [object, setObject] = useState<ObjectConfig[]>([]);
const [text, setText] = useState<number>();
const [tab, setTab] = useState<boolean>(false);
const { mutate: insightReact } = useMutation(InsightAPI.react, {
onSuccess: (response) => {
setText(response?.data.count);
setTab(true);
},
});
useEffect(() => {
setText(taps ?? 0);
}, [taps]);
const handleClick = () => {
insightReact({ insightId, reactionType: name, value: 1 });
setObject((prev) => [...prev, objectConfig]);
Animated.timing(opacityValue, {
toValue: 1,
duration: 0,
useNativeDriver: false,
}).start();
Animated.timing(opacityValue, {
toValue: 0,
duration: 750,
useNativeDriver: false,
}).start();
};
const objectConfig = useMemo(
() => ({
object: <SvgXml xml={xml} height={20} width={20} />,
right: {
fromValue: 15,
toValue: Math.floor(Math.random() * 30),
duration: 1200,
easing: Easing.bezier(
Math.floor(Math.random() * 10) / 10,
Math.floor(Math.random() * 10) / 10 + 0.7,
Math.floor(Math.random() * 10) / 10,
Math.floor(Math.random() * 10) / 10 + 0.7,
),
},
top: {
fromValue: 100,
toValue: 35,
duration: 1200,
easing: Easing.bezier(0.5, 1.0, 0.5, 1.0),
},
show: {},
hide: {},
}),
[object],
);
return (
<>
<Pressable onPress={handleClick}>
<Animated.View
style={{
backgroundColor:
clicked || tab
? color
: opacityValue.interpolate({
inputRange: [0, 1],
outputRange: [theme.colors.graphic.white, color],
}),
padding: 8,
marginTop: 12,
...styles.Button,
}}
>
<SvgXml xml={xml} />
{text !== 0 && (
<Animated.Text
style={{
color: opacityValue.interpolate({
inputRange: [0, 1],
outputRange: [theme.colors.graphic.black, theme.colors.graphic.white],
}),
marginLeft: 4,
fontFamily: 'podkovaBold',
fontSize: 14,
lineHeight: 16,
}}
>
<Text>{text}</Text>
</Animated.Text>
)}
</Animated.View>
<FlyingView
object={object}
containerProps={{ style: { position: 'absolute', bottom: 20 } }}
/>
</Pressable>
</>
);
};
const styles = StyleSheet.create({
Button: {
display: 'flex',
justifyContent: 'center',
flexDirection: 'row',
borderRadius: 40,
marginRight: 8,
},
});
export default ReactIconButton;