comments
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 457 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 273 KiB |
@@ -3,8 +3,10 @@ import React from "react";
|
||||
import ActionSheet from "react-native-actions-sheet";
|
||||
import { gutters, Palette } from "../styles";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
|
||||
const AppActionSheet = ({ children, props }) => {
|
||||
const insets = useSafeAreaInsets();
|
||||
return (
|
||||
<ActionSheet
|
||||
containerStyle={{ backgroundColor: Palette.tran }}
|
||||
@@ -21,7 +23,7 @@ const AppActionSheet = ({ children, props }) => {
|
||||
style={{
|
||||
paddingTop: 36,
|
||||
paddingHorizontal: 14,
|
||||
paddingBottom: gutters,
|
||||
paddingBottom: gutters + (insets?.bottom || 0),
|
||||
backgroundColor: Palette.glass,
|
||||
borderTopLeftRadius: 20,
|
||||
borderTopRightRadius: 20,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React, { useState, useCallback, useEffect } from "react";
|
||||
import { Keyboard, StyleSheet } from "react-native";
|
||||
import { AnimatePresence, Motion } from "@legendapp/motion";
|
||||
import { useKeyboard } from "@react-native-community/hooks";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { Keyboard, StyleSheet } from "react-native";
|
||||
|
||||
import BottomSheet from "./BottomSheet";
|
||||
|
||||
import { Palette } from "../styles";
|
||||
import useLayoutType from "../hooks/useLayoutType";
|
||||
import { Palette } from "../styles";
|
||||
|
||||
export default ({
|
||||
children,
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
import { BlurView } from "expo-blur";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import {
|
||||
Image,
|
||||
Platform,
|
||||
Pressable,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { icons } from "../../assets";
|
||||
import { projectsRef, serverTimestamp } from "../../config/firebase";
|
||||
import useDataFromRef from "../../hooks/useDataFromRef";
|
||||
import { useUser } from "../../providers/UserDataProvider";
|
||||
import { Palette } from "../../styles";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import { size } from "../../styles/Style";
|
||||
import AppActionSheet from "../AppActionSheet";
|
||||
|
||||
const formatRelativeTime = (date) => {
|
||||
try {
|
||||
const d = date instanceof Date ? date : date?.toDate?.() || null;
|
||||
if (!d) return "";
|
||||
const diff = Math.max(0, Date.now() - d.getTime());
|
||||
const sec = Math.floor(diff / 1000);
|
||||
if (sec < 60) return `${sec}s`;
|
||||
const min = Math.floor(sec / 60);
|
||||
if (min < 60) return `${min}min`;
|
||||
const h = Math.floor(min / 60);
|
||||
if (h < 24) return `${h}h`;
|
||||
const dA = Math.floor(h / 24);
|
||||
return `${dA}j`;
|
||||
} catch (e) {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
const CommentsModal = ({ sheetId, payload }) => {
|
||||
const projectId = payload?.projectId || null;
|
||||
const { currentUID, currentUserData } = useUser();
|
||||
const [text, setText] = useState("");
|
||||
|
||||
const commentsRef = useMemo(() => {
|
||||
try {
|
||||
return projectId
|
||||
? projectsRef
|
||||
.doc(projectId)
|
||||
.collection("comments")
|
||||
.orderBy("createdAt", "desc")
|
||||
: null;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}, [projectId]);
|
||||
|
||||
const { data: comments = [] } = useDataFromRef({
|
||||
ref: commentsRef,
|
||||
simpleRef: false,
|
||||
listener: true,
|
||||
condition: !!commentsRef,
|
||||
refreshArray: [projectId],
|
||||
});
|
||||
|
||||
const onSend = async () => {
|
||||
const value = (text || "").trim();
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<AppActionSheet id="Comments" props={{ gestureEnabled: true }}>
|
||||
<View style={{ gap: 14 }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 22,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
alignSelf: "center",
|
||||
}}
|
||||
>
|
||||
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 }}>
|
||||
{c?.profilePicture ? (
|
||||
<Image
|
||||
source={{ uri: c.profilePicture }}
|
||||
cachePolicy="memory-disk"
|
||||
priority="high"
|
||||
contentFit="cover"
|
||||
transition={100}
|
||||
style={{ ...size({ size: 42 }), borderRadius: 100 }}
|
||||
/>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
...size({ size: 42 }),
|
||||
borderRadius: 100,
|
||||
backgroundColor: "#FFFFFF22",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<View style={{ flex: 1 }}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: 6,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterMedium,
|
||||
}}
|
||||
>
|
||||
{c?.userId === currentUID ? "vous" : c?.userName || ""}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: Palette.white,
|
||||
opacity: 0.75,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
}}
|
||||
>
|
||||
• {formatRelativeTime(c?.createdAt)}
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
}}
|
||||
>
|
||||
{c?.text}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
))
|
||||
) : (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
opacity: 0.8,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
textAlign: "center",
|
||||
marginTop: 6,
|
||||
}}
|
||||
>
|
||||
Aucun commentaire pour le moment
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View style={{ marginTop: 6 }}>
|
||||
<BlurView
|
||||
intensity={20}
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: 10,
|
||||
paddingHorizontal: 16,
|
||||
backgroundColor: Palette.glass,
|
||||
borderRadius: 16,
|
||||
overflow: "hidden",
|
||||
height: 54,
|
||||
}}
|
||||
experimentalBlurMethod={
|
||||
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
|
||||
}
|
||||
>
|
||||
<TextInput
|
||||
placeholder="Ajouter un commentaire"
|
||||
placeholderTextColor="#FFFFFFAA"
|
||||
value={text}
|
||||
onChangeText={setText}
|
||||
style={{
|
||||
flex: 1,
|
||||
color: Palette.white,
|
||||
fontSize: 14,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
}}
|
||||
/>
|
||||
<Pressable onPress={onSend}>
|
||||
<Image
|
||||
source={icons.send}
|
||||
style={{ width: 24, height: 24, tintColor: Palette.white }}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
</Pressable>
|
||||
</BlurView>
|
||||
</View>
|
||||
</View>
|
||||
</AppActionSheet>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommentsModal;
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { useState, useRef, createContext } from "react";
|
||||
import { View, TouchableOpacity } from "react-native";
|
||||
import { Motion } from "@legendapp/motion";
|
||||
import React, { createContext, useRef, useState } from "react";
|
||||
import { TouchableOpacity, View } from "react-native";
|
||||
|
||||
import { mainBorderRadius } from "../styles/Style";
|
||||
import { Palette } from "../styles";
|
||||
import { mainBorderRadius } from "../styles/Style";
|
||||
|
||||
export const BottomSheetContext = createContext();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
import { Image, Platform, Pressable, Text, View } from "react-native";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import Carousel from "react-native-reanimated-carousel";
|
||||
import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { icons, img } from "../assets";
|
||||
@@ -353,6 +354,18 @@ const PlaybackItem = ({ item, isActive, userCache, getUserByUid }) => {
|
||||
</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
if (item?.id) {
|
||||
SheetManager.show("Comments", {
|
||||
payload: { projectId: item.id },
|
||||
});
|
||||
}
|
||||
}}
|
||||
style={{ alignItems: "center" }}
|
||||
>
|
||||
<Image source={icons.message} style={size({ size: 26 })} />
|
||||
</Pressable>
|
||||
<Pressable>
|
||||
<Image source={icons.share} style={size({ size: 26 })} />
|
||||
</Pressable>
|
||||
|
||||
@@ -5,6 +5,7 @@ import DeleteAccountModal from "../components/modal/DeleteAccountModal";
|
||||
import DeletePlaybackModal from "../components/modal/DeletePlaybackModal";
|
||||
import DeleteAudioModal from "../components/modal/DeleteAudioModal";
|
||||
import PlaylistModal from "../components/modal/PlaylistModal";
|
||||
import CommentsModal from "../components/modal/CommentsModal";
|
||||
|
||||
registerSheet("Delete", DeleteModal);
|
||||
registerSheet("ProfileSettings", ProfileSettingsModal);
|
||||
@@ -12,5 +13,6 @@ registerSheet("DeleteAccount", DeleteAccountModal);
|
||||
registerSheet("DeletePlayback", DeletePlaybackModal);
|
||||
registerSheet("DeleteAudio", DeleteAudioModal);
|
||||
registerSheet("Playlist", PlaylistModal);
|
||||
registerSheet("Comments", CommentsModal);
|
||||
|
||||
export {};
|
||||
|
||||
Reference in New Issue
Block a user