[REF] InteractiveBase refactoring logic

This commit is contained in:
mathysPaul
2023-11-14 00:46:01 +01:00
parent d01aabe788
commit 5f9e9f5327
2 changed files with 200 additions and 5 deletions

View File

@@ -0,0 +1,143 @@
import React, { useRef, useEffect } from 'react';
import { Animated, StyleSheet, Pressable, ViewStyle, StyleProp } from 'react-native';
type StyleObject = Record<string, any>;
type InterpolatedStyleObject = Record<string, Animated.AnimatedInterpolation<any>>;
interface InteractiveCCProps {
defaultStyle: StyleObject;
hoverStyle: StyleObject;
pressStyle: StyleObject;
duration?: number;
children?: React.ReactNode;
onPress?: () => void | Promise<void>;
isDisabled?: boolean;
style?: StyleProp<ViewStyle>;
styleContainer?: StyleProp<ViewStyle>;
}
const InteractiveCC: React.FC<InteractiveCCProps> = ({ defaultStyle, hoverStyle, pressStyle, children, onPress, isDisabled, style, styleContainer, duration=250 }) => {
const animatedValues = useRef<Record<string, Animated.Value>>({}).current;
const extractTransformKeys = (styleObject: StyleObject) => {
const transformKeys = styleObject.transform ? styleObject.transform.map((t: any) => Object.keys(t)[0]) : [];
return transformKeys;
};
useEffect(() => {
// Initialisez les valeurs animées pour les propriétés de style non-transform
const allStyleKeys = new Set([
...Object.keys(defaultStyle),
...Object.keys(hoverStyle),
...Object.keys(pressStyle),
]);
allStyleKeys.forEach(key => {
if (!animatedValues[key]) {
animatedValues[key] = new Animated.Value(0);
}
});
// Initialisez les valeurs animées pour les propriétés de style transform
const allTransformKeys = new Set([
...extractTransformKeys(defaultStyle),
...extractTransformKeys(hoverStyle),
...extractTransformKeys(pressStyle),
]);
allTransformKeys.forEach(key => {
if (!animatedValues[key]) {
animatedValues[key] = new Animated.Value(0);
}
});
}, [defaultStyle, hoverStyle, pressStyle]);
const getTransformValue = (key: string, style: StyleObject) => {
const transformObject = style.transform?.find((t: any) => t.hasOwnProperty(key));
return transformObject ? transformObject[key] : 0;
};
const interpolateStyle = (stateStyle: StyleObject, stateValue: number): InterpolatedStyleObject => {
const interpolatedStyle: InterpolatedStyleObject = { ...stateStyle };
const transform: any = [];
Object.keys(animatedValues).forEach(key => {
if (stateStyle.transform?.some((t: any) => t.hasOwnProperty(key))) {
// Interpolation des transformations
const defaultValue = getTransformValue(key, defaultStyle);
const hoverValue = getTransformValue(key, hoverStyle);
const pressValue = getTransformValue(key, pressStyle);
const interpolated = animatedValues[key].interpolate({
inputRange: [0, 1, 2],
outputRange: [defaultValue, hoverValue, pressValue],
});
transform.push({ [key]: interpolated });
} else if (stateStyle[key]) {
// Interpolation des autres styles
const defaultValue = defaultStyle[key] || 0;
const hoverValue = hoverStyle[key] !== undefined ? hoverStyle[key] : defaultValue;
const pressValue = pressStyle[key] !== undefined ? pressStyle[key] : defaultValue;
interpolatedStyle[key] = animatedValues[key].interpolate({
inputRange: [0, 1, 2],
outputRange: [defaultValue, hoverValue, pressValue],
});
}
});
interpolatedStyle.transform = transform;
return interpolatedStyle;
};
const animateToState = (stateValue: number) => {
Object.keys(animatedValues).forEach(key => {
Animated.timing(animatedValues[key], {
toValue: stateValue,
duration: duration,
useNativeDriver: true, // Ajustez en fonction des propriétés animées
}).start();
});
};
const handleMouseEnter = () => animateToState(1);
const handlePressIn = () => animateToState(2);
const handlePressOut = () => {
animateToState(1);
if (onPress && !isDisabled) {
onPress();
}
};
const handleMouseLeave = () => animateToState(0);
const animatedStyle = StyleSheet.flatten([
styleContainer,
interpolateStyle(defaultStyle, 0),
interpolateStyle(hoverStyle, 1),
interpolateStyle(pressStyle, 2),
]);
return (
<Animated.View style={animatedStyle}>
<Pressable
style={[styles.content, style]}
focusable={false}
onHoverIn={handleMouseEnter}
onPressIn={handlePressIn}
onPressOut={handlePressOut}
onHoverOut={handleMouseLeave}
>
{children}
</Pressable>
</Animated.View>
);
};
const styles = StyleSheet.create({
content: {
width: '100%',
height: '100%',
},
});
export default InteractiveCC;

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { Center, Text, useBreakpointValue, useTheme } from 'native-base';
import { Center, Text, View, useBreakpointValue, useTheme } from 'native-base';
import { useWindowDimensions } from 'react-native';
import {
TabView,
@@ -19,6 +19,8 @@ import { useQueries, useQuery } from '../Queries';
import API from '../API';
import Song from '../models/Song';
import { LoadingView } from '../components/Loading';
import InteractiveCC from '../components/UI/InteractiveCC';
import ButtonBase from '../components/UI/ButtonBase';
// Fichier de données fictives, par exemple MusicData.ts
export const fakeMusicData = [
@@ -1203,14 +1205,64 @@ export const FavoritesMusic = () => {
},
})) ?? [];
const { colors } = useTheme();
if (isLoading) {
return <LoadingView />;
}
return (
<MusicList
initialMusics={musics}
// musicsPerPage={7}
/>
<>
<View style={{margin: 30}}>
<InteractiveCC
// duration={80}
styleContainer={{
width: 'fit-content',
borderRadius: 10,
}}
style={{
width: '100%',
paddingHorizontal: 20,
paddingVertical: 10,
// borderRadius: 10,
}}
defaultStyle={{
transform: [{ scale: 1,}],
shadowOpacity: 0.3,
shadowRadius: 4.65,
elevation: 8,
backgroundColor: colors.primary[300],
}}
hoverStyle={{
transform: [{ scale: 1.02,}],
shadowOpacity: 0.37,
shadowRadius: 7.49,
elevation: 12,
backgroundColor: colors.primary[400],
}}
pressStyle={{
transform: [{ scale: 0.98,}],
shadowOpacity: 0.23,
shadowRadius: 2.62,
elevation: 4,
backgroundColor: colors.primary[500],
}}
onPress={() => console.log("A que coucou!")}
>
<Text selectable={false} style={{color: '#fff'}}>
Coucou
</Text>
</InteractiveCC>
<ButtonBase
title="Coucou"
style={{ width: 'fit-content', marginTop: 20 }}
type={'filled'}
/>
</View>
<MusicList
initialMusics={musics}
// musicsPerPage={7}
/>
</>
);
};