Loading mobile/src/common/components/rating_page/star_rating_form.tsx 0 → 100644 +94 −0 Original line number Diff line number Diff line import AntDesign from "@expo/vector-icons/AntDesign"; import { View, StyleSheet, Animated } from "react-native"; import { TouchableOpacity } from "react-native-gesture-handler"; import { LIGHT_THEME } from "../../constants/theme"; import { useEffect, useRef, useState } from "react"; import { use } from "i18next"; interface StarRatingFormProps { maxRating: number; onRatingChange: (rating: number) => void; } export const StarRatingForm = ({ maxRating, onRatingChange, }: StarRatingFormProps) => { const [rating, setRating] = useState(0); const danceRef = useRef(new Animated.Value(0)).current; useEffect(() => { Animated.sequence([ Animated.timing(danceRef, { toValue: 10, duration: 100, useNativeDriver: true, }), Animated.timing(danceRef, { toValue: -10, duration: 100, useNativeDriver: true, }), Animated.timing(danceRef, { toValue: 0, duration: 100, useNativeDriver: true, }), ]).start(); }, [rating]); const handleOnPress = (index: number) => { setRating(index + 1); onRatingChange(index + 1); }; return ( <View style={styles.mainView}> {Array.from({ length: maxRating }).map((_, index) => { return ( <TouchableOpacity onPress={() => handleOnPress(index)}> <Animated.View style={[ index < rating ? { transform: [ { rotate: danceRef.interpolate({ inputRange: [-10, 10], outputRange: ["-10deg", "10deg"], }), }, ], } : {}, ]} > <AntDesign key={`star-${index}`} name={index < rating ? "star" : "staro"} size={42} color={ index < rating ? LIGHT_THEME.color.primary : LIGHT_THEME.color.secondary } onPress={() => onRatingChange(index + 1)} /> </Animated.View> </TouchableOpacity> ); })} </View> ); }; const styles = StyleSheet.create({ mainView: { display: "flex", flexDirection: "row", justifyContent: "space-around", alignItems: "center", width: "80%", alignSelf: "center", height: 70, zIndex: 10, }, }); Loading
mobile/src/common/components/rating_page/star_rating_form.tsx 0 → 100644 +94 −0 Original line number Diff line number Diff line import AntDesign from "@expo/vector-icons/AntDesign"; import { View, StyleSheet, Animated } from "react-native"; import { TouchableOpacity } from "react-native-gesture-handler"; import { LIGHT_THEME } from "../../constants/theme"; import { useEffect, useRef, useState } from "react"; import { use } from "i18next"; interface StarRatingFormProps { maxRating: number; onRatingChange: (rating: number) => void; } export const StarRatingForm = ({ maxRating, onRatingChange, }: StarRatingFormProps) => { const [rating, setRating] = useState(0); const danceRef = useRef(new Animated.Value(0)).current; useEffect(() => { Animated.sequence([ Animated.timing(danceRef, { toValue: 10, duration: 100, useNativeDriver: true, }), Animated.timing(danceRef, { toValue: -10, duration: 100, useNativeDriver: true, }), Animated.timing(danceRef, { toValue: 0, duration: 100, useNativeDriver: true, }), ]).start(); }, [rating]); const handleOnPress = (index: number) => { setRating(index + 1); onRatingChange(index + 1); }; return ( <View style={styles.mainView}> {Array.from({ length: maxRating }).map((_, index) => { return ( <TouchableOpacity onPress={() => handleOnPress(index)}> <Animated.View style={[ index < rating ? { transform: [ { rotate: danceRef.interpolate({ inputRange: [-10, 10], outputRange: ["-10deg", "10deg"], }), }, ], } : {}, ]} > <AntDesign key={`star-${index}`} name={index < rating ? "star" : "staro"} size={42} color={ index < rating ? LIGHT_THEME.color.primary : LIGHT_THEME.color.secondary } onPress={() => onRatingChange(index + 1)} /> </Animated.View> </TouchableOpacity> ); })} </View> ); }; const styles = StyleSheet.create({ mainView: { display: "flex", flexDirection: "row", justifyContent: "space-around", alignItems: "center", width: "80%", alignSelf: "center", height: 70, zIndex: 10, }, });