mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-05-01 13:03:01 +00:00
feat(web): update-available banner in web UI (#311)
* feat(web): add update-available banner to web UI Adds a polite, dismissible banner between the header and navigation tabs that appears when the local repo is behind origin/main. Shows commit count and a one-click "Update Now" button that triggers the existing git_pull action. - New GET /api/v3/system/check-update endpoint (5-min cache, compares local HEAD vs origin/main SHA) - Banner auto-checks on page load then every 30 minutes - Dismiss persists for the browser session via sessionStorage - Styled for both light and dark themes - Cache invalidated after successful git_pull so banner hides immediately Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(update-banner): address review findings — lock, returncode checks, update_available logic, a11y, button state - Add _update_check_lock (threading.Lock) around all reads/writes to _update_check_cache in check_for_update() and git_pull, preventing races on concurrent requests - Validate returncode for git fetch, rev-parse HEAD, and rev-parse origin/main; raise RuntimeError on failure so errors are caught and returned as error payloads instead of silently producing stale/empty SHAs - Set update_available = commits_behind > 0 (was unconditionally True when local_sha != remote_sha); prevents false positive when local is ahead of remote - Add type="button" and aria-label="Dismiss update" to the icon-only dismiss button - Restore btn.innerHTML and btn.disabled in both success and error paths of applyUpdate(); only hide the banner and clear sessionStorage when data.status === 'success' Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(update-banner): address second-round review findings api_v3.py: - Move all git work inside _update_check_lock so concurrent requests re-check cache staleness after acquiring the lock; only the first caller runs git fetch/rev-parse/log, subsequent callers return the cached result - Check log_result.returncode and raise on failure so a broken git log doesn't produce a silent false-negative (commits_behind=0) - Rename loop variable l → commit_line base.html: - Replace boolean _dismissed flag with SHA-scoped sessionStorage key 'update-sha-dismissed'; dismissing for SHA X still allows the banner to reappear when origin/main advances to SHA Y - Successful applyUpdate clears 'update-sha-dismissed' so the next update cycle can show the banner again - Add aria-live="polite" aria-atomic="true" to #update-banner-text so screen readers announce content changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Chuck <chuck@example.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1004,3 +1004,39 @@ button.bg-white {
|
||||
[data-theme="dark"] .theme-toggle-btn {
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
/* Update available banner */
|
||||
.update-banner {
|
||||
background-color: #eff6ff;
|
||||
border-color: #bfdbfe;
|
||||
color: #1e40af;
|
||||
}
|
||||
.update-banner-action {
|
||||
background-color: #3b82f6;
|
||||
color: #fff;
|
||||
}
|
||||
.update-banner-action:hover {
|
||||
background-color: #2563eb;
|
||||
}
|
||||
.update-banner-dismiss {
|
||||
color: #1e40af;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.update-banner-dismiss:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .update-banner {
|
||||
background-color: #1e293b;
|
||||
border-color: #334155;
|
||||
color: #93c5fd;
|
||||
}
|
||||
[data-theme="dark"] .update-banner-action {
|
||||
background-color: #2563eb;
|
||||
}
|
||||
[data-theme="dark"] .update-banner-action:hover {
|
||||
background-color: #3b82f6;
|
||||
}
|
||||
[data-theme="dark"] .update-banner-dismiss {
|
||||
color: #93c5fd;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user