new tickets

This commit is contained in:
2025-10-24 14:15:59 +02:00
parent 702e989128
commit 8356b04eb2
10 changed files with 113 additions and 32 deletions
+48 -12
View File
@@ -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,