fix: Web Cam QD and tracking fixed along with resolution increase to support 720p

This commit is contained in:
Sagnik
2026-04-13 02:15:44 +05:30
parent 556eaa2fc1
commit 28d9e46191
12 changed files with 26773 additions and 114 deletions

View File

@@ -1,17 +1,10 @@
/**
* useVelocitySocket — Manages the persistent WebSocket connection to the
* Velocity FastAPI backend. Handles reconnection with exponential backoff,
* routes incoming events to typed handlers, and buffers outgoing packets
* during disconnection for flush-on-reconnect.
*/
import { useEffect, useRef, useCallback } from 'react';
import { useStore } from '@/store/useStore';
import { WS_URL } from '@/lib/api';
import type { QDScoreUpdate, VaultOpenedEvent } from '@/types';
const SENTINEL_WS_ROOT = `${WS_URL}/api/sentinel/ws`;
// Event types coming from the backend
type WsEventType =
| 'WS_ASSET_OPENED'
| 'QD_UPDATED'
@@ -26,13 +19,9 @@ interface WsMessage {
}
interface UseVelocitySocketOptions {
/** Channel name to subscribe to (appended as a path segment) */
channel?: 'notifications' | 'perception';
/** Called when the socket successfully connects */
onConnect?: () => void;
/** Called when the socket disconnects */
onDisconnect?: () => void;
/** Raw message handler — bypasses the built-in notification routing */
onMessage?: (msg: WsMessage) => void;
}
@@ -55,16 +44,14 @@ export function useVelocitySocket(options: UseVelocitySocketOptions = {}) {
return;
}
// Delegate to caller's raw handler if provided
onMessage?.(msg);
// Built-in notification routing
switch (msg.type) {
case 'WS_ASSET_OPENED': {
const d = msg.data as Partial<VaultOpenedEvent>;
addNotification({
type: 'velocity_link_opened',
title: '🚨 Velocity Link Opened',
title: 'Velocity Link Opened',
body: `${d.lead_name ?? 'A prospect'} just opened ${d.asset_name ?? 'your asset'}.`,
leadId: d.lead_id,
});
@@ -75,7 +62,7 @@ export function useVelocitySocket(options: UseVelocitySocketOptions = {}) {
if ((d.qd_score ?? 0) >= 75) {
addNotification({
type: 'qd_spike',
title: '📈 QD Score Spike',
title: 'QD Score Spike',
body: `QD Score jumped to ${d.qd_score}. ${d.reasoning ?? ''}`.trim(),
leadId: d.lead_id,
qdScore: d.qd_score,
@@ -88,7 +75,7 @@ export function useVelocitySocket(options: UseVelocitySocketOptions = {}) {
if (d.tags?.length) {
addNotification({
type: 'lead_tagged',
title: '🏷️ Lead Tagged',
title: 'Lead Tagged',
body: `${d.lead_name ?? 'Lead'} tagged as ${d.tags.join(', ')}.`,
leadId: d.lead_id,
tags: d.tags,
@@ -122,7 +109,7 @@ export function useVelocitySocket(options: UseVelocitySocketOptions = {}) {
ws.onclose = () => {
onDisconnect?.();
if (!isMountedRef.current) return;
// Exponential backoff: 1s, 2s, 4s … cap at 30s
if (retryCountRef.current >= 5) return;
const delay = Math.min(1000 * 2 ** retryCountRef.current, 30_000);
retryCountRef.current += 1;
retryTimerRef.current = setTimeout(connect, delay);
@@ -142,13 +129,11 @@ export function useVelocitySocket(options: UseVelocitySocketOptions = {}) {
};
}, [connect]);
/** Send a JSON-serialisable payload; buffers if the socket is not open */
const sendPacket = useCallback((payload: unknown) => {
const str = JSON.stringify(payload);
if (wsRef.current?.readyState === WebSocket.OPEN) {
wsRef.current.send(str);
} else {
// Buffer up to 100 packets; drop oldest overflow
pendingBufferRef.current.push(str);
if (pendingBufferRef.current.length > 100) {
pendingBufferRef.current.shift();