diff --git a/App.js b/App.js index 3aaba99..47d7762 100644 --- a/App.js +++ b/App.js @@ -38,6 +38,7 @@ import { LogBox } from "react-native"; import CommentsBottomSheet from "./src/components/bottomsheets/CommentsBottomSheet"; import ShareQrModalContainer from "./src/components/modal/ShareQrModalContainer"; import AppDownloadBanner from "./src/components/AppDownloadBanner"; +import MobileSplashVideo from "./src/components/MobileSplashVideo"; import "./src/utils/Sheet"; console.disableYellowBox = true; @@ -219,6 +220,7 @@ const App = () => { + {/* */} diff --git a/src/components/MobileSplashVideo.js b/src/components/MobileSplashVideo.js new file mode 100644 index 0000000..33c0b9e --- /dev/null +++ b/src/components/MobileSplashVideo.js @@ -0,0 +1,81 @@ +import React, { useContext, useEffect, useMemo, useState } from "react"; +import { Platform, StyleSheet, View } from "react-native"; +import { Portal } from "@gorhom/portal"; +import FullscreenIntroVideo from "./FullscreenIntroVideo"; +import { useUser } from "../providers/UserDataProvider"; +import { SplashAnimationContext } from "../providers/SplashAnimationProvider"; + +const BLOCKING_TIMEOUT_MS = 5000; + +// Affiche la vidéo d'intro mobile (videos.splash) juste après le splash screen. +const MobileSplashVideo = () => { + const { videos } = useUser(); + const { isFullyLoaded } = useContext(SplashAnimationContext); + + const [visible, setVisible] = useState(false); + const [hasShown, setHasShown] = useState(false); + const [gaveUp, setGaveUp] = useState(false); + + const splashVideoUrl = useMemo(() => { + if (Platform.OS === "web") return null; + return videos?.splash ?? null; + }, [videos]); + + const shouldAttempt = + Platform.OS !== "web" && isFullyLoaded && !hasShown && !gaveUp; + const showBlockingOverlay = shouldAttempt && !visible; + + useEffect(() => { + if (!shouldAttempt) return; + if (!splashVideoUrl) return; + setVisible(true); + }, [shouldAttempt, splashVideoUrl]); + + useEffect(() => { + if (!showBlockingOverlay) return; + if (splashVideoUrl) return; + + const timeoutId = setTimeout(() => { + setHasShown(true); + setGaveUp(true); + }, BLOCKING_TIMEOUT_MS); + + return () => clearTimeout(timeoutId); + }, [showBlockingOverlay, splashVideoUrl]); + + const handleClose = () => { + setVisible(false); + setHasShown(true); + }; + + if (!showBlockingOverlay && !visible) { + return null; + } + + return ( + <> + {showBlockingOverlay ? ( + + + + ) : null} + {visible ? ( + + ) : null} + + ); +}; + +const styles = StyleSheet.create({ + blocker: { + ...StyleSheet.absoluteFillObject, + backgroundColor: "black", + zIndex: 9998, + }, +}); + +export default MobileSplashVideo; diff --git a/src/layouts/Page.js b/src/layouts/Page.js index 6acc3b4..a844602 100644 --- a/src/layouts/Page.js +++ b/src/layouts/Page.js @@ -80,14 +80,14 @@ export default ({ const nestedSubscription = currentUserData?.subscription && - typeof currentUserData.subscription === "object" + typeof currentUserData.subscription === "object" ? currentUserData.subscription : null; const stripeMetadata = currentUserData?.stripeSubscription && - typeof currentUserData.stripeSubscription === "object" && - typeof currentUserData.stripeSubscription.metadata === "object" + typeof currentUserData.stripeSubscription === "object" && + typeof currentUserData.stripeSubscription.metadata === "object" ? currentUserData.stripeSubscription.metadata : null; @@ -100,18 +100,18 @@ export default ({ const nestedCandidates = nestedSubscription ? ["level", "plan", "pack", "type"].map((key) => - pickLevel(nestedSubscription?.[key]), - ) + pickLevel(nestedSubscription?.[key]), + ) : []; const metadataCandidates = stripeMetadata ? [ - "level", - "subscriptionLevel", - "subscription_level", - "pack", - "Pack", - ].map((key) => pickLevel(stripeMetadata?.[key])) + "level", + "subscriptionLevel", + "subscription_level", + "pack", + "Pack", + ].map((key) => pickLevel(stripeMetadata?.[key])) : []; const resolvedLevel = [ @@ -293,11 +293,11 @@ export default ({ style={{ flex: 1, ...resolvedContentContainerStyle }} {...(scrollEnabled ? { - scrollEventThrottle: 80, - showsVerticalScrollIndicator: false, - contentContainerStyle: { paddingBottom: responsiveHeight(55) }, - keyboardDismissMode: "on-drag", - } + scrollEventThrottle: 80, + showsVerticalScrollIndicator: false, + contentContainerStyle: { paddingBottom: responsiveHeight(55) }, + keyboardDismissMode: "on-drag", + } : {})} > {children} diff --git a/src/providers/UserDataProvider.js b/src/providers/UserDataProvider.js index b9dfdef..303732a 100644 --- a/src/providers/UserDataProvider.js +++ b/src/providers/UserDataProvider.js @@ -55,8 +55,8 @@ export default ({ children }) => { useDataFromRef({ ref: currentUID ? projectsRef - .where("userId", "==", currentUID) - .orderBy("updatedAt", "desc") + .where("userId", "==", currentUID) + .orderBy("updatedAt", "desc") : null, simpleRef: false, listener: true, @@ -299,9 +299,9 @@ export default ({ children }) => { const userDoc = await usersRef.doc(uid).get(); return userDoc.exists ? { - id: userDoc.id, - ...userDoc.data(), - } + id: userDoc.id, + ...userDoc.data(), + } : null; } catch (e) { console.log(e);