()
| 15535 | } catch (error) { |
| 15536 | // Silently fail for background checks |
| 15537 | console.debug('Background update check failed:', error); |
| 15538 | } |
| 15539 | } |
| 15540 | |
| 15541 | // ── Files nav flag ─────────────────────────────────────────────────────────── |
| 15542 | // Put a dot on the "Files" nav word (like the Config update flag) when a file is |
| 15543 | // sent to this unit (its mesh Inbox has items) OR shared to the mesh by a peer |
| 15544 | // since it was last viewed. |
| 15545 | let _filesFlagInbox = 0; |
| 15546 | let _filesFlagSharedNew = false; |
| 15547 | function _applyFilesFlag() { |
| 15548 | const on = _filesFlagInbox > 0 || _filesFlagSharedNew; |
| 15549 | document.querySelectorAll('[data-tab="files"]').forEach(btn => { |
| 15550 | let dot = btn.querySelector('.files-flag'); |
| 15551 | if (on) { |
| 15552 | if (!dot) { |
| 15553 | dot = document.createElement('span'); |
| 15554 | dot.className = 'files-flag absolute -top-1 -right-1 w-3 h-3 bg-amber-500 rounded-full pulse-glow'; |
| 15555 | btn.style.position = 'relative'; |
| 15556 | btn.appendChild(dot); |
| 15557 | } |
| 15558 | } else if (dot) { |
| 15559 | dot.remove(); |
| 15560 | } |
| 15561 | }); |
| 15562 | } |
| 15563 | // Sent-to-this-unit case (Inbox count). |
| 15564 | function setFilesNavFlag(count) { _filesFlagInbox = count; _applyFilesFlag(); } |
| 15565 | function refreshFilesFlag() { |
| 15566 | networkAwareFetch('/api/mesh/inbox') |
| 15567 | .then(r => r.json()) |
| 15568 | .then(d => setFilesNavFlag((d && d.items) ? d.items.length : 0)) |
| 15569 | .catch(() => { /* silent — background check */ }); |
| 15570 | } |
| 15571 | // Shared-to-the-mesh case: flag when a peer has shared more files than we last |
| 15572 | // saw. Baselines silently on first observation so pre-existing shares don't flag. |
| 15573 | function refreshSharedFlag() { |
| 15574 | networkAwareFetch('/api/mesh/share') |
no test coverage detected