new tickets
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import React, { useCallback, useEffect, useRef } from "react";
|
||||
import { View, Pressable, Text } from "react-native";
|
||||
import { VideoView, useVideoPlayer } from "expo-video";
|
||||
import { videos } from "../assets";
|
||||
@@ -10,37 +10,73 @@ import { Portal } from "@gorhom/portal";
|
||||
// - visible?: boolean, when false returns null
|
||||
// - onClose: () => void, called when user skips or when video ends
|
||||
const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
||||
if (!visible) return null;
|
||||
const source = url
|
||||
? typeof url === "string"
|
||||
? { uri: url }
|
||||
: url
|
||||
: videos.test;
|
||||
|
||||
const hasClosedRef = useRef(false);
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
if (hasClosedRef.current) return;
|
||||
hasClosedRef.current = true;
|
||||
try {
|
||||
onClose?.();
|
||||
} catch (e) {}
|
||||
}, [onClose]);
|
||||
|
||||
const player = useVideoPlayer(source, (p) => {
|
||||
p.loop = false;
|
||||
p.timeUpdateEventInterval = 0.25;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
hasClosedRef.current = false;
|
||||
} else {
|
||||
hasClosedRef.current = true;
|
||||
try {
|
||||
player?.pause?.();
|
||||
} catch (e) {}
|
||||
}
|
||||
}, [player, visible]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!visible) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
player?.play?.();
|
||||
} catch (e) {}
|
||||
}, [player]);
|
||||
}, [player, visible]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!player) return;
|
||||
const sub = player.addListener?.("playToEnd", () => {
|
||||
try {
|
||||
onClose?.();
|
||||
} catch (e) {}
|
||||
});
|
||||
if (!player || !visible) return;
|
||||
const playToEndSub = player.addListener?.("playToEnd", handleClose);
|
||||
const timeUpdateSub = player.addListener?.(
|
||||
"timeUpdate",
|
||||
({ currentTime } = {}) => {
|
||||
if (!player?.duration || hasClosedRef.current) {
|
||||
return;
|
||||
}
|
||||
const remaining = player.duration - currentTime;
|
||||
if (Number.isFinite(remaining) && remaining <= 0.1) {
|
||||
handleClose();
|
||||
}
|
||||
}
|
||||
);
|
||||
return () => {
|
||||
try {
|
||||
sub?.remove?.();
|
||||
playToEndSub?.remove?.();
|
||||
timeUpdateSub?.remove?.();
|
||||
} catch (e) {}
|
||||
};
|
||||
}, [player, onClose]);
|
||||
}, [handleClose, player, visible]);
|
||||
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
@@ -65,7 +101,7 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
||||
style={{ position: "absolute", top: 0, bottom: 0, left: 0, right: 0 }}
|
||||
/>
|
||||
<Pressable
|
||||
onPress={() => onClose?.()}
|
||||
onPress={handleClose}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 50,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Portal } from "@gorhom/portal";
|
||||
import { Asset } from "expo-asset";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Pressable, Text, View } from "react-native";
|
||||
|
||||
const overlayStyle = {
|
||||
@@ -56,6 +56,13 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
||||
const videoRef = useRef(null);
|
||||
const [uri, setUri] = useState(null);
|
||||
const [muted, setMuted] = useState(false);
|
||||
const hasClosedRef = useRef(false);
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
if (hasClosedRef.current) return;
|
||||
hasClosedRef.current = true;
|
||||
onClose?.();
|
||||
}, [onClose]);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
@@ -97,13 +104,15 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
hasClosedRef.current = false;
|
||||
|
||||
const video = videoRef.current;
|
||||
|
||||
if (!video || !uri) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const handleEnded = () => onClose?.();
|
||||
const handleEnded = handleClose;
|
||||
video.addEventListener("ended", handleEnded);
|
||||
|
||||
video.currentTime = 0;
|
||||
@@ -125,7 +134,7 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
||||
video.pause();
|
||||
video.removeEventListener("ended", handleEnded);
|
||||
};
|
||||
}, [muted, onClose, uri, visible]);
|
||||
}, [handleClose, muted, uri, visible]);
|
||||
|
||||
useEffect(() => {
|
||||
const video = videoRef.current;
|
||||
@@ -161,7 +170,7 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
||||
controls={false}
|
||||
/>
|
||||
) : null}
|
||||
<Pressable onPress={() => onClose?.()} style={closeButtonStyle}>
|
||||
<Pressable onPress={handleClose} style={closeButtonStyle}>
|
||||
<Text style={closeTextStyle}>Passer la vidéo</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { View, TextInput, Image } from "react-native";
|
||||
import React from "react";
|
||||
import { BlurView } from "expo-blur";
|
||||
import React from "react";
|
||||
import { Image, TextInput, View } from "react-native";
|
||||
import { icons } from "../assets";
|
||||
import Style, { size } from "../styles/Style";
|
||||
import { Palette } from "../styles";
|
||||
import { FONT_FAMILY } from "../styles/Fonts";
|
||||
import Style from "../styles/Style";
|
||||
|
||||
const SearchBar = ({
|
||||
placeholder = "Que souhaites-tu écouter?",
|
||||
@@ -13,12 +13,13 @@ const SearchBar = ({
|
||||
return (
|
||||
<View style={{ borderRadius: 12, overflow: "hidden" }}>
|
||||
<BlurView
|
||||
intensity={10}
|
||||
intensity={80}
|
||||
style={{
|
||||
height: 40,
|
||||
paddingHorizontal: 8,
|
||||
gap: 10,
|
||||
...Style.containerRow,
|
||||
backgroundColor: "Palette.ultraLightBlack",
|
||||
}}
|
||||
>
|
||||
<Image source={icons.search} />
|
||||
|
||||
@@ -75,10 +75,20 @@ const styles = StyleSheet.create({
|
||||
overlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
zIndex: 200,
|
||||
...Platform.select({
|
||||
web: {
|
||||
position: "fixed",
|
||||
},
|
||||
}),
|
||||
},
|
||||
backdrop: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
backgroundColor: "rgba(0, 0, 0, 0.65)",
|
||||
...Platform.select({
|
||||
web: {
|
||||
position: "fixed",
|
||||
},
|
||||
}),
|
||||
},
|
||||
centerWrapper: {
|
||||
flex: 1,
|
||||
|
||||
Reference in New Issue
Block a user