Enhance StreamsScreen animations and layout for improved user experience

This update introduces staggered animations for stream cards and provider filters, enhancing the visual appeal during loading states. The layout has been refined to ensure a smoother transition and better organization of stream details and actions. Additionally, the use of Animated.View components improves performance and responsiveness, contributing to a more engaging user interface.
This commit is contained in:
tapframe 2025-05-27 22:19:08 +05:30
parent 10aa799626
commit 92704f0998

View file

@ -42,7 +42,8 @@ import Animated, {
Extrapolate,
runOnJS,
cancelAnimation,
SharedValue
SharedValue,
Layout
} from 'react-native-reanimated';
import { logger } from '../utils/logger';
@ -76,7 +77,14 @@ const StreamCard = ({ stream, onPress, index, isLoading, statusMessage, theme }:
const displayTitle = isHDRezka ? `HDRezka ${stream.title}` : (stream.name || stream.title || 'Unnamed Stream');
const displayAddonName = isHDRezka ? '' : (stream.title || '');
// Animation delay based on index - stagger effect
const enterDelay = 100 + (index * 50);
return (
<Animated.View
entering={FadeInDown.duration(300).delay(enterDelay).springify()}
layout={Layout.springify()}
>
<TouchableOpacity
style={[
styles.streamCard,
@ -148,6 +156,7 @@ const StreamCard = ({ stream, onPress, index, isLoading, statusMessage, theme }:
/>
</View>
</TouchableOpacity>
</Animated.View>
);
};
@ -174,7 +183,11 @@ const ProviderFilter = memo(({
}) => {
const styles = React.useMemo(() => createStyles(theme.colors), [theme.colors]);
const renderItem = useCallback(({ item }: { item: { id: string; name: string } }) => (
const renderItem = useCallback(({ item, index }: { item: { id: string; name: string }; index: number }) => (
<Animated.View
entering={FadeIn.duration(300).delay(100 + index * 40)}
layout={Layout.springify()}
>
<TouchableOpacity
key={item.id}
style={[
@ -190,9 +203,13 @@ const ProviderFilter = memo(({
{item.name}
</Text>
</TouchableOpacity>
</Animated.View>
), [selectedProvider, onSelect, styles]);
return (
<Animated.View
entering={FadeIn.duration(300)}
>
<FlatList
data={providers}
renderItem={renderItem}
@ -212,6 +229,7 @@ const ProviderFilter = memo(({
index,
})}
/>
</Animated.View>
);
});
@ -807,13 +825,14 @@ export const StreamsScreen = () => {
);
}, [handleStreamPress, loadingProviders, providerStatus, currentTheme]);
const renderSectionHeader = useCallback(({ section }: { section: { title: string } }) => (
const renderSectionHeader = useCallback(({ section }: { section: { title: string; addonId: string } }) => (
<Animated.View
entering={FadeIn.duration(300)}
entering={FadeIn.duration(400)}
layout={Layout.springify()}
>
<Text style={styles.streamGroupTitle}>{section.title}</Text>
</Animated.View>
), []);
), [styles.streamGroupTitle]);
return (
<View style={styles.container}>