feat: start video
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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
@@ -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}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user