chore(debug-1396): nav-instrumentation banner — gated on hash ?navdebug=1 (#1398)

## Summary

Temporary diagnostic patch for #1396 (mobile / narrow-desktop nav
priority reports). Adds a single instrumentation block at the END of
`applyNavPriority()` in `public/app.js`, gated on `navdebug=1` appearing
in the URL hash. No nav behavior change; reverted once root cause is
known.

## What it does

When the URL hash contains `navdebug=1` (e.g. `/#/channels?navdebug=1`),
the function:

1. Paints a fixed-position green-on-black banner pinned to the bottom of
the viewport (`z-index:99999`, `pointer-events:none` so it never blocks
interaction) showing:
   ```
[NAV-DEBUG-1396] vw=<innerWidth> total=N visible=N overflow=N
hidden-by-css=N active=<label>
   visible: [Home,Packets,...]
   overflow: [Tools,...]
   ua: <first 80 chars of UA>
   ```
2. Emits the same payload via `console.warn('[NAV-DEBUG-1396]', ...)`
for anyone who can pop devtools.

The whole block is wrapped in `try/catch` — diagnostic code never breaks
nav.

## Why a banner (not just console)

Affected reporters are on mobile devices where popping devtools is
annoying or impossible. A screenshot of the banner gives us:
- Viewport width (vs the 768 / 1100 / 1101 breakpoints)
- Device UA (Safari iOS quirks, narrow Android, etc.)
- Actual link counts after `applyNavPriority` ran
- Whether anything is hidden by CSS (`display:none`) despite not being
in the overflow set
- Which labels are inline vs in the More menu
- Active route at time of measurement

## Operator usage

On the affected device, open:

```
https://<staging-host>/#/channels?navdebug=1
```

(or any other route; the gate is hash-wide). Screenshot the
green-on-black banner at the bottom of the page and attach to #1396.

## Hard rules respected

- Banner is gated — never visible without `navdebug=1` in the hash.
- No new dependency.
- No change to nav behavior.
- Diagnostic-only; revert PR will follow once root cause is identified.

## Out of scope

- Root-cause fix for #1396 (this is purely instrumentation).
- E2E test for the banner — code is temporary and scheduled for revert.

Co-authored-by: openclaw-bot <bot@openclaw.local>
This commit is contained in:
Kpa-clawbot
2026-05-26 07:47:11 -07:00
committed by GitHub
parent 86d503cd14
commit 7f5cc96bd9
+34
View File
@@ -1327,6 +1327,40 @@ window.addEventListener('DOMContentLoaded', () => {
}
}
rebuildMoreMenu();
// #1396 diagnostic — temporary; remove once root cause known.
// Gated on `navdebug=1` appearing anywhere in the URL hash (the
// app is hash-routed, so this works with e.g. `#/channels?navdebug=1`).
// Operator runs the affected device against staging with that
// hash and screenshots the green-on-black banner pinned to the
// bottom of the viewport — gives us viewport width, UA, total/
// visible/overflow counts, CSS-hidden count, and the actual link
// labels in each bucket without needing devtools.
try {
if (typeof window !== 'undefined' && window.location.hash.indexOf('navdebug=1') !== -1) {
var __dbgTotal = allLinks.length;
var __dbgVisible = allLinks.filter(function(a){ return !a.classList.contains('is-overflow'); });
var __dbgOverflow = allLinks.filter(function(a){ return a.classList.contains('is-overflow'); });
var __dbgHiddenByCss = __dbgVisible.filter(function(a){
return window.getComputedStyle(a).display === 'none';
});
var __dbgVisNames = __dbgVisible.map(function(a){ return (a.textContent||'').trim().slice(0,12); }).join(',');
var __dbgOvrNames = __dbgOverflow.map(function(a){ return (a.textContent||'').trim().slice(0,12); }).join(',');
var __dbgActive = (allLinks.filter(function(a){ return a.classList.contains('active'); })[0] || {}).textContent || '';
__dbgActive = (__dbgActive || '').trim().slice(0,20);
var __dbgBanner = document.getElementById('__navdebug') || document.createElement('div');
__dbgBanner.id = '__navdebug';
__dbgBanner.style.cssText = 'position:fixed;bottom:0;left:0;right:0;background:#000;color:#0f0;font:11px ui-monospace,monospace;padding:4px 8px;z-index:99999;white-space:pre-wrap;word-break:break-all;pointer-events:none';
__dbgBanner.textContent =
'[NAV-DEBUG-1396] vw=' + window.innerWidth + ' total=' + __dbgTotal +
' visible=' + __dbgVisible.length + ' overflow=' + __dbgOverflow.length +
' hidden-by-css=' + __dbgHiddenByCss.length + ' active=' + __dbgActive + '\n' +
'visible: [' + __dbgVisNames + ']\n' +
'overflow: [' + __dbgOvrNames + ']\n' +
'ua: ' + (navigator.userAgent || '').slice(0,80);
if (!__dbgBanner.parentNode) document.body.appendChild(__dbgBanner);
console.warn('[NAV-DEBUG-1396]', __dbgBanner.textContent);
}
} catch (e) { /* diagnostic only — never break nav */ }
}
// Run once on load, again after fonts settle (label widths shift),