feat: start video

This commit is contained in:
2025-12-03 16:11:44 +01:00
parent f6cb467929
commit 13f34d3ef1
4 changed files with 104 additions and 21 deletions
+2
View File
@@ -38,6 +38,7 @@ import { LogBox } from "react-native";
import CommentsBottomSheet from "./src/components/bottomsheets/CommentsBottomSheet"; import CommentsBottomSheet from "./src/components/bottomsheets/CommentsBottomSheet";
import ShareQrModalContainer from "./src/components/modal/ShareQrModalContainer"; import ShareQrModalContainer from "./src/components/modal/ShareQrModalContainer";
import AppDownloadBanner from "./src/components/AppDownloadBanner"; import AppDownloadBanner from "./src/components/AppDownloadBanner";
import MobileSplashVideo from "./src/components/MobileSplashVideo";
import "./src/utils/Sheet"; import "./src/utils/Sheet";
console.disableYellowBox = true; console.disableYellowBox = true;
@@ -219,6 +220,7 @@ const App = () => {
<CommentsBottomSheet /> <CommentsBottomSheet />
<ShareQrModalContainer /> <ShareQrModalContainer />
<AppDownloadBanner /> <AppDownloadBanner />
<MobileSplashVideo />
{/* </AppLayout> */} {/* </AppLayout> */}
</MenuProvider> </MenuProvider>
</Providers> </Providers>
+81
View File
@@ -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 ? (
<Portal>
<View pointerEvents="auto" style={styles.blocker} />
</Portal>
) : null}
{visible ? (
<FullscreenIntroVideo
url={splashVideoUrl}
visible={visible}
onClose={handleClose}
/>
) : null}
</>
);
};
const styles = StyleSheet.create({
blocker: {
...StyleSheet.absoluteFillObject,
backgroundColor: "black",
zIndex: 9998,
},
});
export default MobileSplashVideo;
+16 -16
View File
@@ -80,14 +80,14 @@ export default ({
const nestedSubscription = const nestedSubscription =
currentUserData?.subscription && currentUserData?.subscription &&
typeof currentUserData.subscription === "object" typeof currentUserData.subscription === "object"
? currentUserData.subscription ? currentUserData.subscription
: null; : null;
const stripeMetadata = const stripeMetadata =
currentUserData?.stripeSubscription && currentUserData?.stripeSubscription &&
typeof currentUserData.stripeSubscription === "object" && typeof currentUserData.stripeSubscription === "object" &&
typeof currentUserData.stripeSubscription.metadata === "object" typeof currentUserData.stripeSubscription.metadata === "object"
? currentUserData.stripeSubscription.metadata ? currentUserData.stripeSubscription.metadata
: null; : null;
@@ -100,18 +100,18 @@ export default ({
const nestedCandidates = nestedSubscription const nestedCandidates = nestedSubscription
? ["level", "plan", "pack", "type"].map((key) => ? ["level", "plan", "pack", "type"].map((key) =>
pickLevel(nestedSubscription?.[key]), pickLevel(nestedSubscription?.[key]),
) )
: []; : [];
const metadataCandidates = stripeMetadata const metadataCandidates = stripeMetadata
? [ ? [
"level", "level",
"subscriptionLevel", "subscriptionLevel",
"subscription_level", "subscription_level",
"pack", "pack",
"Pack", "Pack",
].map((key) => pickLevel(stripeMetadata?.[key])) ].map((key) => pickLevel(stripeMetadata?.[key]))
: []; : [];
const resolvedLevel = [ const resolvedLevel = [
@@ -293,11 +293,11 @@ export default ({
style={{ flex: 1, ...resolvedContentContainerStyle }} style={{ flex: 1, ...resolvedContentContainerStyle }}
{...(scrollEnabled {...(scrollEnabled
? { ? {
scrollEventThrottle: 80, scrollEventThrottle: 80,
showsVerticalScrollIndicator: false, showsVerticalScrollIndicator: false,
contentContainerStyle: { paddingBottom: responsiveHeight(55) }, contentContainerStyle: { paddingBottom: responsiveHeight(55) },
keyboardDismissMode: "on-drag", keyboardDismissMode: "on-drag",
} }
: {})} : {})}
> >
{children} {children}
+5 -5
View File
@@ -55,8 +55,8 @@ export default ({ children }) => {
useDataFromRef({ useDataFromRef({
ref: currentUID ref: currentUID
? projectsRef ? projectsRef
.where("userId", "==", currentUID) .where("userId", "==", currentUID)
.orderBy("updatedAt", "desc") .orderBy("updatedAt", "desc")
: null, : null,
simpleRef: false, simpleRef: false,
listener: true, listener: true,
@@ -299,9 +299,9 @@ export default ({ children }) => {
const userDoc = await usersRef.doc(uid).get(); const userDoc = await usersRef.doc(uid).get();
return userDoc.exists return userDoc.exists
? { ? {
id: userDoc.id, id: userDoc.id,
...userDoc.data(), ...userDoc.data(),
} }
: null; : null;
} catch (e) { } catch (e) {
console.log(e); console.log(e);