Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:(grades) Réactions aux notes #559

Merged
merged 20 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
60d0577
feat(Grades): Mise à jour de la version et ajout de la navigation ver…
tryon-dev Dec 14, 2024
88a9fb8
feat(Reactions): Ajout de la gestion des réactions avec affichage dan…
tryon-dev Dec 15, 2024
a94d8c2
feat(Grades): Ajout d'une gestion améliorée des réactions avec affich…
tryon-dev Dec 15, 2024
ec8a041
feat(Grades): Ajout d'un composant AnimatedEmoji et d'une modal Grade…
tryon-dev Dec 28, 2024
3f08e3f
feat(Grades): Ajout des fonctionnalités de partage et de sauvegarde d…
tryon-dev Dec 28, 2024
99ba010
feat(ReelGallery): Amélioration de l'affichage des vignettes et ajout…
tryon-dev Dec 29, 2024
97e8d5e
feat(AnimatedEmoji): Ajout de nouveaux emojis pour une meilleure expé…
tryon-dev Dec 29, 2024
9c823df
feat(GradeReaction): Ajout d'un indicateur de chargement lors de l'en…
tryon-dev Dec 31, 2024
dff2f87
feat(MissingItem): Ajout d'un support pour les emojis animés et améli…
tryon-dev Dec 31, 2024
02e4c3c
feat: Amélioration de l'expérience utilisateur avec des ajustements v…
tryon-dev Dec 31, 2024
7341fd6
feat(GradeDocument): Ajout d'un état pour gérer les réactions et amél…
tryon-dev Dec 31, 2024
460ba2f
feat(GradeReaction): Suppression de commentaires inutiles et nettoyag…
tryon-dev Dec 31, 2024
7a20918
feat(ReelGallery): Amélioration de la mise en page de la galerie
tryon-dev Dec 31, 2024
e703deb
Merge branch 'main' into feat-grade-reaction
tryon-dev Jan 1, 2025
842c193
Update src/components/Settings/ReelGallery.tsx
tryon-dev Jan 1, 2025
4c38f9b
Update src/views/account/Grades/Modals/GradeReaction.tsx
tryon-dev Jan 1, 2025
1f3ac2c
Update src/components/Grades/AnimatedEmoji.tsx
tryon-dev Jan 1, 2025
1d3038d
Update src/components/Grades/AnimatedEmoji.tsx
tryon-dev Jan 1, 2025
055c63a
Update src/views/account/Grades/Modals/GradeReaction.tsx
tryon-dev Jan 1, 2025
bfed7dd
fix(Grades): Image set width to 50%
godetremy Jan 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/components/Global/MissingItem.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import Reanimated, { AnimatedStyle, EntryExitTransition, FadeInUp, FadeOutDown, LinearTransition } from "react-native-reanimated";
import { type StyleProp, Text, type ViewStyle } from "react-native";
import { NativeText } from "./NativeComponents";
import AnimatedEmoji from "../Grades/AnimatedEmoji";

