()
| 805 | } |
| 806 | |
| 807 | async function startTracking() { |
| 808 | if (!navigator.geolocation) { |
| 809 | setMessage("当前浏览器不支持定位,请换用手机系统浏览器测试。"); |
| 810 | setPermissionHint(""); |
| 811 | return; |
| 812 | } |
| 813 | setTracking(true); |
| 814 | setPermissionHint(""); |
| 815 | setMessage("正在请求定位权限..."); |
| 816 | checkLocationPermission().then((hint) => { |
| 817 | if (hint) setPermissionHint(hint); |
| 818 | }); |
| 819 | try { |
| 820 | if ("wakeLock" in navigator) { |
| 821 | (navigator as any).wakeLock?.request?.("screen").catch(() => null); |
| 822 | } |
| 823 | } catch { |
| 824 | // Wake lock is optional. |
| 825 | } |
| 826 | watchRef.current = navigator.geolocation.watchPosition( |
| 827 | async (position) => { |
| 828 | const { latitude, longitude, accuracy, speed } = position.coords; |
| 829 | const result = await api.submitPosition(challengeId, { |
| 830 | lat: latitude, |
| 831 | lng: longitude, |
| 832 | accuracy_m: accuracy, |
| 833 | speed_mps: speed ?? undefined, |
| 834 | }); |
| 835 | if (result.map_lat != null && result.map_lng != null) { |
| 836 | setGpsPosition({ |
| 837 | lat: result.map_lat, |
| 838 | lng: result.map_lng, |
| 839 | mode: "gps", |
| 840 | label: "GPS 当前位置", |
| 841 | }); |
| 842 | } |
| 843 | if (result.cell_id) { |
| 844 | setGpsCellId(result.cell_id); |
| 845 | } |
| 846 | if (result.accepted && result.cell_id) { |
| 847 | setUnlocked((prev) => new Set(prev).add(result.cell_id!)); |
| 848 | setMine((prev) => new Set(prev).add(result.cell_id!)); |
| 849 | if (result.stats) setChallenge((prev) => (prev ? { ...prev, stats: result.stats! } : prev)); |
| 850 | setPermissionHint(""); |
| 851 | setMessage(`定位正常,精度 ${Math.round(accuracy)} 米。`); |
| 852 | } else { |
| 853 | const reasonText = |
| 854 | result.reason === "low_accuracy" |
| 855 | ? "信号弱,暂不计入" |
| 856 | : result.reason === "too_fast" |
| 857 | ? "移动太快,暂不计入" |
| 858 | : result.reason === "outside_area" |
| 859 | ? "你还不在挑战范围内" |
| 860 | : "当前位置暂不计入"; |
| 861 | setMessage(reasonText); |
| 862 | } |
| 863 | }, |
| 864 | (err) => { |
nothing calls this directly
no test coverage detected