mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-10-22 12:52:30 +00:00
Audio: "Tap to enable audio" overlay when context is suspended
Instead of silently dropping notes or hoping gesture listeners fire, show a clear overlay on first packet if AudioContext is suspended. One tap resumes context and removes overlay. Standard pattern used by every browser game/music site.
This commit is contained in:
1 parent
37b89315a4
commit
7514111f5c
3 files changed
+52
-16
No files matched your search
+22
-14
@@ -88,11 +88,13 @@
|
||||
|
||||
function sonifyPacket(pkt) {
|
||||
if (!audioEnabled || !currentVoice) return;
|
||||
// Lazy-init AudioContext on first actual packet (may not have user gesture,
|
||||
// but browser will auto-resume when it gets one)
|
||||
if (!audioCtx) initAudio();
|
||||
if (!audioCtx) return;
|
||||
if (audioCtx.state === 'suspended') audioCtx.resume();
|
||||
if (audioCtx.state === 'suspended') {
|
||||
// Show unlock overlay if not already showing
|
||||
_showUnlockOverlay();
|
||||
return; // don't schedule notes on suspended context
|
||||
}
|
||||
if (activeVoices >= MAX_VOICES) return;
|
||||
|
||||
const parsed = parsePacketBytes(pkt);
|
||||
@@ -175,22 +177,28 @@
|
||||
const savedVoice = localStorage.getItem('live-audio-voice');
|
||||
if (savedVoice) setVoice(savedVoice);
|
||||
|
||||
// If audio was enabled, create context now and try to resume.
|
||||
// Browsers with prior engagement will auto-allow; gesture listener is fallback.
|
||||
// If audio was enabled, create context eagerly. If browser suspends it,
|
||||
// the unlock overlay will appear when the first packet arrives.
|
||||
if (audioEnabled) {
|
||||
initAudio();
|
||||
const unlockAudio = () => {
|
||||
if (audioCtx && audioCtx.state === 'suspended') audioCtx.resume();
|
||||
document.removeEventListener('click', unlockAudio, true);
|
||||
document.removeEventListener('touchstart', unlockAudio, true);
|
||||
document.removeEventListener('keydown', unlockAudio, true);
|
||||
};
|
||||
document.addEventListener('click', unlockAudio, true);
|
||||
document.addEventListener('touchstart', unlockAudio, true);
|
||||
document.addEventListener('keydown', unlockAudio, true);
|
||||
}
|
||||
}
|
||||
|
||||
let _overlayShown = false;
|
||||
|
||||
function _showUnlockOverlay() {
|
||||
if (_overlayShown) return;
|
||||
_overlayShown = true;
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'audio-unlock-overlay';
|
||||
overlay.innerHTML = '<div class="audio-unlock-prompt">🔊 Tap to enable audio</div>';
|
||||
overlay.addEventListener('click', () => {
|
||||
if (audioCtx) audioCtx.resume();
|
||||
overlay.remove();
|
||||
}, { once: true });
|
||||
document.body.appendChild(overlay);
|
||||
}
|
||||
|
||||
// Export engine + helpers for voice modules
|
||||
window.MeshAudio = {
|
||||
sonifyPacket,
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@
|
||||
<meta name="twitter:title" content="MeshCore Analyzer">
|
||||
<meta name="twitter:description" content="Real-time MeshCore LoRa mesh network analyzer — live packet visualization, node tracking, channel decryption, and route analysis.">
|
||||
<meta name="twitter:image" content="https://raw.githubusercontent.com/Kpa-clawbot/meshcore-analyzer/master/public/og-image.png">
|
||||
<link rel="stylesheet" href="style.css?v=1774199178">
|
||||
<link rel="stylesheet" href="style.css?v=1774200683">
|
||||
<link rel="stylesheet" href="home.css">
|
||||
<link rel="stylesheet" href="live.css?v=1774058575">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
@@ -90,7 +90,7 @@
|
||||
<script src="nodes.js?v=1774126708" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="traces.js?v=1774135052" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="analytics.js?v=1774126708" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="audio.js?v=1774200474" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="audio.js?v=1774200683" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="audio-v1-constellation.js?v=1774199178" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="live.js?v=1774199178" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="observers.js?v=1774290000" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
|
||||
@@ -1640,3 +1640,31 @@ tr[data-hops]:hover { background: rgba(59,130,246,0.1); }
|
||||
color: #00ff41 !important;
|
||||
border-color: #00ff4130 !important;
|
||||
}
|
||||
|
||||
/* Audio unlock overlay */
|
||||
.audio-unlock-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 10000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0,0,0,0.6);
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.audio-unlock-prompt {
|
||||
background: #1f2937;
|
||||
color: #e5e7eb;
|
||||
padding: 24px 40px;
|
||||
border-radius: 12px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 4px 24px rgba(0,0,0,0.5);
|
||||
user-select: none;
|
||||
}
|
||||
.matrix-theme .audio-unlock-prompt {
|
||||
background: #001a00;
|
||||
color: #00ff41;
|
||||
box-shadow: 0 0 30px rgba(0,255,65,0.2);
|
||||
}
|
||||
Reference in new issue
Block a user