react-native-album-display 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,198 @@
1
+ import React, { useState, useEffect, useMemo } from 'react';
2
+ import { View, Text, StyleSheet, PanResponder, Animated, Button } from 'react-native';
3
+ import { BarChart } from 'react-native-chart-kit';
4
+ import { Dimensions } from 'react-native';
5
+ import StarRating from 'react-native-star-rating-widget';
6
+
7
+ const screenWidth = Dimensions.get('window').width;
8
+
9
+ const RatingHistogram = ({ ratings, setRatings }) => {
10
+ const [userRating, setUserRating] = useState(null);
11
+ const scaleAnim = useMemo(() => new Animated.Value(1), []);
12
+ const ratingCounts = Array(11).fill(0);
13
+ let totalRatings = 0;
14
+ let sumRatings = 0;
15
+
16
+ useEffect(() => {
17
+ const totalRatings = ratings.length;
18
+ const sumRatings = ratings.reduce((sum, rating) => sum + rating, 0);
19
+ setDisplayValue(totalRatings > 0 ? (sumRatings / totalRatings).toFixed(2) : 'N/A');
20
+ }, [ratings]);
21
+
22
+
23
+ ratings.forEach(rating => {
24
+ const index = Math.round(rating * 2);
25
+ ratingCounts[index] += 1;
26
+ sumRatings += rating;
27
+ totalRatings += 1;
28
+ });
29
+
30
+ const averageRating = totalRatings > 0 ? (sumRatings / totalRatings).toFixed(2) : 'N/A';
31
+ const [displayValue, setDisplayValue] = useState(averageRating);
32
+ const [selectedStarValue, setSelectedStarValue] = useState(0);
33
+
34
+ const barWidth = (screenWidth - 40) / 11;
35
+
36
+ const panResponder = PanResponder.create({
37
+ onStartShouldSetPanResponder: () => true,
38
+ onPanResponderMove: (event, gestureState) => {
39
+ const touchX = gestureState.moveX - 50;
40
+ const index = Math.floor(touchX / barWidth);
41
+ if (index >= 0 && index < ratingCounts.length) {
42
+ setDisplayValue(ratingCounts[index]);
43
+ setSelectedStarValue((index / 2).toFixed(1));
44
+ }
45
+ },
46
+ onPanResponderRelease: () => {
47
+ setDisplayValue(averageRating);
48
+ setSelectedStarValue(0);
49
+ },
50
+ });
51
+
52
+ const data = {
53
+ labels: Array(11).fill(''),
54
+ datasets: [{
55
+ data: ratingCounts,
56
+ }],
57
+ };
58
+
59
+ const animateRating = () => {
60
+ Animated.sequence([
61
+ Animated.timing(scaleAnim, {
62
+ toValue: 1.2,
63
+ duration: 150,
64
+ useNativeDriver: true,
65
+ }),
66
+ Animated.timing(scaleAnim, {
67
+ toValue: 1,
68
+ duration: 150,
69
+ useNativeDriver: true,
70
+ })
71
+ ]).start();
72
+ };
73
+
74
+ const handleRatingChange = (newRating) => {
75
+ setUserRating(newRating);
76
+ animateRating();
77
+
78
+ setTimeout(() => {
79
+ setRatings(prevRatings => {
80
+ const filteredRatings = userRating !== null
81
+ ? prevRatings.filter((_, index) => index !== prevRatings.lastIndexOf(userRating))
82
+ : prevRatings;
83
+
84
+ const updatedRatings = [...filteredRatings, newRating];
85
+ updateAverageRating(updatedRatings);
86
+ return updatedRatings;
87
+ });
88
+ }, 0);
89
+ };
90
+
91
+
92
+ const handleRemoveRating = () => {
93
+ if (userRating !== null) {
94
+ setUserRating(null);
95
+
96
+ setTimeout(() => {
97
+ setRatings(prevRatings => {
98
+ const filteredRatings = prevRatings.filter((_, index) => index !== prevRatings.lastIndexOf(userRating));
99
+ updateAverageRating(filteredRatings);
100
+ return filteredRatings;
101
+ });
102
+ }, 0);
103
+ }
104
+ };
105
+
106
+
107
+ const updateAverageRating = (updatedRatings) => {
108
+ const totalRatings = updatedRatings.length;
109
+ const sumRatings = updatedRatings.reduce((sum, rating) => sum + rating, 0);
110
+ setDisplayValue(totalRatings > 0 ? (sumRatings / totalRatings).toFixed(2) : 'N/A');
111
+ };
112
+
113
+ return (
114
+ <View style={styles.container}>
115
+ <View style={styles.userRatingContainer}>
116
+ <StarRating
117
+ rating={userRating || 0}
118
+ onChange={handleRatingChange}
119
+ starSize={45}
120
+ />
121
+ <Animated.View style={[styles.userRatingValueWrapper, { transform: [{ scale: scaleAnim }] }]}>
122
+ <Text style={styles.userRatingValueNum}>{userRating || '-'}</Text>
123
+ </Animated.View>
124
+ </View>
125
+ {userRating !== null && (
126
+ <Button title="Eliminar rating" onPress={handleRemoveRating} />
127
+ )}
128
+ <View {...panResponder.panHandlers}>
129
+ <BarChart
130
+ data={data}
131
+ width={screenWidth - 40}
132
+ height={100}
133
+ hideLegend
134
+ withInnerLines={false}
135
+ chartConfig={chartConfig}
136
+ fromZero
137
+ withHorizontalLabels={false}
138
+ withCustomBarColorFromData={false}
139
+ />
140
+ </View>
141
+ <View style={styles.ratingNumAndStars}>
142
+ <Text style={styles.averageRating}>{displayValue}</Text>
143
+ <StarRating
144
+ rating={selectedStarValue}
145
+ starSize={20}
146
+ color={"#1f456e"}
147
+ onChange={() => { }}
148
+ />
149
+ </View>
150
+ </View>
151
+ );
152
+ };
153
+
154
+ const chartConfig = {
155
+ backgroundGradientFrom: '#1c1c1c',
156
+ backgroundGradientTo: '#1c1c1c',
157
+ color: (opacity = 1) => `rgba(0, 122, 255, ${opacity})`,
158
+ barPercentage: 0.5,
159
+ };
160
+
161
+ const styles = StyleSheet.create({
162
+ container: {
163
+ padding: 10,
164
+ alignItems: 'center',
165
+ width: '100%',
166
+ },
167
+ userRatingContainer: {
168
+ flexDirection: 'row',
169
+ justifyContent: "space-evenly",
170
+ alignItems: "center",
171
+ },
172
+ userRatingValueWrapper: {
173
+ justifyContent: "center",
174
+ alignItems: "center",
175
+ backgroundColor: "#fdd835",
176
+ width: 50,
177
+ height: 50,
178
+ borderRadius: 25,
179
+ },
180
+ userRatingValueNum: {
181
+ fontSize: 21,
182
+ fontWeight: "bold",
183
+ },
184
+ ratingNumAndStars: {
185
+ flexDirection: 'row',
186
+ alignItems: 'center',
187
+ justifyContent: 'space-evenly',
188
+ width: '100%',
189
+ marginTop: 10,
190
+ },
191
+ averageRating: {
192
+ fontSize: 26,
193
+ fontWeight: 'bold',
194
+ color: '#e3f2fd',
195
+ },
196
+ });
197
+
198
+ export default RatingHistogram;
@@ -0,0 +1,38 @@
1
+ import { useEffect } from "react";
2
+ import { Animated } from "react-native";
3
+
4
+ const FadeInView = (props) => {
5
+ const fadeAnim = new Animated.Value(0); // Initial value for opacity: 0
6
+
7
+ useEffect(() => {
8
+ const fadeIn = () => {
9
+ Animated.timing(fadeAnim, {
10
+ toValue: 1,
11
+ duration: 1000,
12
+ useNativeDriver: true,
13
+ }).start(() => fadeOut());
14
+ };
15
+
16
+ const fadeOut = () => {
17
+ Animated.timing(fadeAnim, {
18
+ toValue: 0.5,
19
+ duration: 1000,
20
+ useNativeDriver: true,
21
+ }).start(() => fadeIn());
22
+ };
23
+
24
+ fadeIn();
25
+ }, [fadeAnim]);
26
+
27
+ return (
28
+ <Animated.View // Special animatable View
29
+ style={{
30
+ ...props.style,
31
+ opacity: fadeAnim, // Bind opacity to animated value
32
+ }}>
33
+ {props.children}
34
+ </Animated.View>
35
+ );
36
+ };
37
+
38
+ export default FadeInView;
package/index.js ADDED
@@ -0,0 +1,8 @@
1
+ import { registerRootComponent } from 'expo';
2
+
3
+ import App from './App';
4
+
5
+ // registerRootComponent calls AppRegistry.registerComponent('main', () => App);
6
+ // It also ensures that whether you load the app in Expo Go or in a native build,
7
+ // the environment is set up appropriately
8
+ registerRootComponent(App);
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "react-native-album-display",
3
+ "version": "1.0.0",
4
+ "authors": [
5
+ {
6
+ "email": "guille@carvajal.es",
7
+ "name": "Guillermo Dylan Carvajal"
8
+ },
9
+ {
10
+ "name": "Diego Moragón Merallo"
11
+ }
12
+ ],
13
+ "main": "index.js",
14
+ "scripts": {
15
+ "start": "expo start",
16
+ "android": "expo start --android",
17
+ "ios": "expo start --ios",
18
+ "web": "expo start --web"
19
+ },
20
+ "dependencies": {
21
+ "@expo/metro-runtime": "~4.0.1",
22
+ "@rneui/themed": "^4.0.0-rc.8",
23
+ "expo": "~52.0.35",
24
+ "expo-status-bar": "~2.0.1",
25
+ "react": "18.3.1",
26
+ "react-dom": "18.3.1",
27
+ "react-native": "0.76.7",
28
+ "react-native-chart-kit": "^6.12.0",
29
+ "react-native-linear-gradient": "^2.8.3",
30
+ "react-native-star-rating-widget": "^1.9.2",
31
+ "react-native-web": "~0.19.13"
32
+ },
33
+ "devDependencies": {
34
+ "@babel/core": "^7.20.0"
35
+ },
36
+ "private": false
37
+ }