diff --git a/frontend/src/components/LogsFooter.css b/frontend/src/components/LogsFooter.css index 7279088a..c9b10263 100644 --- a/frontend/src/components/LogsFooter.css +++ b/frontend/src/components/LogsFooter.css @@ -219,6 +219,50 @@ gap: 2px; } +/* Clickable app-version badge → Settings → Updates (sits by the network icon) */ +.logs-footer__version { + background: none; + border: none; + cursor: pointer; + flex-shrink: 0; + padding: 0 6px; + height: var(--chrome-icon-btn); + border-radius: 4px; + font-size: 11px; + font-variant-numeric: tabular-nums; + letter-spacing: 0.02em; + color: var(--chrome-fg, #ebdbb2); + opacity: 0.55; + transition: opacity 0.15s, color 0.15s; +} +.logs-footer__version:hover { + opacity: 1; + color: var(--chrome-accent, #b8bb26); + text-decoration: underline; +} +/* Update-available: highlight the badge + a pulsing notification dot. */ +.logs-footer__version--update { + position: relative; + opacity: 1; + color: var(--chrome-accent, #b8bb26); + font-weight: 600; +} +.logs-footer__version-dot { + display: inline-block; + width: 6px; + height: 6px; + margin-left: 5px; + border-radius: 50%; + background: var(--chrome-accent, #b8bb26); + box-shadow: 0 0 0 0 color-mix(in srgb, var(--chrome-accent, #b8bb26) 60%, transparent); + animation: version-dot-pulse 2s ease-in-out infinite; + vertical-align: middle; +} +@keyframes version-dot-pulse { + 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--chrome-accent, #b8bb26) 55%, transparent); } + 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--chrome-accent, #b8bb26) 0%, transparent); } +} + /* Discord button */ .logs-footer__discord { background: none; diff --git a/frontend/src/components/LogsFooter.jsx b/frontend/src/components/LogsFooter.jsx index 9728e150..33981476 100644 --- a/frontend/src/components/LogsFooter.jsx +++ b/frontend/src/components/LogsFooter.jsx @@ -12,6 +12,7 @@ import { getFrontendLogs, clearFrontendLogs } from '../utils/consoleBuffer'; import { useTranslation } from 'react-i18next'; import { useAppStore } from '../store'; import NetworkToggle from './NetworkToggle'; +import { APP_VERSION } from '../utils/appVersion'; import './LogsFooter.css'; /** @@ -142,6 +143,10 @@ export default function LogsFooter() { } const [collapsed, setCollapsed] = useState(true); const { t } = useTranslation(); + // Update availability drives the footer version badge's notification dot. + const updateStatus = useAppStore((s) => s.updateStatus); + const updateVersion = useAppStore((s) => s.updateVersion); + const updateReady = updateStatus === 'available' || updateStatus === 'ready'; const [height, setHeight] = useState(() => { const v = Number(localStorage.getItem(LS_HEIGHT)); return Number.isFinite(v) && v >= MIN_H && v <= MAX_H ? v : 300; @@ -412,6 +417,20 @@ export default function LogsFooter() { )} +