Skip to content

Instantly share code, notes, and snippets.

@bidah
Created May 14, 2025 13:55
Show Gist options
  • Save bidah/c9a648590150e93fe60e0f4ce056909b to your computer and use it in GitHub Desktop.
Save bidah/c9a648590150e93fe60e0f4ce056909b to your computer and use it in GitHub Desktop.
youtube expo universal module
import Fontisto from "@expo/vector-icons/Fontisto";
import React, { useState, useCallback, useEffect } from "react";
import { View, ImageBackground, Pressable } from "react-native";
import YoutubePlayerIframe from "react-native-youtube-iframe";
import { useBoolean } from "@/hooks/use-boolean";
const OverlayPlayerScreen = ({
image,
setToggleOverlay,
}: {
image: string;
setToggleOverlay: {
setTrue: () => void;
setFalse: () => void;
toggle: () => void;
};
}) => {
return (
<ImageBackground
source={{ uri: image }}
className="absolute z-10 h-[210] w-full items-center justify-center"
imageStyle={{
borderRadius: 20,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
}}
>
<Pressable
onPress={setToggleOverlay.setTrue}
className="h-[100%] w-[100%] items-center justify-center"
>
<View className="h-16 w-16 items-center justify-center rounded-full bg-black/70">
<Fontisto name="play" size={24} color="white" style={{ left: 3 }} />
</View>
</Pressable>
</ImageBackground>
);
};
export function YoutubePlayer({ image, url }: { image: string; url: string }) {
const [playing, setPlaying] = useState(false);
const { value: toggleOverlay, ...toggleOverlayControls } = useBoolean(false);
const onStateChange = useCallback((state) => {
if (state === "ended") {
setPlaying(false);
}
}, []);
useEffect(() => {
if (toggleOverlay) {
setPlaying(true);
}
}, [toggleOverlay]);
return (
<View>
{!toggleOverlay && (
<OverlayPlayerScreen
image={image}
setToggleOverlay={toggleOverlayControls}
/>
)}
<YoutubePlayerIframe
webViewStyle={{
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
}}
height={210}
play={playing}
videoId={
url?.includes("youtu.be")
? url.split("/").pop()
: url?.split("v=")[1]?.split("&")[0]
}
onChangeState={onStateChange}
/>
</View>
);
}
import React, { useState, useCallback, useEffect, useRef } from "react";
import { View, Alert, ImageBackground, Pressable } from "react-native";
import YouTube, { type YouTubeProps } from "react-youtube";
import Fontisto from "@expo/vector-icons/Fontisto";
import { useBoolean } from "@/hooks/use-boolean";
const OverlayPlayerScreen = ({
image,
setToggleOverlay,
}: {
image: string;
setToggleOverlay: {
setTrue: () => void;
setFalse: () => void;
toggle: () => void;
};
}) => {
return (
<ImageBackground
source={{ uri: image }}
className="z-10 aspect-video bg-white"
resizeMode="contain"
imageStyle={{
borderRadius: 20,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
}}
>
<Pressable
onPress={setToggleOverlay.setTrue}
className="h-[100%] w-[100%] items-center justify-center"
>
<View className="h-16 w-16 items-center justify-center rounded-full bg-black/70">
<Fontisto name="play" size={24} color="white" style={{ left: 3 }} />
</View>
</Pressable>
</ImageBackground>
);
};
export function YoutubePlayer({ image, url }: { image: string; url: string }) {
const [playing, setPlaying] = useState(false);
const { value: toggleOverlay, ...toggleOverlayControls } = useBoolean(false);
const playerRef = useRef<YouTube>(null);
useEffect(() => {
if (toggleOverlay && playerRef.current) {
playerRef.current.internalPlayer.playVideo();
setPlaying(true);
}
}, [toggleOverlay]);
const onReady: YouTubeProps["onReady"] = (event) => {
// No necesitamos hacer nada aquí ahora
};
const onStateChange: YouTubeProps["onStateChange"] = (event) => {
if (event.data === YouTube.PlayerState.ENDED) {
setPlaying(false);
Alert.alert("Video has finished playing!");
}
};
const opts: YouTubeProps["opts"] = {
height: "100%",
width: "100%",
aspectRatio: 16 / 9,
playerVars: {
autoplay: playing ? 1 : 0,
},
};
return (
<View>
{!toggleOverlay && (
<OverlayPlayerScreen
image={image}
setToggleOverlay={toggleOverlayControls}
/>
)}
<YouTube
videoId={
url?.includes("youtu.be")
? url.split("/").pop()
: url?.split("v=")[1]?.split("&")[0]
}
opts={opts}
onReady={onReady}
onStateChange={onStateChange}
className="aspect-video rounded-t-[20px]"
ref={playerRef}
/>
</View>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment