Fix atlas-card click + wire live audio + verify pipeline

- Add hidden admin-screen stub to index.html. The live JS calls
  adminEl.setAttribute() on every hashchange (via openAdmin/closeAdmin);
  with the element missing those threw a null-ref that killed
  syncRouter mid-flight, so atlas card clicks set the hash but never
  opened the detail modal. Stub is empty - menu items navigate to
  BirdNET-Pi's stock pages instead of triggering in-app admin.

- Point the live-audio Audio() at /stream (BirdNET-Pi's existing
  icecast reverse-proxy from install_services.sh:189) instead of the
  worker's /birdnet/stream. The drawer's live-audio button now plays
  real BirdNET-Pi audio on local installs.

Verified end-to-end in Docker container:
- Landing collage: 4 tiles render from seeded DB
- Atlas click: detail modal opens with image + sci/common name
- Menu drawer: opens, shows 4 items (no password in local mode)
- Auto-refresh: INSERTed Bubo virginianus into birds.db, forced
  refresh via window picker re-click, tile count 4→5 with the new
  species appearing in the collage.
This commit is contained in:
Twarner491
2026-05-28 12:03:18 -07:00
parent 2dcb6d2fc3
commit 65ac7efef4
2 changed files with 13 additions and 1 deletions
+1 -1
View File
@@ -1322,7 +1322,7 @@
// race a timeout because icecast can take 110s to warm up
// depending on tunnel + bitrate.
return new Promise(function (resolve, reject) {
liveEl = new Audio('?t=' + Date.now());
liveEl = new Audio('/stream?t=' + Date.now());
// No crossOrigin — the stream is same-origin via the worker
// and crossOrigin='anonymous' would require CORS headers
// icecast doesn't send.
+12
View File
@@ -187,6 +187,18 @@
<button type="button" data-i="2">atlas</button>
</nav>
<!-- AvianVisitors: empty admin-screen stub. The live JS expects this
element to exist (openAdmin/closeAdmin call setAttribute on it).
Menu items navigate to BirdNET-Pi's stock pages instead of opening
in-app admin views, so this stays empty. -->
<section class="admin-screen" id="adminScreen" aria-hidden="true">
<div class="admin-frame">
<header class="admin-title"><h1 id="adminTitle"></h1></header>
<div class="admin-body" id="adminBody"></div>
</div>
</section>
<script src="./apt.js"></script>
</body>
</html>