197 lines
5.6 KiB
TypeScript
197 lines
5.6 KiB
TypeScript
import React from "react";
|
|
import { View, Text, StyleSheet, Alert } from "react-native";
|
|
import { GestureDetector, Gesture, Pressable } from "react-native-gesture-handler";
|
|
import Animated, {
|
|
useSharedValue,
|
|
useAnimatedStyle,
|
|
runOnJS,
|
|
withSpring,
|
|
interpolate,
|
|
Extrapolation,
|
|
FadeOut,
|
|
useDerivedValue,
|
|
SharedValue,
|
|
} from "react-native-reanimated";
|
|
import { Archive, Trash } from "lucide-react-native";
|
|
import { Channel } from "stream-chat";
|
|
import { DefaultStreamChatGenerics } from "stream-chat-expo";
|
|
import { useThemeColor } from "@/hooks/useThemeColor";
|
|
import { useColorScheme } from "@/hooks/useColorScheme";
|
|
|
|
interface SwipeableChannelPreviewProps {
|
|
channel: Channel<DefaultStreamChatGenerics>;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
const SWIPE_THRESHOLD = -80;
|
|
const ACTION_WIDTH = 80;
|
|
|
|
export const SwipeableChannelPreview: React.FC<SwipeableChannelPreviewProps> = ({
|
|
channel,
|
|
children,
|
|
}) => {
|
|
const translateX = useSharedValue(0);
|
|
const colorScheme = useColorScheme();
|
|
|
|
// Theme-aware colors
|
|
const backgroundColor = useThemeColor({ light: "#ffffff", dark: "#1f1f1f" }, "background");
|
|
const textColor = useThemeColor({ light: "#ffffff", dark: "#ffffff" }, "text");
|
|
const deleteButtonColor = colorScheme === "dark" ? "#c2410c" : "#ea580c";
|
|
const iconColor = "#ffffff";
|
|
|
|
// const handleDeleteChannel = async () => {
|
|
// try {
|
|
// // Show confirmation dialog
|
|
// Alert.alert(
|
|
// "Quitter la conversation",
|
|
// "Êtes-vous sûr de vouloir quitter cette conversation ? Vous n'aurez plus accès au tablo associé.",
|
|
// [
|
|
// {
|
|
// text: "Annuler",
|
|
// style: "cancel",
|
|
// onPress: () => {
|
|
// // Close the swipe action
|
|
// translateX.value = withSpring(0);
|
|
// },
|
|
// },
|
|
// {
|
|
// text: "Quitter",
|
|
// style: "destructive",
|
|
// onPress: async () => {
|
|
// try {
|
|
// // Hide the channel for the current user
|
|
// await channel.delete({ hard_delete: false });
|
|
|
|
// // Close the swipe action
|
|
// translateX.value = withSpring(0);
|
|
|
|
// // // Show success message
|
|
// // Alert.alert(
|
|
// // "Succès",
|
|
// // "La conversation a été supprimée avec succès",
|
|
// // [{ text: "OK" }]
|
|
// // );
|
|
// } catch (error) {
|
|
// console.error("Error deleting channel:", error);
|
|
// Alert.alert("Erreur", "Impossible de quitter la conversation");
|
|
// }
|
|
// },
|
|
// },
|
|
// ],
|
|
// { cancelable: true }
|
|
// );
|
|
// } catch (error) {
|
|
// console.error("Error showing archive dialog:", error);
|
|
// }
|
|
// };
|
|
|
|
// const gestureHandler = Gesture.Pan()
|
|
// .onStart((context) => {
|
|
// // cancelOtherAnimations(id);
|
|
// context.translationX = translateX.value;
|
|
// })
|
|
// .onUpdate((event) => {
|
|
// // Only allow swiping left (negative values)
|
|
// translateX.value = Math.min(
|
|
// 0,
|
|
// Math.max(SWIPE_THRESHOLD, event.translationX)
|
|
// );
|
|
// })
|
|
// .onEnd((event) => {
|
|
// const shouldOpen = translateX.value < SWIPE_THRESHOLD / 2;
|
|
|
|
// if (shouldOpen) {
|
|
// translateX.value = withSpring(SWIPE_THRESHOLD);
|
|
// } else {
|
|
// translateX.value = withSpring(0);
|
|
// }
|
|
// });
|
|
|
|
const channelAnimatedStyle = useAnimatedStyle(() => {
|
|
return {
|
|
transform: [{ translateX: translateX.value }],
|
|
};
|
|
});
|
|
|
|
const actionAnimatedStyle = useAnimatedStyle(() => {
|
|
const scale = interpolate(translateX.value, [SWIPE_THRESHOLD, 0], [1, 0], Extrapolation.CLAMP);
|
|
|
|
const opacity = interpolate(
|
|
translateX.value,
|
|
[SWIPE_THRESHOLD, 0],
|
|
[1, 0],
|
|
Extrapolation.CLAMP
|
|
);
|
|
|
|
return {
|
|
transform: [{ scale }],
|
|
opacity,
|
|
};
|
|
});
|
|
|
|
// const onDeletePress = () => {
|
|
// runOnJS(handleDeleteChannel)();
|
|
// };
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
{/* Right Actions Background */}
|
|
{/* <View style={styles.rightActionsContainer}>
|
|
<Pressable
|
|
style={[styles.deleteButton, { backgroundColor: deleteButtonColor }]}
|
|
onPress={onDeletePress}
|
|
>
|
|
<Animated.View style={[styles.actionContent, actionAnimatedStyle]}>
|
|
<Trash size={24} color={iconColor} />
|
|
<Text style={[styles.actionText, { color: textColor }]}>
|
|
Quitter
|
|
</Text>
|
|
</Animated.View>
|
|
</Pressable>
|
|
</View> */}
|
|
|
|
{/* Channel Content */}
|
|
{/* <GestureDetector gesture={gestureHandler}> */}
|
|
<View style={[styles.channelContainer, channelAnimatedStyle, { backgroundColor }]}>
|
|
{children}
|
|
</View>
|
|
{/* </GestureDetector> */}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
position: "relative",
|
|
},
|
|
channelContainer: {
|
|
flex: 1,
|
|
},
|
|
rightActionsContainer: {
|
|
position: "absolute",
|
|
right: 0,
|
|
top: 0,
|
|
bottom: 0,
|
|
width: ACTION_WIDTH,
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
},
|
|
deleteButton: {
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
width: ACTION_WIDTH,
|
|
height: "100%",
|
|
paddingHorizontal: 10,
|
|
},
|
|
actionContent: {
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
gap: 4,
|
|
},
|
|
actionText: {
|
|
fontSize: 12,
|
|
fontWeight: "600",
|
|
textAlign: "center",
|
|
},
|
|
});
|