MCPcopy Create free account
hub / github.com/ImGoodBai/MapGoGoGo / ChallengeView

Function ChallengeView

frontend/src/App.tsx:647–1161  ·  view source on GitHub ↗
({
  config,
  challengeId,
  participant,
  onBack,
}: {
  config: AppConfig | null;
  challengeId: string;
  participant: Participant | null;
  onBack: () => void | Promise<void>;
})

Source from the content-addressed store, hash-verified

645}
646
647function ChallengeView({
648 config,
649 challengeId,
650 participant,
651 onBack,
652}: {
653 config: AppConfig | null;
654 challengeId: string;
655 participant: Participant | null;
656 onBack: () => void | Promise<void>;
657}) {
658 const [challenge, setChallenge] = useState<Challenge | null>(null);
659 const [cells, setCells] = useState<ChallengeCell[]>([]);
660 const [unlocked, setUnlocked] = useState<Set<string>>(new Set());
661 const [mine, setMine] = useState<Set<string>>(new Set());
662 const [leaderboard, setLeaderboard] = useState<LeaderboardRow[]>([]);
663 const [tracking, setTracking] = useState(false);
664 const [message, setMessage] = useState("准备开始。保持页面打开,走动后会点亮格子。");
665 const [permissionHint, setPermissionHint] = useState("");
666 const [gpsPosition, setGpsPosition] = useState<MapPosition | null>(null);
667 const [gpsCellId, setGpsCellId] = useState<string | null>(null);
668 const [desktopMode, setDesktopMode] = useState(() => isDesktopSimulatorLayout());
669 const [activePanel, setActivePanel] = useState<ChallengePanel | null>(null);
670 const [simPosition, setSimPosition] = useState<{ lat: number; lng: number } | null>(null);
671 const [simMine, setSimMine] = useState<Set<string>>(new Set());
672 const [simStepM, setSimStepM] = useState(30);
673 const [mapRotationDeg, setMapRotationDeg] = useState(0);
674 const [simMessage, setSimMessage] = useState("每步按经纬度移动,默认 30 米。");
675 const [shareNotice, setShareNotice] = useState("");
676 const [shareFallbackText, setShareFallbackText] = useState("");
677 const watchRef = useRef<number | null>(null);
678 const cellIdSet = useMemo(() => new Set(cells.map((cell) => cell.cell_id)), [cells]);
679 const cellKey = useMemo(() => cells.map((cell) => cell.cell_id).join("|"), [cells]);
680 const simCellId = useMemo(() => {
681 if (!challenge || !simPosition) return "";
682 return safeLatLngToCell(simPosition.lat, simPosition.lng, challenge.h3_resolution);
683 }, [challenge, simPosition]);
684 const simCellInside = Boolean(simCellId && cellIdSet.has(simCellId));
685 const visibleMine = useMemo(() => {
686 if (!desktopMode) return mine;
687 return simMine;
688 }, [desktopMode, mine, simMine]);
689 const simulatorPosition = useMemo<MapPosition | null>(() => {
690 if (!desktopMode || !simPosition) return null;
691 return {
692 lat: simPosition.lat,
693 lng: simPosition.lng,
694 mode: "simulator",
695 label: "本地模拟位置",
696 };
697 }, [desktopMode, simPosition]);
698 const mapPosition = simulatorPosition || gpsPosition;
699 const mapCellId = simulatorPosition ? (simCellInside ? simCellId : null) : gpsCellId;
700
701 async function load() {
702 const [detail, board] = await Promise.all([
703 api.getChallenge(challengeId),
704 api.leaderboard(challengeId),

Callers

nothing calls this directly

Calls 5

isDesktopSimulatorLayoutFunction · 0.85
safeLatLngToCellFunction · 0.85
loadFunction · 0.85
pctFunction · 0.85
resetSimulatorFunction · 0.85

Tested by

no test coverage detected