This commit is contained in:
2025-09-03 14:55:01 +02:00
parent 2b24900e0c
commit 64fd988d2f
9 changed files with 187 additions and 123 deletions
+4 -4
View File
@@ -1,9 +1,9 @@
import { View, Text, Platform } from "react-native";
import React from "react";
import ActionSheet from "react-native-actions-sheet";
import { gutters, Palette } from "../styles";
import { BlurView } from "expo-blur";
import React from "react";
import { Platform } from "react-native";
import ActionSheet from "react-native-actions-sheet";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { gutters, Palette } from "../styles";
const AppActionSheet = ({ children, props }) => {
const insets = useSafeAreaInsets();
@@ -1,5 +1,18 @@
// CommentsBottomSheet.jsx
import {
BottomSheetBackdrop,
BottomSheetModal,
BottomSheetScrollView,
} from "@gorhom/bottom-sheet";
import { BlurView } from "expo-blur";
import React, { useMemo, useState } from "react";
import { Image as ExpoImage } from "expo-image";
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import {
Image,
Platform,
@@ -8,6 +21,7 @@ import {
TextInput,
View,
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { icons } from "../../assets";
import { projectsRef, serverTimestamp } from "../../config/firebase";
import useDataFromRef from "../../hooks/useDataFromRef";
@@ -15,7 +29,11 @@ import { useUser } from "../../providers/UserDataProvider";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import { size } from "../../styles/Style";
import AppActionSheet from "../AppActionSheet";
let externalOpen;
export const openComments = (projectId) => {
if (typeof externalOpen === "function") externalOpen(projectId);
};
const formatRelativeTime = (date) => {
try {
@@ -35,10 +53,26 @@ const formatRelativeTime = (date) => {
}
};
const CommentsModal = ({ sheetId, payload }) => {
const projectId = payload?.projectId || null;
const CommentsBottomSheet = () => {
const modalRef = useRef(null);
const insets = useSafeAreaInsets();
const { currentUID, currentUserData } = useUser();
const [projectId, setProjectId] = useState(null);
const [text, setText] = useState("");
const [typing, setTyping] = useState(false);
useEffect(() => {
externalOpen = (pid) => {
setProjectId(pid || null);
requestAnimationFrame(() => modalRef.current?.present());
};
return () => {
externalOpen = undefined;
};
}, []);
const snapPoints = useMemo(() => ["50%", "90%"], []);
const commentsRef = useMemo(() => {
try {
@@ -48,7 +82,7 @@ const CommentsModal = ({ sheetId, payload }) => {
.collection("comments")
.orderBy("createdAt", "desc")
: null;
} catch (e) {
} catch {
return null;
}
}, [projectId]);
@@ -66,38 +100,84 @@ const CommentsModal = ({ sheetId, payload }) => {
if (!value || !projectId || !currentUID) return;
try {
setText("");
const docRef = projectsRef.doc(projectId).collection("comments");
await docRef.add({
userId: currentUID,
userName: currentUserData?.userName || "",
profilePicture: currentUserData?.profilePictureURL || "",
text: value,
createdAt: serverTimestamp(),
});
} catch (e) {
// Ignore
await projectsRef
.doc(projectId)
.collection("comments")
.add({
userId: currentUID,
userName: currentUserData?.userName || "",
profilePicture: currentUserData?.profilePictureURL || "",
text: value,
createdAt: serverTimestamp(),
});
} catch {
// ignore
}
};
const renderBackdrop = useCallback(
(props) => (
<BottomSheetBackdrop
{...props}
appearsOnIndex={0}
disappearsOnIndex={-1}
pressBehavior={typing ? "none" : "close"}
/>
),
[typing]
);
return (
<AppActionSheet id="Comments" props={{ gestureEnabled: true }}>
<View style={{ gap: 14 }}>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
alignSelf: "center",
<BottomSheetModal
ref={modalRef}
snapPoints={snapPoints}
keyboardBehavior="interactive" // linput est dans le contenu → mode interactif OK
keyboardBlurBehavior="restore"
enablePanDownToClose={!typing} // évite un dismiss pendant la frappe
enableContentPanningGesture={!typing}
stackBehavior="push"
topInset={insets.top}
bottomInset={insets.bottom}
backdropComponent={renderBackdrop}
handleIndicatorStyle={{ backgroundColor: Palette.white }}
backgroundStyle={{ backgroundColor: "transparent" }}
>
<BlurView
intensity={20}
style={{ flex: 1, backgroundColor: Palette.glass }}
experimentalBlurMethod={
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
}
>
<View style={{ paddingTop: 10, paddingBottom: 8 }}>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
alignSelf: "center",
}}
>
Commentaires
</Text>
</View>
<BottomSheetScrollView
keyboardShouldPersistTaps="handled"
contentContainerStyle={{
paddingHorizontal: 14,
paddingBottom: (insets?.bottom || 0) + 12,
}}
showsVerticalScrollIndicator
>
Commentaires
</Text>
<View style={{ gap: 14, maxHeight: 400 }}>
{Array.isArray(comments) && comments.length > 0 ? (
comments.map((c) => (
<View key={c.id} style={{ flexDirection: "row", gap: 12 }}>
<View
key={c.id}
style={{ flexDirection: "row", gap: 12, marginBottom: 14 }}
>
{c?.profilePicture ? (
<Image
<ExpoImage
source={{ uri: c.profilePicture }}
cachePolicy="memory-disk"
priority="high"
@@ -168,9 +248,9 @@ const CommentsModal = ({ sheetId, payload }) => {
Aucun commentaire pour le moment
</Text>
)}
</View>
<View style={{ marginTop: 6 }}>
{/* INPUT en bas du contenu */}
<View style={{ height: 12 }} />
<BlurView
intensity={20}
style={{
@@ -179,9 +259,9 @@ const CommentsModal = ({ sheetId, payload }) => {
gap: 10,
paddingHorizontal: 16,
backgroundColor: Palette.glass,
borderRadius: 16,
overflow: "hidden",
height: 54,
borderRadius: 16,
}}
experimentalBlurMethod={
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
@@ -192,6 +272,8 @@ const CommentsModal = ({ sheetId, payload }) => {
placeholderTextColor="#FFFFFFAA"
value={text}
onChangeText={setText}
onFocus={() => setTyping(true)}
onBlur={() => setTyping(false)}
style={{
flex: 1,
color: Palette.white,
@@ -207,10 +289,11 @@ const CommentsModal = ({ sheetId, payload }) => {
/>
</Pressable>
</BlurView>
</View>
</View>
</AppActionSheet>
<View style={{ height: (insets?.bottom || 0) + 8 }} />
</BottomSheetScrollView>
</BlurView>
</BottomSheetModal>
);
};
export default CommentsModal;
export default CommentsBottomSheet;