fix: attendance clock-in hanging after geolocation confirmation
On desktop browsers without GPS hardware, getCurrentPosition with enableHighAccuracy:true can silently hang after the user grants permission — neither success nor error callback fires. Previous safety timeout (12s) only reset the button without sending the punch request, leaving users stuck. Now: - enableHighAccuracy: false (faster fallback to IP-based location) - Browser timeout reduced to 5s - Safety timeout reduced to 6s and automatically calls submitPunch without GPS data instead of just showing an error - Wrapped success callback in try/catch as additional safeguard Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -186,15 +186,14 @@ export default function Attendance() {
|
||||
setSubmitting(true);
|
||||
latestActionRef.current = action;
|
||||
|
||||
// Safety timeout: if geolocation hangs silently (some browsers ignore
|
||||
// the timeout option), reset the button so the user isn't stuck.
|
||||
// Some browsers silently hang on getCurrentPosition (especially with
|
||||
// enableHighAccuracy:true on desktops without GPS). Use a short safety
|
||||
// timeout and proceed without GPS rather than leaving the user stuck.
|
||||
const safetyTimeout = setTimeout(() => {
|
||||
if (mountedRef.current) {
|
||||
setSubmitting(false);
|
||||
alert.error("Vypršel časový limit pro získání polohy");
|
||||
setGpsConfirm({ isOpen: true, action });
|
||||
submitPunch(action, {});
|
||||
}
|
||||
}, 12000);
|
||||
}, 6000);
|
||||
|
||||
if (!navigator.geolocation) {
|
||||
clearTimeout(safetyTimeout);
|
||||
@@ -207,14 +206,19 @@ export default function Attendance() {
|
||||
(position) => {
|
||||
clearTimeout(safetyTimeout);
|
||||
if (!mountedRef.current) return;
|
||||
const { latitude, longitude, accuracy } = position.coords;
|
||||
submitPunch(action, { latitude, longitude, accuracy, address: "" });
|
||||
try {
|
||||
const { latitude, longitude, accuracy } = position.coords;
|
||||
submitPunch(action, { latitude, longitude, accuracy, address: "" });
|
||||
} catch {
|
||||
submitPunch(action, {});
|
||||
}
|
||||
|
||||
// Fire-and-forget reverse geocoding to update the address later
|
||||
if (geoAbortRef.current) geoAbortRef.current.abort();
|
||||
const controller = new AbortController();
|
||||
geoAbortRef.current = controller;
|
||||
fetch(
|
||||
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude}&lon=${longitude}&zoom=18&addressdetails=1`,
|
||||
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${position.coords.latitude}&lon=${position.coords.longitude}&zoom=18&addressdetails=1`,
|
||||
{
|
||||
headers: { "Accept-Language": "cs" },
|
||||
signal: controller.signal,
|
||||
@@ -229,8 +233,8 @@ export default function Attendance() {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
latitude,
|
||||
longitude,
|
||||
latitude: position.coords.latitude,
|
||||
longitude: position.coords.longitude,
|
||||
address: geoData.display_name,
|
||||
punch_action: action,
|
||||
}),
|
||||
@@ -252,7 +256,7 @@ export default function Attendance() {
|
||||
setSubmitting(false);
|
||||
setGpsConfirm({ isOpen: true, action });
|
||||
},
|
||||
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 60000 },
|
||||
{ enableHighAccuracy: false, timeout: 5000, maximumAge: 60000 },
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user