AIdentity

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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 }