diff --git a/mobile/components/ui/Skeleton.js b/mobile/components/ui/Skeleton.js new file mode 100644 index 0000000..5478784 --- /dev/null +++ b/mobile/components/ui/Skeleton.js @@ -0,0 +1,45 @@ +import React, { useEffect, useRef } from 'react'; +import { Animated, StyleSheet, View } from 'react-native'; +import { useTheme } from 'react-native-paper'; + +const Skeleton = ({ width, height, borderRadius, style }) => { + const theme = useTheme(); + const opacityAnim = useRef(new Animated.Value(0.3)).current; + + useEffect(() => { + const loop = Animated.loop( + Animated.sequence([ + Animated.timing(opacityAnim, { + toValue: 1, + duration: 700, + useNativeDriver: true, + }), + Animated.timing(opacityAnim, { + toValue: 0.3, + duration: 700, + useNativeDriver: true, + }), + ]) + ); + loop.start(); + + return () => loop.stop(); + }, [opacityAnim]); + + return ( + + ); +}; + +export default Skeleton; diff --git a/mobile/screens/FriendsScreen.js b/mobile/screens/FriendsScreen.js index c778a95..ab250fe 100644 --- a/mobile/screens/FriendsScreen.js +++ b/mobile/screens/FriendsScreen.js @@ -1,6 +1,6 @@ import { useIsFocused } from "@react-navigation/native"; -import { useContext, useEffect, useRef, useState } from "react"; -import { Alert, Animated, FlatList, RefreshControl, StyleSheet, View } from "react-native"; +import { useContext, useEffect, useState } from "react"; +import { Alert, FlatList, RefreshControl, StyleSheet, View } from "react-native"; import { Appbar, Avatar, @@ -12,6 +12,7 @@ import { import HapticIconButton from '../components/ui/HapticIconButton'; import { HapticListAccordion } from '../components/ui/HapticList'; import { triggerPullRefreshHaptic } from '../components/ui/hapticUtils'; +import Skeleton from '../components/ui/Skeleton'; import { getFriendsBalance, getGroups } from "../api/groups"; import { AuthContext } from "../context/AuthContext"; import { formatCurrency } from "../utils/currency"; @@ -167,42 +168,12 @@ const FriendsScreen = () => { ); }; - // Shimmer skeleton components - const opacityAnim = useRef(new Animated.Value(0.3)).current; - useEffect(() => { - const loop = Animated.loop( - Animated.sequence([ - Animated.timing(opacityAnim, { - toValue: 1, - duration: 700, - useNativeDriver: true, - }), - Animated.timing(opacityAnim, { - toValue: 0.3, - duration: 700, - useNativeDriver: true, - }), - ]) - ); - loop.start(); - return () => loop.stop(); - }, [opacityAnim]); - const SkeletonRow = () => ( - + - - + + ); @@ -315,23 +286,6 @@ const styles = StyleSheet.create({ alignItems: "center", marginBottom: 14, }, - skeletonAvatar: { - width: 48, - height: 48, - borderRadius: 24, - backgroundColor: "#e0e0e0", - }, - skeletonLine: { - height: 14, - backgroundColor: "#e0e0e0", - borderRadius: 6, - marginBottom: 6, - }, - skeletonLineSmall: { - height: 12, - backgroundColor: "#e0e0e0", - borderRadius: 6, - }, }); export default FriendsScreen;