diff --git a/src/app/room/[id]/page.tsx b/src/app/room/[id]/page.tsx index 86147ef..9b2cc12 100644 --- a/src/app/room/[id]/page.tsx +++ b/src/app/room/[id]/page.tsx @@ -1,9 +1,10 @@ "use client"; -import { useEffect, useState, useCallback } from "react"; +import { useEffect, useState, useCallback, useRef } from "react"; import { useParams, useRouter } from "next/navigation"; import TopNav from "@/components/TopNav"; import SwipeDeck from "@/components/SwipeDeck"; +import LeaveConfirmModal from "@/components/LeaveConfirmModal"; import { useRoomPolling } from "@/hooks/useRoomPolling"; import { getUserId } from "@/lib/userId"; @@ -15,6 +16,8 @@ export default function RoomPage() { const [userId, setUserId] = useState(""); const [joined, setJoined] = useState(false); const [joinFailed, setJoinFailed] = useState(false); + const [showLeaveConfirm, setShowLeaveConfirm] = useState(false); + const leavingRef = useRef(false); const { userCount, match, matchType, matchLikes, runnerUps, likeCounts, swipeCounts, restaurants, notFound, mutate, @@ -34,6 +37,42 @@ export default function RoomPage() { }).catch(() => setJoinFailed(true)); }, [roomId]); + useEffect(() => { + window.history.pushState({ roomGuard: true }, ""); + + const handlePopState = () => { + if (leavingRef.current) return; + window.history.pushState({ roomGuard: true }, ""); + setShowLeaveConfirm(true); + }; + + const handleBeforeUnload = (e: BeforeUnloadEvent) => { + if (leavingRef.current) return; + e.preventDefault(); + }; + + window.addEventListener("popstate", handlePopState); + window.addEventListener("beforeunload", handleBeforeUnload); + return () => { + window.removeEventListener("popstate", handlePopState); + window.removeEventListener("beforeunload", handleBeforeUnload); + }; + }, []); + + const confirmLeave = useCallback(() => { + leavingRef.current = true; + setShowLeaveConfirm(false); + router.push("/"); + }, [router]); + + const cancelLeave = useCallback(() => { + setShowLeaveConfirm(false); + }, []); + + const handleExitRequest = useCallback(() => { + setShowLeaveConfirm(true); + }, []); + const handleReset = useCallback(async () => { await fetch(`/api/room/${roomId}/reset`, { method: "POST" }); await mutate(); @@ -78,7 +117,7 @@ export default function RoomPage() { return (
+ 退出后你的滑卡进度不会丢失,可以用房间号重新加入 +
+ +