From eccc6e10cfafa8aa8def44565cf540c002e9b9e3 Mon Sep 17 00:00:00 2001 From: K-Kizuku Date: Sun, 18 Aug 2024 07:29:52 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20=E3=81=AC=E3=82=8B=E3=81=AC?= =?UTF-8?q?=E3=82=8B=E5=8B=95=E3=81=8F=E3=82=88=E3=81=86=E3=81=AB=E3=81=AA?= =?UTF-8?q?=E3=81=A3=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 13 ++- src/components/Yatai/TargetOverlay.module.css | 15 +-- src/components/Yatai/TargetOverlay.tsx | 25 ++--- src/pages/shooter/index.tsx | 106 ++++++++++++------ 4 files changed, 98 insertions(+), 61 deletions(-) diff --git a/index.html b/index.html index 434434f..dc39bba 100644 --- a/index.html +++ b/index.html @@ -1,11 +1,14 @@ - - + + - - - + + + VIRTUAL_NATSUMATSURI diff --git a/src/components/Yatai/TargetOverlay.module.css b/src/components/Yatai/TargetOverlay.module.css index c285a00..d22ce22 100644 --- a/src/components/Yatai/TargetOverlay.module.css +++ b/src/components/Yatai/TargetOverlay.module.css @@ -1,12 +1,13 @@ .target { - position: absolute; - z-index: 1; - width: 100px; - height: 100px; - transform: translate(calc(-50%+50px), calc(-50%+50px)); + position: absolute; + z-index: 1; + width: 100px; + height: 100px; + transform: translate(calc(-50%+50px), calc(-50%+50px)); + transition: all 0.1s linear; } .image { - width: 100%; - height: 100%; + width: 100%; + height: 100%; } diff --git a/src/components/Yatai/TargetOverlay.tsx b/src/components/Yatai/TargetOverlay.tsx index f5ffe29..ea05a42 100644 --- a/src/components/Yatai/TargetOverlay.tsx +++ b/src/components/Yatai/TargetOverlay.tsx @@ -1,10 +1,7 @@ import { useEffect, useState } from "react"; import { useSocketReceiver } from "../../hooks/useSocketReceiver"; -import { - type ActionSchema, - MessageType, - type Target, -} from "../../type/shooting"; +import type { ActionSchema, PointerSchema, Target } from "../../type/shooting"; +import { MessageType } from "../../type/shooting"; import styles from "./TargetOverlay.module.css"; export const TargetOverlay = () => { @@ -12,29 +9,27 @@ export const TargetOverlay = () => { useEffect(() => { onMessage((data) => { - // ここも本来はPointerSchemaになる if (data.message_type === MessageType.Action) { shotTarget(data); } + if (data.message_type === MessageType.Pointer) { + aimTarget(data); + } }); }, [onMessage]); // TODO: これらは一人用,いつかマルチプレイヤー対応する const [aim, setAim] = useState(undefined); - // TODO: エイム照準の実装 - // const aimTarget = (data: PointerSchema) => { - // const x = window.innerWidth * data.target.x + window.innerWidth / 2; - // const y = window.innerHeight * data.target.y + window.innerHeight / 2; - // setAim({ x, y }); - // }; + const aimTarget = (data: PointerSchema) => { + const x = window.innerWidth / 2 + data.target.x * 1200; + const y = window.innerHeight / 2 + data.target.y * 1200; + setAim({ x, y }); + }; - // const [target, setTarget] = useState(undefined); const shotTarget = (data: ActionSchema) => { const x = window.innerWidth / 2 + data.target.x * 1200; const y = window.innerHeight / 2 + data.target.y * 1200; - // TODO: エイム実装ができたらここのsetAimは削除する setAim({ x, y }); - // setTarget({ x, y }); }; return ( diff --git a/src/pages/shooter/index.tsx b/src/pages/shooter/index.tsx index e858016..49cd32a 100644 --- a/src/pages/shooter/index.tsx +++ b/src/pages/shooter/index.tsx @@ -1,21 +1,21 @@ -import { type KeyboardEventHandler, useEffect, useState } from "react"; +import { + type KeyboardEventHandler, + useCallback, + useEffect, + useState, +} from "react"; import { DefaultButton } from "../../components/ui/Button"; import { Modal } from "../../components/ui/Modal"; import { ShooterButton } from "../../components/ui/ShooterButton"; -import { useOrientation } from "../../hooks/useOrientation"; -import { useSocketReceiver } from "../../hooks/useSocketReceiver"; +import type { Orientation } from "../../hooks/useOrientation"; import { useSocketSender } from "../../hooks/useSocketSender"; import { useUUIDStore } from "../../store"; import { message_type } from "../../type/schema"; -import { MessageType } from "../../type/shooting"; import style from "./index.module.css"; const Shooter = () => { const [isOpen, setIsOpen] = useState(true); - const [score, setScore] = useState(0); - const { orientationDiff } = useOrientation(); const { sendData } = useSocketSender(); - const { onMessage } = useSocketReceiver(); const initialImages = [ "/2D_material/cork.webp", @@ -25,31 +25,49 @@ const Shooter = () => { const [images, setImages] = useState(initialImages); const uuid = useUUIDStore((state) => state.uuid); + // const intervalId = useRef(null); + const [initialOrientation, setInitialOrientation] = useState({ + alpha: 0, + beta: 0, + gamma: 0, + }); + const send = useCallback( + (event: DeviceOrientationEvent, msg_type: message_type) => { + if (!event.alpha || !event.beta || !event.gamma) { + return; + } + console.log(event.alpha, event.beta, event.gamma); + sendData(msg_type, uuid, { + alpha: initialOrientation + ? (event.gamma - initialOrientation.gamma) * 2 + : event.gamma, + beta: initialOrientation + ? event.beta - initialOrientation.beta + : event.beta, + }); + }, + [sendData, uuid, initialOrientation], + ); useEffect(() => { - let intervalId: number | null = null; - - intervalId = window.setInterval(() => { - sendData(message_type.status, uuid, orientationDiff); + const intervalId = setInterval(() => { + window.addEventListener( + "deviceorientation", + (event) => send(event, message_type.status), + { once: true }, + ); }, 100); - return () => { - if (intervalId !== null) { - clearInterval(intervalId); - } + clearInterval(intervalId); }; - }, [uuid, orientationDiff, sendData]); + }, [send]); - useEffect(() => { - onMessage((data) => { - if (data.message_type === MessageType.Hit && data.id === uuid) { - setScore((prevScore) => prevScore + 1); - console.log(score); - } - }); - }, [onMessage, uuid, score]); - - const handleClick = () => { + const handleClick = async () => { + window.addEventListener( + "deviceorientation", + (event) => send(event, message_type.action), + { once: true }, + ); const audio = new Audio("/sound/cork_sound.mp3"); audio .play() @@ -57,7 +75,6 @@ const Shooter = () => { .catch((error) => { console.error("オーディオの音が出なかった", error); }); - sendData(message_type.action, uuid, orientationDiff); setImages((prevImages) => prevImages.slice(1)); }; @@ -66,11 +83,15 @@ const Shooter = () => { handleClick(); } }; + console.log("hige"); return (
setIsOpen(false)}> - +
@@ -81,16 +102,36 @@ const Shooter = () => { コルクの残量を表示しています ))}
+

{initialOrientation.alpha}

+

{initialOrientation.beta}

+

{initialOrientation.gamma}

); }; type ModalContentProps = { setIsOpen: (isOpen: boolean) => void; + setInitialOrientation: (orientation: Orientation) => void; }; -const ModalContent: React.FC = ({ setIsOpen }) => { - const { reset } = useOrientation(); +const ModalContent: React.FC = ({ + setIsOpen, + setInitialOrientation, +}) => { + const handleClick = () => { + window.addEventListener( + "deviceorientation", + (event) => { + setInitialOrientation({ + alpha: event.alpha || 0, + beta: event.beta || 0, + gamma: event.gamma || 0, + }); + }, + { once: true }, + ); + setIsOpen(false); + }; return (
= ({ setIsOpen }) => { variant="outlined" color="red" size="md" - onClick={() => { - reset(); - setIsOpen(false); - }} + onClick={handleClick} > 置いたよ! From 4479cc69556910aef270868d137346f54b07c6d0 Mon Sep 17 00:00:00 2001 From: K-Kizuku Date: Sun, 18 Aug 2024 07:31:46 +0900 Subject: [PATCH 2/9] =?UTF-8?q?fix:=20=E3=82=B3=E3=83=B3=E3=82=BD=E3=83=BC?= =?UTF-8?q?=E3=83=AB=E3=83=AD=E3=82=B0=E6=B6=88=E3=81=97=E5=BF=98=E3=82=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/shooter/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/shooter/index.tsx b/src/pages/shooter/index.tsx index 49cd32a..4631092 100644 --- a/src/pages/shooter/index.tsx +++ b/src/pages/shooter/index.tsx @@ -83,7 +83,6 @@ const Shooter = () => { handleClick(); } }; - console.log("hige"); return (
From 891cf9417fad117ac7ea4e244356c47025917e0e Mon Sep 17 00:00:00 2001 From: K-Kizuku Date: Sun, 18 Aug 2024 07:34:46 +0900 Subject: [PATCH 3/9] =?UTF-8?q?fix:=20=E3=83=87=E3=83=90=E3=83=83=E3=82=B0?= =?UTF-8?q?=E3=82=88=E3=81=86=E8=A1=A8=E7=A4=BA=E6=B6=88=E3=81=97=E5=BF=98?= =?UTF-8?q?=E3=82=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/shooter/index.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pages/shooter/index.tsx b/src/pages/shooter/index.tsx index 4631092..890d466 100644 --- a/src/pages/shooter/index.tsx +++ b/src/pages/shooter/index.tsx @@ -101,9 +101,6 @@ const Shooter = () => { コルクの残量を表示しています ))}
-

{initialOrientation.alpha}

-

{initialOrientation.beta}

-

{initialOrientation.gamma}

); }; From 3e113afbab3cefe32f339bda12983f3a8e7f45e7 Mon Sep 17 00:00:00 2001 From: FUKUDA Miyu <126382452+Sea10wood@users.noreply.github.com> Date: Sat, 17 Aug 2024 22:50:32 +0000 Subject: [PATCH 4/9] =?UTF-8?q?Add:=20topaz=E3=81=AE=E3=83=AA=E3=83=B3?= =?UTF-8?q?=E3=82=AF=E3=82=92readme=E3=81=AB=E8=BF=BD=E5=8A=A0=E3=81=97?= =?UTF-8?q?=E3=81=9F=E3=81=A0=E3=81=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bb71330..5036d57 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # ばーちゃる夏祭り frontend -https://virtual-natsumatsuri.web.app/ \ No newline at end of file +https://virtual-natsumatsuri.web.app/ + +## topazLink +https://topaz.dev/projects/4505516cee6f487ac360 \ No newline at end of file From 4dbf63cc047e7c9f0db3d2e47b62f3704ac67f27 Mon Sep 17 00:00:00 2001 From: K-Kizuku Date: Mon, 19 Aug 2024 05:42:59 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20=E3=83=AA=E3=83=AA=E3=83=BC?= =?UTF-8?q?=E3=82=B9=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 2 +- src/components/Gallery/index.module.css | 93 +++++++++++++------------ src/components/Gallery/index.tsx | 24 ++++++- src/hooks/useSocketSender.ts | 1 - src/pages/result/index.module.css | 83 +++++++++++----------- src/pages/result/index.tsx | 8 +-- src/pages/shooter/index.tsx | 35 +++++----- src/store/useScoreStore.ts | 6 +- src/store/useTargetStatusStore.ts | 5 ++ src/utils/copyClipBoard.ts | 4 +- 10 files changed, 142 insertions(+), 119 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 40406a9..0faef9c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,7 +9,7 @@ const AppRoutes = () => { } /> } /> - } /> + } /> } /> ); diff --git a/src/components/Gallery/index.module.css b/src/components/Gallery/index.module.css index b9df346..81a4051 100644 --- a/src/components/Gallery/index.module.css +++ b/src/components/Gallery/index.module.css @@ -1,61 +1,62 @@ -h1{ - font-size: 40px; +h1 { + font-size: 40px; } -.title{ - position: absolute; - top: 0; - left: 0; - z-index: 1; - padding: 16px; - margin: 0; -} -.nobori img{ - position: absolute; - bottom: 0; - left: -240px; - height: 80vh; - aspect-ratio: 1 / 1; - z-index: -1; +.title { + position: absolute; + top: 0; + left: 0; + z-index: 1; + padding: 16px; + margin: 0; + cursor: pointer; +} +.nobori img { + position: absolute; + bottom: 0; + left: -240px; + height: 80vh; + aspect-ratio: 1 / 1; + z-index: -1; } -.light img{ - position: absolute; - top: 0; - left: 0px; - height: 80vh; - aspect-ratio: 1 / 1; - z-index: -1; +.light img { + position: absolute; + top: 0; + left: 0px; + height: 80vh; + aspect-ratio: 1 / 1; + z-index: -1; } .container { - display: flex; - align-items: flex-end; - position: absolute; - bottom: 16px; - left: 4vw; - z-index: 1; + display: flex; + align-items: flex-end; + position: absolute; + bottom: 16px; + left: 4vw; + z-index: 1; } .logo img { - height: 16vh; - aspect-ratio: 1 / 1; - margin-right: 2vw; + height: 16vh; + aspect-ratio: 1 / 1; + margin-right: 2vw; } .shop { - color: var(--white); - font-size: 4vw; - padding: 16px; - margin: 0; + color: var(--white); + font-size: 4vw; + padding: 16px; + margin: 0; } -.light-right img{ - position: absolute; - top: 0; - right: 0px; - height: 80vh; - aspect-ratio: 1 / 1; - z-index: -1; - transform: scale(-1, 1); -} \ No newline at end of file +.light-right img { + position: absolute; + top: 0; + right: 0px; + height: 80vh; + aspect-ratio: 1 / 1; + z-index: -1; + transform: scale(-1, 1); +} diff --git a/src/components/Gallery/index.tsx b/src/components/Gallery/index.tsx index af3ee94..1944664 100644 --- a/src/components/Gallery/index.tsx +++ b/src/components/Gallery/index.tsx @@ -1,6 +1,20 @@ +import { useNavigate } from "react-router-dom"; +import { useRoomIdStore, useTargetStatusStore } from "../../store"; import styles from "./index.module.css"; function Gallery() { + const navigate = useNavigate(); + const updateUUID = useRoomIdStore((state) => state.updateUUID); + const resetTargetStatus = useTargetStatusStore( + (state) => state.resetTargetStatus, + ); + + const handleClick = () => { + resetTargetStatus(); + updateUUID(); + navigate("/"); + }; + return (
{/* biome-ignore lint/a11y/useMediaCaption: 夏祭りの音を再生します。 */} @@ -10,7 +24,15 @@ function Gallery() { loop aria-label="夏祭りの音" /> -

VIRTUAL_NATSUMATSURI

+

{ + handleClick(); + }} + onKeyDown={() => {}} + className={styles.title} + > + VIRTUAL_NATSUMATSURI +

夏祭り_のぼり
diff --git a/src/hooks/useSocketSender.ts b/src/hooks/useSocketSender.ts index ca6eb51..306690b 100644 --- a/src/hooks/useSocketSender.ts +++ b/src/hooks/useSocketSender.ts @@ -31,7 +31,6 @@ export const useSocketSender = () => { message_type: mes_type, event_type: event_type.shooter, }; - console.log(data); socketRef?.current?.send(JSON.stringify(data)); }, [socketRef], diff --git a/src/pages/result/index.module.css b/src/pages/result/index.module.css index ce483cf..1a6e17f 100644 --- a/src/pages/result/index.module.css +++ b/src/pages/result/index.module.css @@ -1,36 +1,36 @@ .result-text { - position: absolute; - left: 50%; - transform: translateX(-50%); - font-size: 40px; + position: absolute; + left: 50%; + transform: translateX(-50%); + font-size: 40px; + z-index: 1; } -.background-logo{ - opacity: 0.6; - position: absolute; - top: 40%; - left: 50%; - transform: translate(-50%, -50%); - justify-content: center; - align-items: center; - +.background-logo { + opacity: 0.6; + position: absolute; + top: 40%; + left: 50%; + transform: translate(-50%, -50%); + justify-content: center; + align-items: center; } .get-text { - position: absolute; - top: 60%; - left: 50%; - transform: translateX(-50%); - font-size: 40px; - white-space: nowrap; + position: absolute; + top: 60%; + left: 50%; + transform: translateX(-50%); + font-size: 40px; + white-space: nowrap; } -.share-btn{ - position: absolute; - top: 80%; - left: 50%; - transform: translateX(-50%); - white-space: nowrap; +.share-btn { + position: absolute; + top: 80%; + left: 50%; + transform: translateX(-50%); + white-space: nowrap; } .replay-text { @@ -39,30 +39,29 @@ left: 50%; transform: translateX(-50%); white-space: nowrap; - font-family: 'Yuji Syuku', serif, sans-serif; + font-family: "Yuji Syuku", serif, sans-serif; line-height: 1.5; font-weight: 400; font-style: normal; } @keyframes rotate { - from { - transform: translate(-50%, -50%) rotate(0deg); - } - to { - transform: translate(-50%, -50%) rotate(360deg); - } + from { + transform: translate(-50%, -50%) rotate(0deg); + } + to { + transform: translate(-50%, -50%) rotate(360deg); + } } .get-image-container { - position: absolute; - top: 40%; - left: 50%; - transform: translate(-50%, -50%); - display: flex; - justify-content: center; - align-items: center; - z-index: 1; - animation: rotate 16s linear infinite; + position: absolute; + top: 40%; + left: 50%; + transform: translate(-50%, -50%); + display: flex; + justify-content: center; + align-items: center; + z-index: 1; + animation: rotate 16s linear infinite; } - diff --git a/src/pages/result/index.tsx b/src/pages/result/index.tsx index 7c04145..e9e9266 100644 --- a/src/pages/result/index.tsx +++ b/src/pages/result/index.tsx @@ -1,12 +1,10 @@ import GetImage from "../../components/GetImage"; import { DefaultButton } from "../../components/ui/Button"; +import { useScoreStore } from "../../store/useScoreStore"; import styles from "./index.module.css"; -type ResultProps = { - score: number; -}; - -const Result = ({ score }: ResultProps) => { +const Result = () => { + const score = useScoreStore((state) => state.score); const image = score >= 0 && score <= 3 ? `/drink/bottle${score}.webp` diff --git a/src/pages/shooter/index.tsx b/src/pages/shooter/index.tsx index 120d442..691a997 100644 --- a/src/pages/shooter/index.tsx +++ b/src/pages/shooter/index.tsx @@ -1,29 +1,28 @@ -import { useNavigate } from "react-router-dom"; import { type KeyboardEventHandler, useCallback, useEffect, useState, } from "react"; +import { useNavigate } from "react-router-dom"; import { DefaultButton } from "../../components/ui/Button"; import { Modal } from "../../components/ui/Modal"; import { ShooterButton } from "../../components/ui/ShooterButton"; import type { Orientation } from "../../hooks/useOrientation"; +import { useSocketReceiver } from "../../hooks/useSocketReceiver"; import { useSocketSender } from "../../hooks/useSocketSender"; import { useUUIDStore } from "../../store"; import { useScoreStore } from "../../store/useScoreStore"; import { message_type } from "../../type/schema"; -import style from "./index.module.css"; import { MessageType } from "../../type/shooting"; -import { useSocketReceiver } from "../../hooks/useSocketReceiver"; +import styles from "./index.module.css"; const Shooter = () => { const [isOpen, setIsOpen] = useState(true); const { sendData } = useSocketSender(); const { onMessage } = useSocketReceiver(); - const addOneScore = useScoreStore((state) => state.addOneScore); const navigate = useNavigate(); - const score = useScoreStore((state) => state.score); + const addOneScore = useScoreStore((state) => state.addOneScore); const initialImages = [ "/2D_material/cork.webp", @@ -32,7 +31,6 @@ const Shooter = () => { ]; const [images, setImages] = useState(initialImages); const uuid = useUUIDStore((state) => state.uuid); - // const intervalId = useRef(null); const [initialOrientation, setInitialOrientation] = useState({ alpha: 0, beta: 0, @@ -44,7 +42,6 @@ const Shooter = () => { if (!event.alpha || !event.beta || !event.gamma) { return; } - console.log(event.alpha, event.beta, event.gamma); sendData(msg_type, uuid, { alpha: initialOrientation ? (event.gamma - initialOrientation.gamma) * 2 @@ -72,18 +69,22 @@ const Shooter = () => { }; }, [send]); + // biome-ignore lint/correctness/useExhaustiveDependencies: 初期化処理だけでいいため依存配列は空配列にしている useEffect(() => { onMessage((data) => { if (data.message_type === MessageType.Hit && data.id === uuid) { addOneScore(); } }); - }, [onMessage, uuid, addOneScore]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + useEffect(() => { if (images.length === 0) { - navigate("/result", { state: { score } }); + navigate("/result"); } - }, [images, navigate, score]); + }, [images, navigate]); + const handleClick = async () => { window.addEventListener( "deviceorientation", @@ -102,7 +103,7 @@ const Shooter = () => { const handleKeyUp: KeyboardEventHandler = (event) => { if (event.key === "Enter" || event.key === " ") { - handleClick(); + // handleClick(); } }; @@ -114,10 +115,10 @@ const Shooter = () => { setInitialOrientation={setInitialOrientation} /> -
+
-
+
{images.length > 0 ? ( images.map((src, i) => ( // biome-ignore lint/suspicious/noArrayIndexKey: @@ -155,21 +156,21 @@ const ModalContent: React.FC = ({ setIsOpen(false); }; return ( -
+
スマホを画面に向かって垂直におく図 -
-

+

+

スマホを画面に向かって
垂直に机の上に置いてね

-
+
void; }; -export const useScoreStore = create((set) => ({ +export const useScoreStore = create()((set) => ({ score: 0, setScore: (score) => set(() => ({ score: score })), addOneScore: () => set((state) => ({ score: state.score + 1 })), diff --git a/src/store/useTargetStatusStore.ts b/src/store/useTargetStatusStore.ts index dcda4c1..96dc6e9 100644 --- a/src/store/useTargetStatusStore.ts +++ b/src/store/useTargetStatusStore.ts @@ -7,6 +7,7 @@ type State = { type Action = { updateTargetStatus: (index: number, status: TargetStatus) => void; + resetTargetStatus: () => void; }; export const useTargetStatusStore = create((set) => ({ @@ -18,4 +19,8 @@ export const useTargetStatusStore = create((set) => ({ targetStatus[index] = status; return { targetStatus }; }), + resetTargetStatus: () => + set(() => ({ + targetStatus: [TargetStatus.Live, TargetStatus.Live, TargetStatus.Live], + })), })); diff --git a/src/utils/copyClipBoard.ts b/src/utils/copyClipBoard.ts index 1652119..1a77e0c 100644 --- a/src/utils/copyClipBoard.ts +++ b/src/utils/copyClipBoard.ts @@ -1,8 +1,6 @@ export const copyStringToClipboard = (text: string) => { navigator.clipboard.writeText(text).then( - () => { - console.log("Async: Copying to clipboard was successful!"); - }, + () => {}, (err) => { console.error("Async: Could not copy text: ", err); }, From e02752a4d8398b94558ccc835d8d53205acbd27c Mon Sep 17 00:00:00 2001 From: K-Kizuku Date: Mon, 19 Aug 2024 05:45:48 +0900 Subject: [PATCH 6/9] fix: lint --- src/pages/shooter/index.tsx | 306 ++++++++++++++++++------------------ 1 file changed, 153 insertions(+), 153 deletions(-) diff --git a/src/pages/shooter/index.tsx b/src/pages/shooter/index.tsx index 691a997..7464ab6 100644 --- a/src/pages/shooter/index.tsx +++ b/src/pages/shooter/index.tsx @@ -1,8 +1,8 @@ import { - type KeyboardEventHandler, - useCallback, - useEffect, - useState, + type KeyboardEventHandler, + useCallback, + useEffect, + useState, } from "react"; import { useNavigate } from "react-router-dom"; import { DefaultButton } from "../../components/ui/Button"; @@ -18,170 +18,170 @@ import { MessageType } from "../../type/shooting"; import styles from "./index.module.css"; const Shooter = () => { - const [isOpen, setIsOpen] = useState(true); - const { sendData } = useSocketSender(); - const { onMessage } = useSocketReceiver(); - const navigate = useNavigate(); - const addOneScore = useScoreStore((state) => state.addOneScore); + const [isOpen, setIsOpen] = useState(true); + const { sendData } = useSocketSender(); + const { onMessage } = useSocketReceiver(); + const navigate = useNavigate(); + const addOneScore = useScoreStore((state) => state.addOneScore); - const initialImages = [ - "/2D_material/cork.webp", - "/2D_material/cork.webp", - "/2D_material/cork.webp", - ]; - const [images, setImages] = useState(initialImages); - const uuid = useUUIDStore((state) => state.uuid); - const [initialOrientation, setInitialOrientation] = useState({ - alpha: 0, - beta: 0, - gamma: 0, - }); + const initialImages = [ + "/2D_material/cork.webp", + "/2D_material/cork.webp", + "/2D_material/cork.webp", + ]; + const [images, setImages] = useState(initialImages); + const uuid = useUUIDStore((state) => state.uuid); + const [initialOrientation, setInitialOrientation] = useState({ + alpha: 0, + beta: 0, + gamma: 0, + }); - const send = useCallback( - (event: DeviceOrientationEvent, msg_type: message_type) => { - if (!event.alpha || !event.beta || !event.gamma) { - return; - } - sendData(msg_type, uuid, { - alpha: initialOrientation - ? (event.gamma - initialOrientation.gamma) * 2 - : event.gamma, - beta: initialOrientation - ? event.beta - initialOrientation.beta - : event.beta, - }); - }, - [sendData, uuid, initialOrientation] - ); - useEffect(() => { - const intervalId = setInterval(() => { - window.addEventListener( - "deviceorientation", - (event) => send(event, message_type.status), - { once: true } - ); - }, 100); + const send = useCallback( + (event: DeviceOrientationEvent, msg_type: message_type) => { + if (!event.alpha || !event.beta || !event.gamma) { + return; + } + sendData(msg_type, uuid, { + alpha: initialOrientation + ? (event.gamma - initialOrientation.gamma) * 2 + : event.gamma, + beta: initialOrientation + ? event.beta - initialOrientation.beta + : event.beta, + }); + }, + [sendData, uuid, initialOrientation], + ); + useEffect(() => { + const intervalId = setInterval(() => { + window.addEventListener( + "deviceorientation", + (event) => send(event, message_type.status), + { once: true }, + ); + }, 100); - return () => { - if (intervalId !== null) { - clearInterval(intervalId); - } - }; - }, [send]); + return () => { + if (intervalId !== null) { + clearInterval(intervalId); + } + }; + }, [send]); - // biome-ignore lint/correctness/useExhaustiveDependencies: 初期化処理だけでいいため依存配列は空配列にしている - useEffect(() => { - onMessage((data) => { - if (data.message_type === MessageType.Hit && data.id === uuid) { - addOneScore(); - } - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + // biome-ignore lint/correctness/useExhaustiveDependencies: 初期化処理だけでいいため依存配列は空配列にしている + useEffect(() => { + onMessage((data) => { + if (data.message_type === MessageType.Hit && data.id === uuid) { + addOneScore(); + } + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); - useEffect(() => { - if (images.length === 0) { - navigate("/result"); - } - }, [images, navigate]); + useEffect(() => { + if (images.length === 0) { + navigate("/result"); + } + }, [images, navigate]); - const handleClick = async () => { - window.addEventListener( - "deviceorientation", - (event) => send(event, message_type.action), - { once: true } - ); - const audio = new Audio("/sound/cork_sound.mp3"); - audio - .play() - .then(() => {}) - .catch((error) => { - console.error("オーディオの音が出なかった", error); - }); - setImages((prevImages) => prevImages.slice(1)); - }; + const handleClick = async () => { + window.addEventListener( + "deviceorientation", + (event) => send(event, message_type.action), + { once: true }, + ); + const audio = new Audio("/sound/cork_sound.mp3"); + audio + .play() + .then(() => {}) + .catch((error) => { + console.error("オーディオの音が出なかった", error); + }); + setImages((prevImages) => prevImages.slice(1)); + }; - const handleKeyUp: KeyboardEventHandler = (event) => { - if (event.key === "Enter" || event.key === " ") { - // handleClick(); - } - }; + const handleKeyUp: KeyboardEventHandler = (event) => { + if (event.key === "Enter" || event.key === " ") { + // handleClick(); + } + }; - return ( -
- setIsOpen(false)}> - - -
- -
-
- {images.length > 0 ? ( - images.map((src, i) => ( - // biome-ignore lint/suspicious/noArrayIndexKey: - コルクの残量を表示しています - )) - ) : ( -

コルクがなくなりました!

- )} -
-
- ); + return ( +
+ setIsOpen(false)}> + + +
+ +
+
+ {images.length > 0 ? ( + images.map((src, i) => ( + // biome-ignore lint/suspicious/noArrayIndexKey: + コルクの残量を表示しています + )) + ) : ( +

コルクがなくなりました!

+ )} +
+
+ ); }; type ModalContentProps = { - setIsOpen: (isOpen: boolean) => void; - setInitialOrientation: (orientation: Orientation) => void; + setIsOpen: (isOpen: boolean) => void; + setInitialOrientation: (orientation: Orientation) => void; }; const ModalContent: React.FC = ({ - setIsOpen, - setInitialOrientation, + setIsOpen, + setInitialOrientation, }) => { - const handleClick = () => { - window.addEventListener( - "deviceorientation", - (event) => { - setInitialOrientation({ - alpha: event.alpha || 0, - beta: event.beta || 0, - gamma: event.gamma || 0, - }); - }, - { once: true } - ); - setIsOpen(false); - }; - return ( -
- スマホを画面に向かって垂直におく図 -
-

- スマホを画面に向かって -
- 垂直に机の上に置いてね -

-
-
- - 置いたよ! - -
-
- ); + const handleClick = () => { + window.addEventListener( + "deviceorientation", + (event) => { + setInitialOrientation({ + alpha: event.alpha || 0, + beta: event.beta || 0, + gamma: event.gamma || 0, + }); + }, + { once: true }, + ); + setIsOpen(false); + }; + return ( +
+ スマホを画面に向かって垂直におく図 +
+

+ スマホを画面に向かって +
+ 垂直に机の上に置いてね +

+
+
+ + 置いたよ! + +
+
+ ); }; export default Shooter; From d99275bbe1e9bd682f9981a1c41bc0f492a76c74 Mon Sep 17 00:00:00 2001 From: K-Kizuku Date: Mon, 19 Aug 2024 06:27:25 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20aimTarget=E3=81=AE=E7=B5=B1=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Yatai/TargetOverlay.tsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/components/Yatai/TargetOverlay.tsx b/src/components/Yatai/TargetOverlay.tsx index ea05a42..2598d34 100644 --- a/src/components/Yatai/TargetOverlay.tsx +++ b/src/components/Yatai/TargetOverlay.tsx @@ -9,10 +9,10 @@ export const TargetOverlay = () => { useEffect(() => { onMessage((data) => { - if (data.message_type === MessageType.Action) { - shotTarget(data); - } - if (data.message_type === MessageType.Pointer) { + if ( + data.message_type === MessageType.Action || + data.message_type === MessageType.Pointer + ) { aimTarget(data); } }); @@ -20,13 +20,7 @@ export const TargetOverlay = () => { // TODO: これらは一人用,いつかマルチプレイヤー対応する const [aim, setAim] = useState(undefined); - const aimTarget = (data: PointerSchema) => { - const x = window.innerWidth / 2 + data.target.x * 1200; - const y = window.innerHeight / 2 + data.target.y * 1200; - setAim({ x, y }); - }; - - const shotTarget = (data: ActionSchema) => { + const aimTarget = (data: PointerSchema | ActionSchema) => { const x = window.innerWidth / 2 + data.target.x * 1200; const y = window.innerHeight / 2 + data.target.y * 1200; setAim({ x, y }); From 71f8a084f18e06593d5f916d12728402032b9d8b Mon Sep 17 00:00:00 2001 From: K-Kizuku Date: Mon, 19 Aug 2024 08:45:32 +0900 Subject: [PATCH 8/9] =?UTF-8?q?fix:=20score=E3=81=AE=E4=B8=8A=E9=99=90?= =?UTF-8?q?=E3=82=92=E8=A8=AD=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/useScoreStore.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/store/useScoreStore.ts b/src/store/useScoreStore.ts index 601bf51..baf99a2 100644 --- a/src/store/useScoreStore.ts +++ b/src/store/useScoreStore.ts @@ -12,5 +12,11 @@ type Action = { export const useScoreStore = create()((set) => ({ score: 0, setScore: (score) => set(() => ({ score: score })), - addOneScore: () => set((state) => ({ score: state.score + 1 })), + addOneScore: () => + set((state) => { + if (state.score > 3) { + return { score: 3 }; + } + return { score: state.score + 1 }; + }), })); From 06b8574e9d005cb4def2e8fa1194de3d205c0fc8 Mon Sep 17 00:00:00 2001 From: claustra01 Date: Mon, 19 Aug 2024 09:18:37 +0900 Subject: [PATCH 9/9] fix: init target status --- src/components/Gallery/index.tsx | 6 +----- src/pages/yatai/index.tsx | 11 +++++++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/components/Gallery/index.tsx b/src/components/Gallery/index.tsx index 1944664..7db986c 100644 --- a/src/components/Gallery/index.tsx +++ b/src/components/Gallery/index.tsx @@ -1,16 +1,12 @@ import { useNavigate } from "react-router-dom"; -import { useRoomIdStore, useTargetStatusStore } from "../../store"; +import { useRoomIdStore } from "../../store"; import styles from "./index.module.css"; function Gallery() { const navigate = useNavigate(); const updateUUID = useRoomIdStore((state) => state.updateUUID); - const resetTargetStatus = useTargetStatusStore( - (state) => state.resetTargetStatus, - ); const handleClick = () => { - resetTargetStatus(); updateUUID(); navigate("/"); }; diff --git a/src/pages/yatai/index.tsx b/src/pages/yatai/index.tsx index 596ebe5..a92dd9d 100644 --- a/src/pages/yatai/index.tsx +++ b/src/pages/yatai/index.tsx @@ -1,9 +1,20 @@ +import { useEffect } from "react"; import Gallery from "../../components/Gallery"; import { TargetOverlay } from "../../components/Yatai/TargetOverlay"; import { YataiStage } from "../../components/Yatai/YataiStage"; +import { useTargetStatusStore } from "../../store"; import styles from "./index.module.css"; function Yatai() { + const resetTargetStatus = useTargetStatusStore( + (state) => state.resetTargetStatus, + ); + + // init target status + useEffect(() => { + resetTargetStatus(); + }, [resetTargetStatus]); + return (