feat: enhance call and point registration features with sensor data integration
- Updated the CallWindow component to include connection quality states and reconnection attempts, improving user experience during calls. - Enhanced the ChatWindow to allow starting audio and video calls in a new window, providing users with more flexibility. - Integrated accelerometer and gyroscope data collection in the RegistroPonto component, enabling validation of point registration authenticity. - Improved error handling and user feedback for sensor permissions and data validation, ensuring a smoother registration process. - Updated backend logic to validate sensor data and adjust confidence scores for point registration, enhancing security against spoofing.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
import AreaChart from './charts/AreaChart.svelte';
|
||||
import DoughnutChart from './charts/DoughnutChart.svelte';
|
||||
import BarChart from './charts/BarChart.svelte';
|
||||
import { obterInformacoesDispositivo } from '$lib/utils/deviceInfo';
|
||||
|
||||
const client = useConvexClient();
|
||||
|
||||
@@ -45,6 +46,18 @@
|
||||
serviceWorkerStatus: string;
|
||||
domNodes: number;
|
||||
jsHeapSize: number;
|
||||
// GPS
|
||||
latitude?: number;
|
||||
longitude?: number;
|
||||
gpsPrecision?: number;
|
||||
gpsConfidence?: number;
|
||||
// Acelerômetro
|
||||
accelerometerX?: number;
|
||||
accelerometerY?: number;
|
||||
accelerometerZ?: number;
|
||||
movementDetected?: boolean;
|
||||
movementMagnitude?: number;
|
||||
sensorAvailable?: boolean;
|
||||
};
|
||||
|
||||
type NetworkInformationEx = {
|
||||
@@ -548,7 +561,8 @@
|
||||
usuariosOnline,
|
||||
tempoRespostaMedio,
|
||||
batteryInfo,
|
||||
indexedDBSize
|
||||
indexedDBSize,
|
||||
deviceInfo
|
||||
] = await Promise.all([
|
||||
estimateCPU(),
|
||||
Promise.resolve(getMemoryUsage()),
|
||||
@@ -557,14 +571,15 @@
|
||||
getUsuariosOnline(),
|
||||
getResponseTime(),
|
||||
getBatteryInfo(),
|
||||
getIndexedDBSize()
|
||||
getIndexedDBSize(),
|
||||
obterInformacoesDispositivo().catch(() => ({}) as Record<string, unknown>) // Capturar erro se falhar
|
||||
]);
|
||||
|
||||
const browserInfo = getBrowserInfo();
|
||||
const networkInfo = getNetworkInfo();
|
||||
const wsInfo = getWebSocketStatus();
|
||||
|
||||
const newMetrics = {
|
||||
const newMetrics: Metrics = {
|
||||
timestamp: Date.now(),
|
||||
cpuUsage,
|
||||
memoryUsage,
|
||||
@@ -594,7 +609,19 @@
|
||||
indexedDBSize,
|
||||
serviceWorkerStatus: getServiceWorkerStatus(),
|
||||
domNodes: getDOMNodeCount(),
|
||||
jsHeapSize: getJSHeapSize()
|
||||
jsHeapSize: getJSHeapSize(),
|
||||
// GPS
|
||||
latitude: deviceInfo.latitude,
|
||||
longitude: deviceInfo.longitude,
|
||||
gpsPrecision: deviceInfo.precisao,
|
||||
gpsConfidence: deviceInfo.confiabilidadeGPS,
|
||||
// Acelerômetro
|
||||
accelerometerX: deviceInfo.acelerometro?.x,
|
||||
accelerometerY: deviceInfo.acelerometro?.y,
|
||||
accelerometerZ: deviceInfo.acelerometro?.z,
|
||||
movementDetected: deviceInfo.acelerometro?.movimentoDetectado,
|
||||
movementMagnitude: deviceInfo.acelerometro?.magnitude,
|
||||
sensorAvailable: deviceInfo.sensorDisponivel
|
||||
};
|
||||
|
||||
// Resetar contadores
|
||||
@@ -1445,6 +1472,181 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Seção de GPS e Sensores -->
|
||||
<div class="mt-8">
|
||||
<div class="divider">
|
||||
<h2 class="text-primary flex items-center gap-3 text-2xl font-bold">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"
|
||||
/>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"
|
||||
/>
|
||||
</svg>
|
||||
GPS e Sensores
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
<!-- Latitude -->
|
||||
{#if metrics.latitude !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-primary/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Latitude</div>
|
||||
<div class="stat-value text-primary text-2xl">{metrics.latitude.toFixed(6)}</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div class="badge badge-primary badge-sm">GPS</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Longitude -->
|
||||
{#if metrics.longitude !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-primary/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Longitude</div>
|
||||
<div class="stat-value text-primary text-2xl">{metrics.longitude.toFixed(6)}</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div class="badge badge-primary badge-sm">GPS</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Precisão GPS -->
|
||||
{#if metrics.gpsPrecision !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-info/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Precisão GPS</div>
|
||||
<div class="stat-value text-info text-2xl">{metrics.gpsPrecision.toFixed(2)}m</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div class="badge badge-info badge-sm">Precisão</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Confiança GPS -->
|
||||
{#if metrics.gpsConfidence !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-success/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Confiança GPS</div>
|
||||
<div class="stat-value text-success text-2xl">
|
||||
{(metrics.gpsConfidence * 100).toFixed(1)}%
|
||||
</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div class="badge badge-success badge-sm">Confiança</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Acelerômetro X -->
|
||||
{#if metrics.accelerometerX !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-warning/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Acelerômetro X</div>
|
||||
<div class="stat-value text-warning text-2xl">{metrics.accelerometerX.toFixed(3)}</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div class="badge badge-warning badge-sm">m/s²</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Acelerômetro Y -->
|
||||
{#if metrics.accelerometerY !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-warning/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Acelerômetro Y</div>
|
||||
<div class="stat-value text-warning text-2xl">{metrics.accelerometerY.toFixed(3)}</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div class="badge badge-warning badge-sm">m/s²</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Acelerômetro Z -->
|
||||
{#if metrics.accelerometerZ !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-warning/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Acelerômetro Z</div>
|
||||
<div class="stat-value text-warning text-2xl">{metrics.accelerometerZ.toFixed(3)}</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div class="badge badge-warning badge-sm">m/s²</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Magnitude de Movimento -->
|
||||
{#if metrics.movementMagnitude !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-error/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Magnitude de Movimento</div>
|
||||
<div class="stat-value text-error text-2xl">{metrics.movementMagnitude.toFixed(3)}</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div class="badge badge-error badge-sm">m/s²</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Movimento Detectado -->
|
||||
{#if metrics.movementDetected !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-accent/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Movimento Detectado</div>
|
||||
<div class="stat-value text-accent text-3xl">
|
||||
{metrics.movementDetected ? 'Sim' : 'Não'}
|
||||
</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div
|
||||
class="badge {metrics.movementDetected ? 'badge-success' : 'badge-warning'} badge-sm"
|
||||
>
|
||||
{metrics.movementDetected ? 'Ativo' : 'Inativo'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Status do Sensor -->
|
||||
{#if metrics.sensorAvailable !== undefined}
|
||||
<div
|
||||
class="stat bg-base-100 border-secondary/10 rounded-2xl border shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
|
||||
>
|
||||
<div class="stat-title font-semibold">Sensor Disponível</div>
|
||||
<div class="stat-value text-secondary text-3xl">
|
||||
{metrics.sensorAvailable ? 'Sim' : 'Não'}
|
||||
</div>
|
||||
<div class="stat-desc mt-2">
|
||||
<div
|
||||
class="badge {metrics.sensorAvailable ? 'badge-success' : 'badge-ghost'} badge-sm"
|
||||
>
|
||||
{metrics.sensorAvailable ? 'Disponível' : 'Indisponível'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Seção de Gráficos Interativos -->
|
||||
{#if metricsHistory.length > 5}
|
||||
<div class="mt-8">
|
||||
@@ -1608,14 +1810,16 @@
|
||||
</svg>
|
||||
<div>
|
||||
<h3 class="font-bold">
|
||||
Monitoramento Ativo (Modo Local) - 23 Métricas Técnicas + 4 Gráficos Interativos
|
||||
Monitoramento Ativo (Modo Local) - Métricas Técnicas + GPS + Sensores + 4 Gráficos Interativos
|
||||
</h3>
|
||||
<div class="text-xs">
|
||||
<strong>Sistema:</strong> CPU, RAM, Latência, Storage |
|
||||
<strong>Aplicação:</strong> Usuários, Mensagens, Tempo Resposta, Erros, HTTP Requests |
|
||||
<strong>Performance:</strong> FPS, Conexão, Navegador, Tela |
|
||||
<strong>Hardware:</strong> RAM Física, Núcleos CPU, Cache, Bateria, Uptime |
|
||||
<strong>Avançado:</strong> WebSocket, IndexedDB, Service Worker, DOM Nodes, JS Heap
|
||||
<strong>Avançado:</strong> WebSocket, IndexedDB, Service Worker, DOM Nodes, JS Heap |
|
||||
<strong>GPS:</strong> Latitude, Longitude, Precisão, Confiança |
|
||||
<strong>Sensores:</strong> Acelerômetro (X, Y, Z), Magnitude, Movimento Detectado
|
||||
<br />
|
||||
<strong>Gráficos:</strong> Linha (Recursos), Área (Atividade), Donut (Distribuição),
|
||||
Barras (Métricas)
|
||||
|
||||
Reference in New Issue
Block a user