mirror of
https://github.com/urosran/cally.git
synced 2025-07-10 07:07:16 +00:00
67 lines
1.5 KiB
TypeScript
67 lines
1.5 KiB
TypeScript
import React, { useRef, useEffect } from 'react';
|
|
import { TouchableOpacity, Animated, Easing } from 'react-native';
|
|
import { Feather } from '@expo/vector-icons';
|
|
|
|
interface RefreshButtonProps {
|
|
onRefresh: () => Promise<void>;
|
|
isSyncing: boolean;
|
|
size?: number;
|
|
color?: string;
|
|
}
|
|
|
|
const RefreshButton = ({
|
|
onRefresh,
|
|
isSyncing,
|
|
size = 24,
|
|
color = "#83807F"
|
|
}: RefreshButtonProps) => {
|
|
const rotateAnim = useRef(new Animated.Value(0)).current;
|
|
const rotationLoop = useRef<Animated.CompositeAnimation | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (isSyncing) {
|
|
startContinuousRotation();
|
|
} else {
|
|
stopRotation();
|
|
}
|
|
}, [isSyncing]);
|
|
|
|
const startContinuousRotation = () => {
|
|
rotateAnim.setValue(0);
|
|
rotationLoop.current = Animated.loop(
|
|
Animated.timing(rotateAnim, {
|
|
toValue: 1,
|
|
duration: 1000,
|
|
easing: Easing.linear,
|
|
useNativeDriver: true,
|
|
})
|
|
);
|
|
rotationLoop.current.start();
|
|
};
|
|
|
|
const stopRotation = () => {
|
|
rotationLoop.current?.stop();
|
|
rotateAnim.setValue(0);
|
|
};
|
|
|
|
const rotate = rotateAnim.interpolate({
|
|
inputRange: [0, 1],
|
|
outputRange: ['0deg', '360deg'],
|
|
});
|
|
|
|
const handlePress = async () => {
|
|
if (!isSyncing) {
|
|
await onRefresh();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<TouchableOpacity onPress={handlePress} disabled={isSyncing}>
|
|
<Animated.View style={{ transform: [{ rotate }] }}>
|
|
<Feather name="refresh-cw" size={size} color={color} />
|
|
</Animated.View>
|
|
</TouchableOpacity>
|
|
);
|
|
};
|
|
|
|
export default RefreshButton; |