mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-27 13:38:28 +00:00
71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import { Ionicons } from "@expo/vector-icons";
|
|
import { type QueryClient, useQueryClient } from "@tanstack/react-query";
|
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
import { Animated, Easing } from "react-native";
|
|
import { TVButton } from "./TVButton";
|
|
|
|
export interface TVRefreshButtonProps {
|
|
itemId: string | undefined;
|
|
queryClient?: QueryClient;
|
|
}
|
|
|
|
export const TVRefreshButton: React.FC<TVRefreshButtonProps> = ({
|
|
itemId,
|
|
queryClient: externalQueryClient,
|
|
}) => {
|
|
const defaultQueryClient = useQueryClient();
|
|
const queryClient = externalQueryClient ?? defaultQueryClient;
|
|
const [isRefreshing, setIsRefreshing] = useState(false);
|
|
const spinValue = useRef(new Animated.Value(0)).current;
|
|
|
|
useEffect(() => {
|
|
if (isRefreshing) {
|
|
spinValue.setValue(0);
|
|
Animated.loop(
|
|
Animated.timing(spinValue, {
|
|
toValue: 1,
|
|
duration: 1000,
|
|
easing: Easing.linear,
|
|
useNativeDriver: true,
|
|
}),
|
|
).start();
|
|
} else {
|
|
spinValue.stopAnimation();
|
|
spinValue.setValue(0);
|
|
}
|
|
}, [isRefreshing, spinValue]);
|
|
|
|
const spin = spinValue.interpolate({
|
|
inputRange: [0, 1],
|
|
outputRange: ["0deg", "360deg"],
|
|
});
|
|
|
|
const handleRefresh = useCallback(async () => {
|
|
if (!itemId || isRefreshing) return;
|
|
|
|
setIsRefreshing(true);
|
|
const minSpinTime = new Promise((resolve) => setTimeout(resolve, 1000));
|
|
try {
|
|
await Promise.all([
|
|
queryClient.invalidateQueries({ queryKey: ["item", itemId] }),
|
|
minSpinTime,
|
|
]);
|
|
} finally {
|
|
setIsRefreshing(false);
|
|
}
|
|
}, [itemId, queryClient, isRefreshing]);
|
|
|
|
return (
|
|
<TVButton
|
|
onPress={handleRefresh}
|
|
variant='glass'
|
|
square
|
|
disabled={isRefreshing}
|
|
>
|
|
<Animated.View style={{ transform: [{ rotate: spin }] }}>
|
|
<Ionicons name='refresh' size={28} color='#FFFFFF' />
|
|
</Animated.View>
|
|
</TVButton>
|
|
);
|
|
};
|