Skip to content

Commit

Permalink
fix(Animations): ajuster les paramètres d'échelle pour les animations…
Browse files Browse the repository at this point in the history
… d'entrée et de sortie

fix(Lessons): ajouter un décalage supérieur pour le modal de sélection de date
fix(LessonsHeader): améliorer l'importation des animations et la gestion de l'affichage du modal
  • Loading branch information
ecnivtwelve committed Mar 11, 2025
1 parent cafa0cc commit cf4fedd
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 99 deletions.
20 changes: 14 additions & 6 deletions src/utils/ui/animations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ const anim2Papillon = (animation: any) => {
};

const EnteringDuration = 180;
const EnteringScale = 0.8;
const EnteringScaleX = 0.8;
const EnteringScaleY = 0.65;

const ExitingDuration = 120;
const ExitingScale = 0.9;
const ExitingScaleX = 0.9;
const ExitingScaleY = 0.7;

// Paramètres d'animation pour l'entrée du menu contextuel
const PapillonAnimSettings = {
Expand All @@ -36,14 +39,18 @@ const PapillonContextEnter = () => {
opacity: withTiming(1, PapillonAnimSettings),
transform: [
{
scale: withTiming(1, PapillonAnimSettings),
scaleX: withTiming(1, PapillonAnimSettings),
},
{
scaleY: withTiming(1, PapillonAnimSettings),
},
],
};
const initialValues = {
opacity: 0,
transform: [
{ scale: EnteringScale },
{ scaleX: EnteringScaleX},
{ scaleY: EnteringScaleY },
],
};
return {
Expand All @@ -58,12 +65,13 @@ const PapillonContextExit = () => {
const animations = {
opacity: withTiming(0, PapillonAnimSettingsExit),
transform: [
{ scale: withTiming(ExitingScale, PapillonAnimSettingsExit) },
{ scaleX: withTiming(ExitingScaleX, PapillonAnimSettingsExit) },
{ scaleY: withTiming(ExitingScaleY, PapillonAnimSettingsExit) },
],
};
const initialValues = {
opacity: 1,
transform: [{ scale: 1 }],
transform: [{ scaleX: 1 }, { scaleY: 1 }],
};
return {
initialValues,
Expand Down
1 change: 1 addition & 0 deletions src/views/account/Lessons/Lessons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ const Lessons: Screen<"Lessons"> = ({ route, navigation }) => {
/>

<LessonsDateModal
topOffset={insets.top + 60}
showDatePicker={showDatePicker}
setShowDatePicker={setShowDatePicker}
currentDate={pickerDate}
Expand Down
214 changes: 121 additions & 93 deletions src/views/account/Lessons/LessonsHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { useTheme } from "@react-navigation/native";
import React from "react";
import { Dimensions, Modal, Platform, Pressable, Text, TouchableOpacity, View } from "react-native";
import { Modal, Platform, Pressable, Text, TouchableOpacity, View } from "react-native";

import { X } from "lucide-react-native";

import Reanimated, {
FadeInDown,
FadeOutDown,
FadeIn,
FadeOut,
LinearTransition,
} from "react-native-reanimated";

import RNDateTimePicker from "@react-native-community/datetimepicker";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import {animPapillon} from "@/utils/ui/animations";
import {animPapillon, PapillonContextEnter, PapillonContextExit} from "@/utils/ui/animations";
import useScreenDimensions from "@/hooks/useScreenDimensions";

interface HeaderCalendarProps {
index: number,
Expand Down Expand Up @@ -44,6 +45,7 @@ interface LessonsDateModalProps {
currentPageIndex?: number,
defaultDate?: Date,
currentDate: Date,
topOffset?: number,
// NOTE: PagerRef is hard to type, may need help on this ?
PagerRef?: React.RefObject<any>,
getDateFromIndex?: (index: number) => Date
Expand All @@ -53,11 +55,25 @@ const LessonsDateModal: React.FC<LessonsDateModalProps> = ({
showDatePicker,
setShowDatePicker,
onDateSelect,
currentDate
currentDate,
topOffset
}) => {
const { colors } = useTheme();
const insets = useSafeAreaInsets();

const [showModalPicker, setShowModalPicker] = React.useState(false);
const {isTablet} = useScreenDimensions();

React.useEffect(() => {
if (showDatePicker) {
setShowModalPicker(true);
} else {
setTimeout(() => {
setShowModalPicker(false);
}, 200);
}
}, [showDatePicker]);

if (Platform.OS === "android") {
return (
showDatePicker && (
Expand All @@ -84,108 +100,120 @@ const LessonsDateModal: React.FC<LessonsDateModalProps> = ({

return (
<Modal
animationType="fade"
transparent={true}
visible={showDatePicker}
visible={showModalPicker}
>
<View
style={{
flex: 1,
justifyContent: "flex-end",
alignItems: "center",
backgroundColor: "#00000099",
paddingBottom: insets.bottom + 10,
}}
>
<Pressable
{showDatePicker && (
<Reanimated.View
style={{
width: "100%",
flex: 1,
justifyContent: "flex-end",
alignItems: "center",
backgroundColor: "#00000099",
paddingBottom: insets.bottom + 10,
}}
onPress={() => setShowDatePicker(false)}
/>

{showDatePicker && (
<Reanimated.View
entering={FadeIn.duration(200)}
exiting={FadeOut.duration(200)}
>
<Pressable
style={{
width: Dimensions.get("window").width - 20,
backgroundColor: colors.card,
overflow: "hidden",
borderRadius: 16,
borderCurve: "continuous",
width: "100%",
flex: 1,
}}
entering={FadeInDown.mass(1).damping(20).stiffness(300)}
exiting={FadeOutDown.mass(1).damping(20).stiffness(300)}
>
<View
style={{
flexDirection: "column",
alignItems: "flex-start",
paddingHorizontal: 18,
paddingVertical: 14,
backgroundColor: colors.primary,
gap: 2,
}}
onPress={() => setShowDatePicker(false)}
/>

{showDatePicker && (
<Reanimated.View
style={[
{
maxWidth: 400,
backgroundColor: colors.card,
overflow: "hidden",
borderRadius: 16,
borderCurve: "continuous",
transformOrigin: "bottom center",
},
topOffset ? {
position: "absolute",
top: topOffset,
left: 16 + (isTablet ? 320 : 0),
transformOrigin: "top left",
} : null
]}
entering={PapillonContextEnter}
exiting={PapillonContextExit}
>
<Text
<View
style={{
fontSize: 15,
fontFamily: "medium",
color: "#ffffff99",
flexDirection: "column",
alignItems: "flex-start",
paddingHorizontal: 18,
paddingVertical: 14,
backgroundColor: colors.primary,
gap: 2,
}}
>
Sélection de la date
</Text>
<Text
style={{
fontSize: 18,
fontFamily: "semibold",
color: "#fff",
}}
>
{new Date(currentDate).toLocaleDateString("fr-FR", { weekday: "long", day: "numeric", month: "long" })}
</Text>
<Text
style={{
fontSize: 15,
fontFamily: "medium",
color: "#ffffff99",
}}
>
Sélection de la date
</Text>
<Text
style={{
fontSize: 18,
fontFamily: "semibold",
color: "#fff",
}}
>
{new Date(currentDate).toLocaleDateString("fr-FR", { weekday: "long", day: "numeric", month: "long" })}
</Text>

<TouchableOpacity
<TouchableOpacity
style={{
position: "absolute",
right: 12,
top: 12,
backgroundColor: "#ffffff39",
opacity: 0.7,
padding: 6,
borderRadius: 50,
}}
onPress={() => setShowDatePicker(false)}
>
<X
size={20}
strokeWidth={3}
color="#fff"
/>
</TouchableOpacity>
</View>
<RNDateTimePicker
style={{
position: "absolute",
right: 12,
top: 12,
backgroundColor: "#ffffff39",
opacity: 0.7,
padding: 6,
borderRadius: 50,
marginHorizontal: 8,
marginTop: -5,
marginBottom: 10,
}}
onPress={() => setShowDatePicker(false)}
>
<X
size={20}
strokeWidth={3}
color="#fff"
/>
</TouchableOpacity>
</View>
<RNDateTimePicker
style={{
marginHorizontal: 8,
marginTop: -5,
marginBottom: 10,
}}
value={new Date(currentDate)}
display="inline"
mode="date"
locale="fr-FR"
accentColor={colors.primary}
onChange={(_event, selectedDate) => {
const newSelectedDate = selectedDate || currentDate;
// set hours to 0
newSelectedDate.setHours(0, 0, 0, 0);
onDateSelect(newSelectedDate);
}}
/>
</Reanimated.View>
)}
</View>
value={new Date(currentDate)}
display="inline"
mode="date"
locale="fr-FR"
accentColor={colors.primary}
onChange={(_event, selectedDate) => {
const newSelectedDate = selectedDate || currentDate;
// set hours to 0
newSelectedDate.setHours(0, 0, 0, 0);
onDateSelect(newSelectedDate);
}}
/>
</Reanimated.View>
)}
</Reanimated.View>
)}
</Modal>
);
};
Expand Down

0 comments on commit cf4fedd

Please sign in to comment.