diff --git a/App.js b/App.js index 66c9196..207fcce 100644 --- a/App.js +++ b/App.js @@ -36,6 +36,7 @@ import { import "./src/utils/Sheet"; import {LogBox} from "react-native"; +import CommentsBottomSheet from "./src/components/bottomsheets/CommentsBottomSheet"; console.disableYellowBox = true; console.reportErrorsAsExceptions = false; @@ -142,6 +143,7 @@ const App = () => { > + diff --git a/app.json b/app.json index 677a39b..3db0ba1 100644 --- a/app.json +++ b/app.json @@ -16,14 +16,7 @@ "fallbackToCacheTimeout": 0 }, "packagerOpts": { - "sourceExts": [ - "js", - "json", - "ts", - "tsx", - "jsx", - "vue" - ] + "sourceExts": ["js", "json", "ts", "tsx", "jsx", "vue"] }, "splash": { "image": "./assets/splash.png", @@ -35,9 +28,7 @@ "supportsTablet": true, "requireFullScreen": true, "userInterfaceStyle": "dark", - "associatedDomains": [ - "applinks:minuit.starter" - ], + "associatedDomains": ["applinks:minuit.starter"], "bundleIdentifier": "com.minuit.starter", "infoPlist": { "UISupportedInterfaceOrientations": [ @@ -48,10 +39,7 @@ "UIInterfaceOrientationLandscapeLeft", "UIInterfaceOrientationLandscapeRight" ], - "LSApplicationQueriesSchemes": [ - "itms-apps", - "minuit" - ] + "LSApplicationQueriesSchemes": ["itms-apps", "minuit"] }, "config": { "usesNonExemptEncryption": false @@ -62,15 +50,14 @@ "appleTeamId": "W2QZ9CTMYJ" }, "android": { + "softwareKeyboardLayoutMode": "resize", "googleServicesFile": "./config/google-services.json", "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#0A0D12" }, "package": "com.minuit.starter", - "permissions": [ - "android.permission.RECORD_AUDIO" - ] + "permissions": ["android.permission.RECORD_AUDIO"] }, "web": { "bundler": "metro" diff --git a/src/assets/icons/chatBubble.png b/src/assets/icons/chatBubble.png new file mode 100644 index 0000000..e50f09b Binary files /dev/null and b/src/assets/icons/chatBubble.png differ diff --git a/src/assets/index.js b/src/assets/index.js index 1d0550e..0657576 100644 --- a/src/assets/index.js +++ b/src/assets/index.js @@ -1,52 +1,52 @@ -import home from "./UI/tabs/home.png"; -import tasks from "./UI/tabs/tasks.png"; -import chat from "./UI/tabs/chat.png"; -import design from "./UI/tabs/design.png"; -import quotes from "./UI/tabs/quotes.png"; -import settings from "./UI/tabs/settings.png"; import addTab from "./UI/tabs/add.png"; import albums from "./UI/tabs/albums.png"; -import ribbon from "./UI/tabs/ribbon.png"; +import chat from "./UI/tabs/chat.png"; +import design from "./UI/tabs/design.png"; +import home from "./UI/tabs/home.png"; import mic from "./UI/tabs/mic.png"; import person from "./UI/tabs/person.png"; +import quotes from "./UI/tabs/quotes.png"; +import ribbon from "./UI/tabs/ribbon.png"; +import settings from "./UI/tabs/settings.png"; +import tasks from "./UI/tabs/tasks.png"; import bell from "./UI/bell.png"; import sort from "./UI/sort.png"; -import chevronDown from "./UI/chevronDown.png"; import arrowRight from "./UI/arrowRight.png"; +import chevronDown from "./UI/chevronDown.png"; import threeDots from "./UI/threeDots.png"; -import thumbUp from "./UI/thumbUp.png"; import thumbDown from "./UI/thumbDown.png"; +import thumbUp from "./UI/thumbUp.png"; import add from "./UI/add.png"; -import search from "./UI/search.png"; import addFile from "./UI/addFile.png"; -import send from "./UI/send.png"; -import eye from "./UI/eye.png"; -import edit from "./UI/edit.png"; -import trash from "./UI/trash.png"; -import message from "./UI/message.png"; import check from "./UI/check.png"; import checkCircle from "./UI/checkCircle.png"; -import undo from "./UI/undo.png"; -import shoppingBag from "./UI/shoppingBag.png"; -import lock from "./UI/lock.png"; import deliveryTime from "./UI/deliveryTime.png"; +import edit from "./UI/edit.png"; +import eye from "./UI/eye.png"; +import lock from "./UI/lock.png"; +import message from "./UI/message.png"; +import search from "./UI/search.png"; +import send from "./UI/send.png"; +import shoppingBag from "./UI/shoppingBag.png"; import tools from "./UI/tools.png"; +import trash from "./UI/trash.png"; +import undo from "./UI/undo.png"; +import focus from "./UI/focus.png"; import picture from "./UI/picture.png"; import screenshot from "./UI/screenshot.png"; -import focus from "./UI/focus.png"; import android from "./UI/android.png"; import ios from "./UI/ios.png"; import web from "./UI/web.png"; -import user from "./UI/user.png"; import law from "./UI/law.png"; import support from "./UI/support.png"; +import user from "./UI/user.png"; import attachment from "./UI/attachment.png"; @@ -54,65 +54,63 @@ import cloud from "./icons/cloud.png"; import dashboard from "./icons/dashboard.png"; import file from "./icons/file.png"; -import figma from "./icons/figma.png"; -import gitlab from "./icons/gitlab.png"; +import circle from "./art/circle.png"; +import gradientTriangle from "./art/gradientTriangle.png"; +import square from "./art/square.png"; +import triangle from "./art/triangle.png"; import algolia from "./icons/algolia.png"; -import play from "./icons/play.png"; -import disk from "./icons/disk.png"; -import stars from "./icons/stars.png"; -import musicLandLogo from "./icons/musicLandLogo.png"; +import calendar from "./icons/calendar.png"; +import chatBubble from "./icons/chatBubble.png"; import close from "./icons/close.png"; +import coin from "./icons/coin.png"; +import disk from "./icons/disk.png"; +import figma from "./icons/figma.png"; +import forward from "./icons/forward.png"; +import gitlab from "./icons/gitlab.png"; import heart from "./icons/heart.png"; import heartOutline from "./icons/heartOutline.png"; -import more from "./icons/more.png"; -import forward from "./icons/forward.png"; -import pause from "./icons/pause.png"; -import share from "./icons/share.png"; import hitParadeLogo from "./icons/hitParadeLogo.png"; -import calendar from "./icons/calendar.png"; -import coin from "./icons/coin.png"; +import more from "./icons/more.png"; +import musicLandLogo from "./icons/musicLandLogo.png"; +import pause from "./icons/pause.png"; +import play from "./icons/play.png"; +import share from "./icons/share.png"; +import stars from "./icons/stars.png"; -import triangle from "./art/triangle.png"; -import circle from "./art/circle.png"; -import square from "./art/square.png"; -import gradientTriangle from "./art/gradientTriangle.png"; - -import threeCoins from "./art/threeCoins.png"; import boost from "./art/boost.png"; import boostBig from "./art/boostBig.png"; +import threeCoins from "./art/threeCoins.png"; -import welcome from "./tutorial/welcome.png"; import tutorialChat from "./tutorial/chat.png"; import coins from "./tutorial/coins.png"; import followProgress from "./tutorial/followProgress.png"; import tutorialTasks from "./tutorial/tasks.png"; +import welcome from "./tutorial/welcome.png"; -import loginAppDashboard from "./mockups/loginAppDashboard.png"; - -import writingBG from "./UI/writingBG.png"; -import studioBG from "./UI/studioBG.png"; -import studioBG2 from "./UI/studioBG2.png"; -import productionBG from "./UI/productionBG.png"; -import productionBG2 from "./UI/productionBG2.png"; -import playbackBG from "./UI/playbackBG.png"; -import playbackBG2 from "./UI/playbackBG2.png"; -import libraryBG from "./UI/libraryBG.png"; -import libraryBG2 from "./UI/libraryBG2.png"; -import profileBG from "./UI/profileBG.png"; import hitParadeBG from "./UI/hitParadeBG.png"; import homeBG from "./UI/homeBG.png"; +import libraryBG from "./UI/libraryBG.png"; +import libraryBG2 from "./UI/libraryBG2.png"; +import playbackBG from "./UI/playbackBG.png"; +import playbackBG2 from "./UI/playbackBG2.png"; +import productionBG from "./UI/productionBG.png"; +import productionBG2 from "./UI/productionBG2.png"; +import profileBG from "./UI/profileBG.png"; +import studioBG from "./UI/studioBG.png"; +import studioBG2 from "./UI/studioBG2.png"; +import writingBG from "./UI/writingBG.png"; -import nathalie from "./UI/nathalie.png"; -import theo from "./UI/theo.png"; import bena from "./UI/bena.png"; import john from "./UI/john.png"; +import nathalie from "./UI/nathalie.png"; +import theo from "./UI/theo.png"; +import goodVibe from "./UI/goodVibe.png"; import placeholder from "./UI/placeholder.jpg"; import placeholder2 from "./UI/placeholder2.jpg"; import placeholder3 from "./UI/placeholder3.png"; import placeholder4 from "./UI/placeholder4.jpg"; import profile from "./UI/profile.jpg"; -import goodVibe from "./UI/goodVibe.png"; export const tabs = { home, @@ -139,7 +137,7 @@ export const icons = { thumbUp, thumbDown, - + chatBubble, add, search, addFile, diff --git a/src/components/AppActionSheet.js b/src/components/AppActionSheet.js index 77411f1..97617c1 100644 --- a/src/components/AppActionSheet.js +++ b/src/components/AppActionSheet.js @@ -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(); diff --git a/src/components/modal/CommentsModal.js b/src/components/bottomsheets/CommentsBottomSheet.js similarity index 60% rename from src/components/modal/CommentsModal.js rename to src/components/bottomsheets/CommentsBottomSheet.js index d344df3..0abd697 100644 --- a/src/components/modal/CommentsModal.js +++ b/src/components/bottomsheets/CommentsBottomSheet.js @@ -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) => ( + + ), + [typing] + ); + return ( - - - + + + + Commentaires + + + + - Commentaires - - {Array.isArray(comments) && comments.length > 0 ? ( comments.map((c) => ( - + {c?.profilePicture ? ( - { Aucun commentaire pour le moment )} - - + {/* INPUT en bas du contenu */} + { 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 }) => { /> - - - + + + + ); }; -export default CommentsModal; +export default CommentsBottomSheet; diff --git a/src/providers/SharedProviders.js b/src/providers/SharedProviders.js index 1723d96..35018ed 100644 --- a/src/providers/SharedProviders.js +++ b/src/providers/SharedProviders.js @@ -1,6 +1,7 @@ import React from "react"; import { ActionSheetProvider } from "@expo/react-native-action-sheet"; import { SafeAreaProvider } from "react-native-safe-area-context"; +import { BottomSheetModalProvider } from "@gorhom/bottom-sheet"; import UserDataProvider from "./UserDataProvider"; import WebViewProvider from "./WebViewProvider"; @@ -18,6 +19,7 @@ const SharedProviders = ({ children }) => { [UserDataProvider, {}], [StripeEmbeddedProvider, {}], [UniversalLinkProvider, {}], + [BottomSheetModalProvider, {}], [SheetProvider, {}], ]; diff --git a/src/screens/Playbacks.js b/src/screens/Playbacks.js index 515cdd9..73578f5 100644 --- a/src/screens/Playbacks.js +++ b/src/screens/Playbacks.js @@ -10,10 +10,10 @@ 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"; +import { openComments } from "../components/bottomsheets/CommentsBottomSheet"; import KaraokeLyrics from "../components/KaraokeLyrics"; import { arrayRemove, @@ -355,16 +355,10 @@ const PlaybackItem = ({ item, isActive, userCache, getUserByUid }) => { )} { - if (item?.id) { - SheetManager.show("Comments", { - payload: { projectId: item.id }, - }); - } - }} + onPress={() => item?.id && openComments(item.id)} style={{ alignItems: "center" }} > - + diff --git a/src/utils/Sheet.js b/src/utils/Sheet.js index 1a3e645..1ac8bf8 100644 --- a/src/utils/Sheet.js +++ b/src/utils/Sheet.js @@ -5,7 +5,6 @@ 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); @@ -13,6 +12,5 @@ registerSheet("DeleteAccount", DeleteAccountModal); registerSheet("DeletePlayback", DeletePlaybackModal); registerSheet("DeleteAudio", DeleteAudioModal); registerSheet("Playlist", PlaylistModal); -registerSheet("Comments", CommentsModal); export {};