interface MissingItemProps {
style?: StyleProp<AnimatedStyle<StyleProp<ViewStyle>>>;
emoji: string;
emoji?: string;
animatedEmoji?: boolean;
title: string;
description: string;
entering?: EntryExitTransition;
Expand All @@ -14,6 +16,7 @@ interface MissingItemProps {
const MissingItem: React.FC<MissingItemProps> = ({
style,
emoji,
animatedEmoji,
title,
description,
entering,
Expand All @@ -31,9 +34,13 @@ const MissingItem: React.FC<MissingItemProps> = ({
entering={entering ? entering : FadeInUp}
exiting={exiting ? exiting : FadeOutDown}
>
<Text style={{ fontSize: 32 }}>
{emoji}
</Text>
{!animatedEmoji ? (
<Text style={{ fontSize: 32 }}>
{emoji}
</Text>
) : (
<AnimatedEmoji initialScale={1.2} size={40} />
)}

<NativeText variant="title" style={{ textAlign: "center", marginTop: 3 }}>
{title}
Expand Down
93 changes: 93 additions & 0 deletions src/components/Grades/AnimatedEmoji.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React, { useEffect } from "react";
tryon-dev marked this conversation as resolved.
Show resolved Hide resolved
import { View, Text } from "react-native";
import Animated, {
useAnimatedStyle,
useSharedValue,
withTiming,
withSpring,
withSequence,
Easing,
} from "react-native-reanimated";

interface AnimatedEmojiProps {
initialScale?: number;
size?: number; // Taille de la police
}

const AnimatedEmoji: React.FC<AnimatedEmojiProps> = ({ initialScale = 1, size = 20 }) => {
const scale = useSharedValue(initialScale);
const opacity = useSharedValue(1);
const emojis = ["😍", "🙄", "😭", "🥳", "😱", "😳", "🤓", "🤡", "🤯", "😨", "🤔", "🫠"];
const [currentEmoji, setCurrentEmoji] = React.useState(emojis[0]);
tryon-dev marked this conversation as resolved.
Show resolved Hide resolved

const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{ scale: scale.value }],
opacity: opacity.value,
};
});

const changeEmoji = () => {
scale.value = withSequence(
withSpring(initialScale * 0.5, {
damping: 10,
stiffness: 100,
}),
withSpring(initialScale, {
damping: 12,
stiffness: 200,
})
);

opacity.value = withSequence(
withTiming(0, {
duration: 100,
easing: Easing.inOut(Easing.ease),
}),
withTiming(1, {
duration: 200,
easing: Easing.inOut(Easing.ease),
})
);

setTimeout(() => {
const nextIndex = (emojis.indexOf(currentEmoji) + 1) % emojis.length;
setCurrentEmoji(emojis[nextIndex]);
}, 100);
};

useEffect(() => {
const interval = setInterval(() => {
changeEmoji();
}, 2000);

return () => clearInterval(interval);
}, [currentEmoji]);

return (
<View
style={{
justifyContent: "center",
alignItems: "center",
}}
>
<Animated.Text
style={[
{
color: "#FFFFFF",
fontSize: size,
fontFamily: "semibold",
textAlign: "center",
textAlignVertical: "center",
marginTop: -2,
},
animatedStyle,
]}
>
{currentEmoji}
</Animated.Text>
</View>
);
};

export default AnimatedEmoji;
238 changes: 238 additions & 0 deletions src/components/Grades/GradeModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
import React from "react";
import {
Modal,
View,
Image,
TouchableOpacity,
Text,
Platform,
Alert
} from "react-native";
import { Download, Trash, Maximize2, Share, Delete } from "lucide-react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { BlurView } from "expo-blur";
import { ScrollView } from "react-native-gesture-handler";
import * as Sharing from "expo-sharing";
import * as FileSystem from "expo-file-system";
import * as MediaLibrary from "expo-media-library";
interface GradeModalProps {
isVisible: boolean;
imageBase64: string;
onClose: () => void;
DeleteGrade: () => void;
}

const GradeModal: React.FC<GradeModalProps> = ({
isVisible,
imageBase64,
onClose,
DeleteGrade,
}) => {
const insets = useSafeAreaInsets();

const shareImage = async () => {
try {
const fileUri = FileSystem.cacheDirectory + "image.jpg";
await FileSystem.writeAsStringAsync(fileUri, imageBase64, { encoding: FileSystem.EncodingType.Base64 });
await Sharing.shareAsync(fileUri);
} catch (error) {
console.error("Failed to share image:", error);
}
};

const saveimage = async () => {
try {
const fileUri = FileSystem.cacheDirectory + "image.jpg";
await FileSystem.writeAsStringAsync(fileUri, imageBase64, { encoding: FileSystem.EncodingType.Base64 });
const asset = await MediaLibrary.createAssetAsync(fileUri);
await MediaLibrary.createAlbumAsync("Download", asset, false);
Alert.alert("Image sauvegardée", "L'image a été sauvegardée dans votre galerie.");
} catch (error) {
console.error("Failed to save image:", error);
}
};

return (
<Modal
transparent={true}
visible={isVisible}
animationType="fade"
onRequestClose={onClose}
>
<BlurView
intensity={100}
tint="dark"
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<View
style={{
width: "100%",
height: "100%",
borderRadius: 20,
alignItems: "center",
flexDirection: "column",
paddingTop: insets.top,
}}
>
<Image
source={{ uri: `data:image/jpeg;base64,${imageBase64}` }}
style={{
width: "90%",
height: 500,
objectFit: "contain",
}}
/>
<View
style={{
width: "100%",
height: 170,
padding: 20,

justifyContent: "center",
alignItems: "center",
flexDirection: "row",
gap: 35,
}}
>
<TouchableOpacity
style={{
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
gap: 7,
}}
onPress={saveimage}
>
<View
style={{
padding: 15,
borderRadius: 100,
backgroundColor: "#000000",
}}
>
<Download color="white" size={30} />
</View>
<Text
style={{
color: "#FFFFFF",
fontSize: 15,
fontFamily: "semibold",
textAlign: "center",
textAlignVertical: "center"
}}
>
Télécharger
</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
gap: 7,
}}
onPress={shareImage}
>
<View
style={{
padding: 15,
borderRadius: 100,
backgroundColor: "#0E7CCB",
}}
>
<Share color="white" size={30} />
</View>
<Text
style={{
color: "#FFFFFF",
fontSize: 15,
fontFamily: "semibold",
textAlign: "center",
textAlignVertical: "center"
}}
>
Partager
</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
gap: 7,
}}
onPress={DeleteGrade}
>
<View
style={{
padding: 15,
borderRadius: 100,
backgroundColor: "#888888",
}}
>
<Trash color="white" size={30} />
</View>
<Text
style={{
color: "#FFFFFF",
fontSize: 15,
fontFamily: "semibold",
textAlign: "center",
textAlignVertical: "center"
}}
>
Supprimer
</Text>
</TouchableOpacity>

</View>
<View
style={{
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
width: "100%",
gap: 20,
paddingHorizontal: 20,
position: "absolute",
bottom: insets.bottom+50,
left: 0,
}}
>
<TouchableOpacity
style={{
flex: 1,
paddingHorizontal: 10,
paddingVertical: 20,
backgroundColor: "#FFFFFF50",
justifyContent: "center",
alignItems: "center",
borderRadius: 100,
}}
onPress={onClose}
>
<Text
style={{
fontSize: 16,
fontFamily: "semibold",
letterSpacing: 1,
textTransform: "uppercase",
textAlign: "center",
color: "#FFFFFF",
}}
>
Fermer
</Text>
</TouchableOpacity>
</View>
</View>
</BlurView>
</Modal>
);
};

export default GradeModal;
Loading
Loading