feat(v27): directional FOV approach filter, dynamic ETA countdown, windshield mirror HUD, stealth AMOLED night mode, 1-tap driving sighting stamp, audio boost and steering haptics

This commit is contained in:
2026-09-12 19:01:06 -07:00
parent 671c908c46
commit 4f8c67e6f6
4 changed files with 862 additions and 128 deletions
+81 -19
View File
@@ -54,7 +54,7 @@
<meta name="apple-mobile-web-app-title" content="FlockRadar">
<!-- Main Stylesheet -->
<link rel="stylesheet" href="css/styles.css?v=26">
<link rel="stylesheet" href="css/styles.css?v=27">
</head>
<body>
@@ -155,7 +155,7 @@
<span>ALL CLEAR</span>
</div>
<!-- Metrics Row: Speed + Nearest Distance -->
<!-- Metrics Row: Speed + Nearest Distance + Intercept ETA -->
<div class="hud-metrics-row">
<div class="hud-metric-box">
<div class="hud-val-group">
@@ -175,6 +175,14 @@
</div>
<span class="hud-metric-label">Nearest</span>
</div>
<div class="hud-metric-box" id="hud-eta-box">
<div class="hud-val-group">
<span class="hud-metric-number" id="hud-eta-val"></span>
<span class="hud-metric-unit" id="hud-eta-sub">SEC</span>
</div>
<span class="hud-metric-label">Intercept</span>
</div>
</div>
<!-- Header Quick Triggers (Audio Toggle, Tools, Search) -->
@@ -197,14 +205,17 @@
</div>
</div>
<!-- Current Agency / Street Monitoring -->
<!-- Current Agency / Street Monitoring & Approach Vector Badge -->
<div class="hud-location-bar">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="var(--accent-cyan)" stroke-width="2">
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="8" x2="12.01" y2="8"></line>
<polyline points="11 12 12 12 12 16 13 16"></polyline>
</svg>
<span id="hud-cam-agency">Monitoring Roadway Grid</span>
<div class="hud-loc-left" style="display:flex; align-items:center; gap:6px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; min-width:0;">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="var(--accent-cyan)" stroke-width="2" style="flex-shrink:0;">
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="8" x2="12.01" y2="8"></line>
<polyline points="11 12 12 12 12 16 13 16"></polyline>
</svg>
<span id="hud-cam-agency" style="overflow:hidden; text-overflow:ellipsis;">Monitoring Roadway Grid</span>
</div>
<span id="hud-approach-badge" class="hud-approach-badge approach-none">ALL CLEAR</span>
</div>
<!-- High-Priority Pulsing Warning Banner -->
@@ -370,6 +381,47 @@
</button>
</div>
<!-- Cockpit Display & Windshield Reflection HUD -->
<div class="tools-group">
<div class="tools-group-label">COCKPIT & WINDSHIELD HUD</div>
<div class="tools-toggle-grid">
<button type="button" id="btn-mirror-hud" class="btn-hud-action btn-tool-item" title="Mirror HUD horizontally so phone placed flat on dashboard reflects right-side up on windshield glass">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="7 8 3 12 7 16"/><polyline points="17 8 21 12 17 16"/><line x1="14" y1="4" x2="10" y2="20"/></svg>
<span id="mirror-hud-label">Windshield Mirror: OFF</span>
</button>
<button type="button" id="btn-stealth-amoled" class="btn-hud-action btn-tool-item" title="Switch to pitch-black #000000 AMOLED stealth mode for zero cockpit glare">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
<span id="stealth-amoled-label">AMOLED Pitch Dark: OFF</span>
</button>
</div>
</div>
<!-- Cabin Sound Boost & Haptic Feedback -->
<div class="tools-group">
<div class="tools-group-label">CABIN SOUND & HAPTICS</div>
<div class="tools-toggle-grid">
<button type="button" id="btn-toggle-audio-boost" class="btn-hud-action btn-tool-item" title="Boost radar siren & voice chime volume by +6dB (160%) for loud road noise">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"/><line x1="22" y1="2" x2="22" y2="8"/><line x1="19" y1="5" x2="25" y2="5"/></svg>
<span id="audio-boost-label">Audio Boost (+6dB): OFF</span>
</button>
<button type="button" id="btn-toggle-haptic-boost" class="btn-hud-action btn-tool-item active" title="Vibrate phone on zone entry like lane-keep steering wheel feedback">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"/><line x1="2" y1="8" x2="2" y2="16"/><line x1="22" y1="8" x2="22" y2="16"/></svg>
<span id="haptic-boost-label">Steering Haptics: ON</span>
</button>
</div>
</div>
<!-- Instant Stamped Sightings -->
<div class="tools-group" id="group-quick-stamps">
<div class="tools-group-label" style="display: flex; justify-content: space-between; align-items: center;">
<span>SAVED SIGHTINGS (<span id="stamps-count">0</span>)</span>
<button type="button" id="btn-clear-stamps" class="btn-mini-clear" title="Clear all local quick stamps">Clear</button>
</div>
<div id="stamps-list-container" class="stamps-list-container">
<p class="stamps-empty-hint">No quick stamps yet. Tap ⚡ Stamp while driving to record GPS instantly.</p>
</div>
</div>
<!-- Driving Audio Alert Mode Selector -->
<div class="tools-group">
<div class="tools-group-label">AUDIO ALERT STYLE</div>
@@ -506,15 +558,25 @@
<span>Recenter on Vehicle</span>
</button>
<!-- Giant 1-Tap Floating Action Button: Snap & Log Flock Camera (Bottom-Right) -->
<!-- Floating Action Buttons: Instant GPS Sighting Stamp + Photo Evidence (Bottom-Right) -->
<div class="driver-fab-container">
<button id="btn-quick-log-cam" class="btn-driver-fab" title="Snap camera photo on pole & log at GPS location">
<button id="btn-quick-mark-dash" class="btn-driver-fab btn-fab-stamp" title="⚡ 1-Tap Instant Sighting Stamp (Safe while driving - records GPS location instantly without typing)">
<div class="fab-icon-glow">
<svg class="flock-svg flock-svg-lg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/></svg>
<svg class="flock-svg flock-svg-md" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>
</div>
<div class="fab-text-group">
<span class="fab-main-title">+ SNAP & LOG CAMERA</span>
<span class="fab-sub-title">Opens Camera for Photo Proof</span>
<span class="fab-main-title"> STAMP</span>
<span class="fab-sub-title">1-Tap GPS Mark</span>
</div>
</button>
<button id="btn-quick-log-cam" class="btn-driver-fab btn-fab-photo" title="Snap camera photo on pole & log at GPS location">
<div class="fab-icon-glow">
<svg class="flock-svg flock-svg-md" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/></svg>
</div>
<div class="fab-text-group">
<span class="fab-main-title">+ SNAP</span>
<span class="fab-sub-title">Photo Proof</span>
</div>
</button>
</div>
@@ -1509,11 +1571,11 @@
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<!-- Data & Application Logic with Cache Busting -->
<script src="data/portals.js?v=26"></script>
<script src="js/icons.js?v=26"></script>
<script src="js/auth.js?v=26"></script>
<script src="js/radar.js?v=26"></script>
<script src="js/app.js?v=26"></script>
<script src="data/portals.js?v=27"></script>
<script src="js/icons.js?v=27"></script>
<script src="js/auth.js?v=27"></script>
<script src="js/radar.js?v=27"></script>
<script src="js/app.js?v=27"></script>
<!-- Service Worker Instant Cache Invalidation -->
<script>