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);
|
setSubmitting(true);
|
||||||
latestActionRef.current = action;
|
latestActionRef.current = action;
|
||||||
|
|
||||||
// Safety timeout: if geolocation hangs silently (some browsers ignore
|
// Some browsers silently hang on getCurrentPosition (especially with
|
||||||
// the timeout option), reset the button so the user isn't stuck.
|
// enableHighAccuracy:true on desktops without GPS). Use a short safety
|
||||||
|
// timeout and proceed without GPS rather than leaving the user stuck.
|
||||||
const safetyTimeout = setTimeout(() => {
|
const safetyTimeout = setTimeout(() => {
|
||||||
if (mountedRef.current) {
|
if (mountedRef.current) {
|
||||||
setSubmitting(false);
|
submitPunch(action, {});
|
||||||
alert.error("Vypršel časový limit pro získání polohy");
|
|
||||||
setGpsConfirm({ isOpen: true, action });
|
|
||||||
}
|
}
|
||||||
}, 12000);
|
}, 6000);
|
||||||
|
|
||||||
if (!navigator.geolocation) {
|
if (!navigator.geolocation) {
|
||||||
clearTimeout(safetyTimeout);
|
clearTimeout(safetyTimeout);
|
||||||
@@ -207,14 +206,19 @@ export default function Attendance() {
|
|||||||
(position) => {
|
(position) => {
|
||||||
clearTimeout(safetyTimeout);
|
clearTimeout(safetyTimeout);
|
||||||
if (!mountedRef.current) return;
|
if (!mountedRef.current) return;
|
||||||
const { latitude, longitude, accuracy } = position.coords;
|
try {
|
||||||
submitPunch(action, { latitude, longitude, accuracy, address: "" });
|
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();
|
if (geoAbortRef.current) geoAbortRef.current.abort();
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
geoAbortRef.current = controller;
|
geoAbortRef.current = controller;
|
||||||
fetch(
|
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" },
|
headers: { "Accept-Language": "cs" },
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
@@ -229,8 +233,8 @@ export default function Attendance() {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
latitude,
|
latitude: position.coords.latitude,
|
||||||
longitude,
|
longitude: position.coords.longitude,
|
||||||
address: geoData.display_name,
|
address: geoData.display_name,
|
||||||
punch_action: action,
|
punch_action: action,
|
||||||
}),
|
}),
|
||||||
@@ -252,7 +256,7 @@ export default function Attendance() {
|
|||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
setGpsConfirm({ isOpen: true, action });
|
setGpsConfirm({ isOpen: true, action });
|
||||||
},
|
},
|
||||||
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 60000 },
|
{ enableHighAccuracy: false, timeout: 5000, maximumAge: 60000 },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user