feat: fixes and formatter
This commit is contained in:
@@ -1,183 +1,183 @@
|
||||
import { Portal } from "@gorhom/portal";
|
||||
import { Asset } from "expo-asset";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Pressable, Text, View } from "react-native";
|
||||
import { Portal } from '@gorhom/portal'
|
||||
import { Asset } from 'expo-asset'
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { Pressable, Text, View } from 'react-native'
|
||||
|
||||
const CLOSE_THRESHOLD_SECONDS = 0.35;
|
||||
const CLOSE_POLL_INTERVAL_MS = 500;
|
||||
const CLOSE_THRESHOLD_SECONDS = 0.35
|
||||
const CLOSE_POLL_INTERVAL_MS = 500
|
||||
|
||||
const overlayStyle = {
|
||||
position: "fixed",
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
backgroundColor: "black",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
backgroundColor: 'black',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
zIndex: 9999,
|
||||
};
|
||||
}
|
||||
|
||||
const videoStyle = {
|
||||
position: "absolute",
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "cover",
|
||||
};
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover',
|
||||
}
|
||||
|
||||
const closeButtonStyle = {
|
||||
position: "absolute",
|
||||
position: 'absolute',
|
||||
top: 50,
|
||||
right: 20,
|
||||
backgroundColor: "#00000080",
|
||||
backgroundColor: '#00000080',
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 14,
|
||||
borderRadius: 20,
|
||||
borderWidth: 1,
|
||||
borderColor: "#FFFFFF55",
|
||||
cursor: "pointer",
|
||||
};
|
||||
borderColor: '#FFFFFF55',
|
||||
cursor: 'pointer',
|
||||
}
|
||||
|
||||
const closeTextStyle = {
|
||||
color: "#FFF",
|
||||
color: '#FFF',
|
||||
fontSize: 14,
|
||||
};
|
||||
}
|
||||
|
||||
const resolveModuleUri = async (module) => {
|
||||
const asset = Asset.fromModule(module);
|
||||
const asset = Asset.fromModule(module)
|
||||
|
||||
if (!asset.localUri && !asset.uri) {
|
||||
await asset.downloadAsync();
|
||||
await asset.downloadAsync()
|
||||
}
|
||||
|
||||
return asset.localUri ?? asset.uri ?? null;
|
||||
};
|
||||
return asset.localUri ?? asset.uri ?? null
|
||||
}
|
||||
|
||||
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 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]);
|
||||
if (hasClosedRef.current) return
|
||||
hasClosedRef.current = true
|
||||
onClose?.()
|
||||
}, [onClose])
|
||||
|
||||
const evaluateShouldClose = useCallback(() => {
|
||||
const video = videoRef.current;
|
||||
const video = videoRef.current
|
||||
|
||||
if (!video || hasClosedRef.current) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
if (video.ended) {
|
||||
handleClose();
|
||||
return;
|
||||
handleClose()
|
||||
return
|
||||
}
|
||||
|
||||
const remaining = video.duration - video.currentTime;
|
||||
const remaining = video.duration - video.currentTime
|
||||
|
||||
if (Number.isFinite(remaining) && remaining <= CLOSE_THRESHOLD_SECONDS) {
|
||||
handleClose();
|
||||
handleClose()
|
||||
}
|
||||
}, [handleClose]);
|
||||
}, [handleClose])
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
let isMounted = true
|
||||
|
||||
const assignUri = (nextUri) => {
|
||||
if (isMounted) {
|
||||
setMuted(false);
|
||||
setUri(nextUri);
|
||||
setMuted(false)
|
||||
setUri(nextUri)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof url === "string") {
|
||||
assignUri(url);
|
||||
if (typeof url === 'string') {
|
||||
assignUri(url)
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
isMounted = false
|
||||
}
|
||||
}
|
||||
|
||||
const load = async () => {
|
||||
try {
|
||||
const nextUri = await resolveModuleUri(url);
|
||||
assignUri(nextUri);
|
||||
const nextUri = await resolveModuleUri(url)
|
||||
assignUri(nextUri)
|
||||
} catch {
|
||||
if (isMounted) {
|
||||
setUri(null);
|
||||
setUri(null)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
load();
|
||||
load()
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, [url]);
|
||||
isMounted = false
|
||||
}
|
||||
}, [url])
|
||||
|
||||
useEffect(() => {
|
||||
if (!visible || !uri) {
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
|
||||
hasClosedRef.current = false;
|
||||
let rafId;
|
||||
hasClosedRef.current = false
|
||||
let rafId
|
||||
|
||||
const attemptPlay = () => {
|
||||
const video = videoRef.current;
|
||||
const video = videoRef.current
|
||||
|
||||
if (!video) {
|
||||
rafId = requestAnimationFrame(attemptPlay);
|
||||
return;
|
||||
rafId = requestAnimationFrame(attemptPlay)
|
||||
return
|
||||
}
|
||||
|
||||
video.currentTime = 0;
|
||||
const result = video.play();
|
||||
video.currentTime = 0
|
||||
const result = video.play()
|
||||
|
||||
if (result?.catch) {
|
||||
result.catch((error) => {
|
||||
if (error?.name === "NotAllowedError" && !muted) {
|
||||
setMuted(true);
|
||||
if (error?.name === 'NotAllowedError' && !muted) {
|
||||
setMuted(true)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
attemptPlay();
|
||||
const pollId = setInterval(evaluateShouldClose, CLOSE_POLL_INTERVAL_MS);
|
||||
attemptPlay()
|
||||
const pollId = setInterval(evaluateShouldClose, CLOSE_POLL_INTERVAL_MS)
|
||||
|
||||
return () => {
|
||||
if (rafId) {
|
||||
cancelAnimationFrame(rafId);
|
||||
cancelAnimationFrame(rafId)
|
||||
}
|
||||
clearInterval(pollId);
|
||||
const video = videoRef.current;
|
||||
video?.pause();
|
||||
};
|
||||
}, [evaluateShouldClose, muted, uri, visible]);
|
||||
clearInterval(pollId)
|
||||
const video = videoRef.current
|
||||
video?.pause()
|
||||
}
|
||||
}, [evaluateShouldClose, muted, uri, visible])
|
||||
|
||||
useEffect(() => {
|
||||
const video = videoRef.current;
|
||||
const video = videoRef.current
|
||||
|
||||
if (!video || !muted) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
const result = video.play();
|
||||
const result = video.play()
|
||||
|
||||
if (result?.catch) {
|
||||
result.catch(() => {});
|
||||
result.catch(() => {})
|
||||
}
|
||||
}, [muted]);
|
||||
}, [muted])
|
||||
|
||||
if (!visible) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -204,7 +204,7 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
||||
</Pressable>
|
||||
</View>
|
||||
</Portal>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default FullscreenIntroVideo;
|
||||
export default FullscreenIntroVideo
|
||||
|
||||
Reference in New Issue
Block a user