feat: enhance webcam capture and geolocation functionality

- Improved webcam capture process with multiple constraint strategies for better compatibility and error handling.
- Added loading state management for video readiness, enhancing user experience during webcam access.
- Refactored geolocation retrieval to implement multiple strategies, improving accuracy and reliability in obtaining user location.
- Enhanced error handling for both webcam and geolocation features, providing clearer feedback to users.
This commit is contained in:
2025-11-18 16:20:38 -03:00
parent b01d2d6786
commit 67d6b3ec72
2 changed files with 360 additions and 93 deletions

View File

@@ -230,7 +230,7 @@ function obterInformacoesMemoria(): string {
}
/**
* Obtém localização via GPS
* Obtém localização via GPS com múltiplas tentativas
*/
async function obterLocalizacao(): Promise<{
latitude?: number;
@@ -242,76 +242,131 @@ async function obterLocalizacao(): Promise<{
pais?: string;
}> {
if (typeof navigator === 'undefined' || !navigator.geolocation) {
console.warn('Geolocalização não suportada');
return {};
}
return new Promise((resolve) => {
const timeout = setTimeout(() => {
resolve({});
}, 5000); // Timeout de 5 segundos (reduzido para não bloquear)
// Tentar múltiplas estratégias
const estrategias = [
// Estratégia 1: Alta precisão (mais lento, mas mais preciso)
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
},
// Estratégia 2: Precisão média (balanceado)
{
enableHighAccuracy: false,
timeout: 8000,
maximumAge: 30000
},
// Estratégia 3: Rápido (usa cache)
{
enableHighAccuracy: false,
timeout: 5000,
maximumAge: 60000
}
];
navigator.geolocation.getCurrentPosition(
async (position) => {
clearTimeout(timeout);
const { latitude, longitude, accuracy } = position.coords;
for (const options of estrategias) {
try {
const resultado = await new Promise<{
latitude?: number;
longitude?: number;
precisao?: number;
endereco?: string;
cidade?: string;
estado?: string;
pais?: string;
}>((resolve) => {
const timeout = setTimeout(() => {
resolve({});
}, options.timeout + 1000);
// Tentar obter endereço via reverse geocoding
let endereco = '';
let cidade = '';
let estado = '';
let pais = '';
navigator.geolocation.getCurrentPosition(
async (position) => {
clearTimeout(timeout);
const { latitude, longitude, accuracy } = position.coords;
try {
const response = await fetch(
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude}&lon=${longitude}&zoom=18&addressdetails=1`
);
if (response.ok) {
const data = (await response.json()) as {
address?: {
road?: string;
house_number?: string;
city?: string;
town?: string;
state?: string;
country?: string;
};
};
if (data.address) {
const addr = data.address;
if (addr.road) {
endereco = `${addr.road}${addr.house_number ? `, ${addr.house_number}` : ''}`;
}
cidade = addr.city || addr.town || '';
estado = addr.state || '';
pais = addr.country || '';
// Validar coordenadas
if (isNaN(latitude) || isNaN(longitude) || latitude === 0 || longitude === 0) {
resolve({});
return;
}
}
} catch (error) {
console.warn('Erro ao obter endereço:', error);
}
resolve({
latitude,
longitude,
precisao: accuracy,
endereco,
cidade,
estado,
pais,
});
},
(error) => {
clearTimeout(timeout);
console.warn('Erro ao obter localização:', error);
resolve({});
},
{
enableHighAccuracy: false, // false para ser mais rápido
timeout: 5000, // Timeout reduzido para 5 segundos
maximumAge: 60000, // Aceitar localização de até 1 minuto atrás
// Tentar obter endereço via reverse geocoding
let endereco = '';
let cidade = '';
let estado = '';
let pais = '';
try {
const response = await fetch(
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude}&lon=${longitude}&zoom=18&addressdetails=1`,
{
headers: {
'User-Agent': 'SGSE-App/1.0'
}
}
);
if (response.ok) {
const data = (await response.json()) as {
address?: {
road?: string;
house_number?: string;
city?: string;
town?: string;
state?: string;
country?: string;
};
};
if (data.address) {
const addr = data.address;
if (addr.road) {
endereco = `${addr.road}${addr.house_number ? `, ${addr.house_number}` : ''}`;
}
cidade = addr.city || addr.town || '';
estado = addr.state || '';
pais = addr.country || '';
}
}
} catch (error) {
console.warn('Erro ao obter endereço:', error);
}
resolve({
latitude,
longitude,
precisao: accuracy,
endereco,
cidade,
estado,
pais,
});
},
(error) => {
clearTimeout(timeout);
console.warn('Erro ao obter localização:', error.code, error.message);
resolve({});
},
options
);
});
// Se obteve localização, retornar
if (resultado.latitude && resultado.longitude) {
console.log('Localização obtida com sucesso:', resultado);
return resultado;
}
);
});
} catch (error) {
console.warn('Erro na estratégia de geolocalização:', error);
continue;
}
}
// Se todas as estratégias falharam, retornar vazio
console.warn('Não foi possível obter localização após todas as tentativas');
return {};
}
/**