120 lines
3.8 KiB
TypeScript
120 lines
3.8 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
|
|
function App() {
|
|
const [screenStatus, setScreenStatus] = useState<
|
|
"notfullscreen" | "fullscreen"
|
|
>("notfullscreen");
|
|
const [text, setText] = useState("");
|
|
const [imageUrl, setImageUrl] = useState("");
|
|
|
|
useEffect(() => {
|
|
const handleFullscreenChange = () => {
|
|
if (!document.fullscreenElement) {
|
|
setScreenStatus("notfullscreen");
|
|
} else {
|
|
setScreenStatus("fullscreen");
|
|
}
|
|
};
|
|
|
|
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
|
|
return () => {
|
|
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (screenStatus === "fullscreen") {
|
|
const handlePullState = () => {
|
|
fetch(
|
|
"https://shsf-api.reversed.dev/api/exec/15/1c44d8b5-4065-4a54-b259-748561021329/pull_full",
|
|
)
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
setText(data.state?.text ?? "");
|
|
setImageUrl(data.state?.image_url ?? "");
|
|
})
|
|
.catch((error) => {
|
|
console.error("Error pulling state:", error);
|
|
});
|
|
};
|
|
|
|
handlePullState(); // Initial pull when entering fullscreen
|
|
const interval = setInterval(handlePullState, 5000); // Poll every 5 seconds
|
|
|
|
return () => clearInterval(interval);
|
|
}
|
|
}, [screenStatus]);
|
|
|
|
return (
|
|
<>
|
|
{screenStatus === "notfullscreen" ? (
|
|
<div className="flex flex-col items-center gap-8 px-8 text-center">
|
|
<div className="flex flex-col items-center gap-2">
|
|
<div className="w-16 h-16 rounded-2xl bg-gray-800 border border-gray-700 flex items-center justify-center mb-2">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className="w-8 h-8 text-gray-400"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
strokeWidth={1.5}
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
d="M6 8V6a2 2 0 012-2h8a2 2 0 012 2v2M6 16v2a2 2 0 002 2h8a2 2 0 002-2v-2M3 12h18"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<h1 className="text-3xl font-semibold tracking-tight text-white">
|
|
TV View
|
|
</h1>
|
|
<p className="text-gray-500 text-sm max-w-xs">
|
|
Enter fullscreen mode to enter fullscreen mode.
|
|
</p>
|
|
</div>
|
|
|
|
<button
|
|
onClick={() => document.documentElement.requestFullscreen()}
|
|
className="group flex items-center gap-2 bg-white text-gray-900 font-medium px-6 py-3 rounded-xl hover:bg-gray-200 active:scale-95 transition-all duration-150 cursor-pointer"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className="w-4 h-4"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
strokeWidth={2}
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
d="M4 8V4m0 0h4M4 4l5 5m11-5h-4m4 0v4m0-4l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"
|
|
/>
|
|
</svg>
|
|
Go Fullscreen
|
|
</button>
|
|
</div>
|
|
) : (
|
|
<div className="flex flex-col items-center gap-6 text-center w-full h-full justify-center">
|
|
{imageUrl && (
|
|
<img
|
|
src={imageUrl}
|
|
alt="TV display"
|
|
className="max-w-full max-h-[70vh] rounded-2xl object-contain shadow-2xl"
|
|
/>
|
|
)}
|
|
{text && (
|
|
<h1 className="text-4xl font-bold tracking-tight text-white">
|
|
{text}
|
|
</h1>
|
|
)}
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default App;
|