File size: 2,874 Bytes
0bedb61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React from 'react';
import { StyleSheet, Text, Pressable } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
  withSequence,
  withTiming,
} from 'react-native-reanimated';
import { COLORS } from '../constants/colors';

interface AnswerButtonProps {
  answer: number;
  index: number;
  onPress: (answer: number) => void;
  disabled: boolean;
  isCorrect?: boolean | null;
}

export const AnswerButton: React.FC<AnswerButtonProps> = ({

  answer,

  index,

  onPress,

  disabled,

  isCorrect,

}) => {
  const scale = useSharedValue(1);
  const shake = useSharedValue(0);

  const handlePress = () => {
    if (disabled) return;
    scale.value = withSpring(0.94, { damping: 12, stiffness: 300 }, () => {
      scale.value = withSpring(1, { damping: 10, stiffness: 200 });
    });
    onPress(answer);
  };

  React.useEffect(() => {
    if (isCorrect === false) {
      shake.value = withSequence(
        withTiming(-6, { duration: 40 }),
        withTiming(6, { duration: 40 }),
        withTiming(-6, { duration: 40 }),
        withTiming(6, { duration: 40 }),
        withTiming(0, { duration: 40 })
      );
    } else if (isCorrect === true) {
      scale.value = withSequence(
        withSpring(1.08, { damping: 6, stiffness: 200 }),
        withSpring(1, { damping: 10, stiffness: 200 })
      );
    }
  }, [isCorrect]);

  const animStyle = useAnimatedStyle(() => ({
    transform: [
      { scale: scale.value },
      { translateX: shake.value },
    ],
  }));

  const bgColor =
    isCorrect === true
      ? COLORS.success
      : isCorrect === false
      ? COLORS.error
      : COLORS.surfaceLight;

  const borderColor =
    isCorrect === true
      ? COLORS.success
      : isCorrect === false
      ? COLORS.error
      : COLORS.borderLight;

  const textColor =
    isCorrect === true
      ? COLORS.success
      : isCorrect === false
      ? COLORS.error
      : COLORS.text;

  return (
    <Animated.View style={[styles.container, animStyle]}>

      <Pressable

        onPress={handlePress}

        disabled={disabled}

        style={[

          styles.button,

          {

            backgroundColor: isCorrect !== null ? bgColor + '18' : COLORS.surface,

            borderColor: borderColor,

          },

        ]}

      >

        <Text style={[styles.text, { color: textColor }]}>{answer}</Text>

      </Pressable>

    </Animated.View>
  );
};

const styles = StyleSheet.create({
  container: {
    width: '48%',
    marginVertical: 5,
  },
  button: {
    borderRadius: 12,
    borderWidth: 1.5,
    paddingVertical: 18,
    alignItems: 'center',
    justifyContent: 'center',
  },
  text: {
    fontSize: 26,
    fontWeight: '800',
    fontVariant: ['tabular-nums'],
  },
});