page.tsx (4640B)
1 "use client"; 2 3 import { useEffect, useRef, useState, useCallback } from "react"; 4 import dynamic from "next/dynamic"; 5 import { useRouter } from "next/navigation"; 6 7 export interface StageProps { 8 onComplete: () => void; 9 } 10 11 const Loading = () => <p>loading...</p>; 12 13 //component dynamic import handler 14 const FirstChat = dynamic<StageProps>( 15 () => import("../components/1_chat.tsx"), 16 { 17 loading: Loading, 18 }, 19 ); 20 const SecondDraw = dynamic<StageProps>( 21 () => import("../components/2_draw.tsx"), 22 { 23 loading: Loading, 24 }, 25 ); 26 const ThreeVR = dynamic<StageProps>(() => import("../components/3_vr.tsx"), { 27 loading: Loading, 28 }); 29 const OilArt = dynamic<StageProps>(() => import("../components/4_oil.tsx"), { 30 loading: Loading, 31 }); 32 const FifthTitle = dynamic<StageProps>( 33 () => import("../components/5_title.tsx"), 34 { 35 loading: Loading, 36 }, 37 ); 38 const SixthChat = dynamic<StageProps>( 39 () => import("../components/6_chat.tsx"), 40 { 41 loading: Loading, 42 }, 43 ); 44 const SeventhVR = dynamic<StageProps>(() => import("../components/7_vr.tsx"), { 45 loading: Loading, 46 }); 47 const EighthProtect = dynamic<StageProps>( 48 () => import("../components/8_protectHart.tsx"), 49 { 50 loading: Loading, 51 }, 52 ); 53 const Error = dynamic<StageProps>(() => import("../components/error.tsx"), { 54 loading: Loading, 55 }); 56 57 export default function Play() { 58 const pageRef = useRef<HTMLDivElement>(null); 59 const [isFullscreen, setIsFullscreen] = useState(false); 60 const [isInitialCheckDone, setIsInitialCheckDone] = useState(false); 61 const [stage, setStage] = useState(1); 62 const handleStageComplete = useCallback(() => { 63 setStage((prevStage) => prevStage + 1); 64 }, []); 65 const router = useRouter(); 66 67 useEffect(() => { 68 if (stage === 9) { 69 router.push("/complete"); 70 } 71 }); 72 73 let StageComponent: React.ReactNode; 74 console.log("now, stage is ", stage); 75 switch (stage) { 76 case 1: 77 StageComponent = <FirstChat onComplete={handleStageComplete} />; 78 break; 79 case 2: 80 StageComponent = <SecondDraw onComplete={handleStageComplete} />; 81 break; 82 case 3: 83 StageComponent = <ThreeVR onComplete={handleStageComplete} />; 84 break; 85 case 4: 86 StageComponent = <OilArt onComplete={handleStageComplete} />; 87 break; 88 case 5: 89 StageComponent = <FifthTitle onComplete={handleStageComplete} />; 90 break; 91 case 6: 92 StageComponent = <SixthChat onComplete={handleStageComplete} />; 93 break; 94 case 7: 95 StageComponent = <SeventhVR onComplete={handleStageComplete} />; 96 break; 97 case 8: 98 StageComponent = <EighthProtect onComplete={handleStageComplete} />; 99 break; 100 case 9: 101 StageComponent = <Loading />; 102 break; 103 default: 104 StageComponent = <Error onComplete={handleStageComplete} />; 105 } 106 107 const checkFullscreen = () => { 108 const isTargetFullscreen = document.fullscreenElement === pageRef.current; 109 setIsFullscreen(isTargetFullscreen); 110 }; 111 112 useEffect(() => { 113 // for fullscreen 114 const element = pageRef.current; 115 if (element && element.requestFullscreen) { 116 element 117 .requestFullscreen() 118 .then(() => { 119 checkFullscreen(); 120 }) 121 .catch(() => { 122 setIsFullscreen(false); 123 }) 124 .finally(() => { 125 setIsInitialCheckDone(true); 126 }); 127 } else { 128 setIsFullscreen(false); 129 setIsInitialCheckDone(true); 130 setStage(1); 131 } 132 133 document.addEventListener("fullscreenchange", checkFullscreen); 134 return () => { 135 document.removeEventListener("fullscreenchange", checkFullscreen); 136 }; 137 }, []); 138 139 const enterFullScreen = () => { 140 const element = pageRef.current; 141 if (element && element.requestFullscreen) { 142 element.requestFullscreen().catch(() => { 143 alert("フルスクリーンにできませんでした。"); 144 setIsFullscreen(false); 145 }); 146 } 147 }; 148 149 if (!isInitialCheckDone) { 150 return ( 151 <div ref={pageRef} style={{ height: "100vh", width: "100vw" }}></div> 152 ); 153 } 154 155 return ( 156 <main ref={pageRef} style={{ height: "100vh", width: "100vw" }}> 157 {!isFullscreen ? ( 158 <article 159 style={{ 160 height: "100%", 161 width: "100%", 162 alignItems: "center", 163 justifyContent: "center", 164 display: "flex", 165 }} 166 > 167 <button 168 type="button" 169 onClick={enterFullScreen} 170 style={{ fontSize: "xxx-large" }} 171 > 172 フルスクリーンにする 173 </button> 174 </article> 175 ) : ( 176 StageComponent 177 )} 178 </main> 179 ); 180 }