Merge claude/2

This commit is contained in:
librelad 2026-05-27 14:13:56 +01:00
commit b754794789
3 changed files with 110 additions and 1 deletions

View File

@ -2,6 +2,68 @@
/* Topbar layout, nav pills, donate/logout buttons. Extracted from style.css. Theme via var(--*) tokens. */
/* Developer-mode strip sits flush under the fixed topbar when CFG_DEV_MODE
is on. Amber-tinted glass so it reads as "non-default state" without
shouting. Body gets .has-dev-banner to bump padding-top by the strip's
height; dismissal is local and remembered in localStorage until dev
mode is toggled off + on again. */
.dev-banner {
position: fixed;
top: 60px;
left: 0;
right: 0;
z-index: 999;
height: 36px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
font-size: 0.85rem;
font-weight: 500;
color: var(--text-primary);
background: rgba(var(--status-warning-rgb), 0.14);
border-bottom: 1px solid rgba(var(--status-warning-rgb), 0.35);
backdrop-filter: blur(12px) saturate(140%);
-webkit-backdrop-filter: blur(12px) saturate(140%);
}
.dev-banner[hidden] { display: none; }
.dev-banner-label {
display: inline-flex;
align-items: center;
gap: 8px;
color: var(--status-warning);
}
.dev-banner-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
padding: 0;
background: transparent;
border: none;
border-radius: 6px;
color: var(--text-primary);
opacity: 0.7;
cursor: pointer;
transition: opacity 0.15s ease, background 0.15s ease;
}
.dev-banner-close:hover {
opacity: 1;
background: rgba(var(--text-rgb), 0.1);
}
body.has-dev-banner { padding-top: 96px; }
@media (max-width: 768px) {
.dev-banner { padding: 0 12px; font-size: 0.8rem; }
body.has-dev-banner .mobile-drawer { top: 96px; height: calc(100vh - 96px); }
}
/* Topbar */
.topbar {
display: flex;

View File

@ -1,4 +1,18 @@
<!-- Topbar -->
<div class="dev-banner" id="dev-banner" hidden role="status">
<span class="dev-banner-label">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path>
</svg>
You are currently running in Developer mode
</span>
<button type="button" class="dev-banner-close" id="dev-banner-close" aria-label="Dismiss developer mode banner">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<line x1="6" y1="6" x2="18" y2="18"></line>
<line x1="18" y1="6" x2="6" y2="18"></line>
</svg>
</button>
</div>
<div class="topbar">
<button class="mobile-menu-toggle" id="mobile-menu-toggle" aria-label="Toggle navigation menu">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">

View File

@ -71,6 +71,7 @@ class TopbarComponent {
this.setupConfigUpdateLockout();
this.setupSetupGate();
this.setupDevModeEasterEgg();
this.setupDevBanner();
this.autoEnableDevModeIfNeeded();
// Mount the "out of date" badge now that .topbar-controls exists.
window.updateNotifier?.onTopbarReady();
@ -126,12 +127,38 @@ class TopbarComponent {
const onDevInstall = (installMode === 'git' || installMode === 'local');
const devModeOff = (devMode !== 'true' && devMode !== true);
if (onDevInstall && devModeOff) {
this._devToast(`Developer mode auto-enabled — you're on a ${installMode} install. Click the LibrePortal logo 10× to disable.`, 'success');
this._devToast(`Developer mode auto-enabled — you're on a ${installMode} install.`, 'success');
await this._setDevMode(true, /*silent*/ true);
} else if (devMode === 'true' || devMode === true) {
this._updateDevBanner(true);
}
} catch { /* missing configs.json, network blip — leave it; easter egg still works */ }
}
// Wires the dismiss button on the developer-mode strip. Dismissal is
// remembered in localStorage and cleared whenever dev mode is re-enabled
// (in _setDevMode), so toggling off + back on brings the banner back.
setupDevBanner() {
const btn = document.getElementById('dev-banner-close');
if (!btn) return;
btn.addEventListener('click', () => {
try { localStorage.setItem('lp.devBannerDismissed', 'true'); } catch {}
this._updateDevBanner(false);
});
}
// Show/hide the banner + body padding offset. visible=true only paints
// it when the user hasn't dismissed for this install.
_updateDevBanner(visible) {
const el = document.getElementById('dev-banner');
if (!el) return;
let dismissed = false;
try { dismissed = localStorage.getItem('lp.devBannerDismissed') === 'true'; } catch {}
const shouldShow = visible && !dismissed;
el.hidden = !shouldShow;
document.body.classList.toggle('has-dev-banner', shouldShow);
}
// Toast helper — uses the project's notification system if loaded, else
// a quiet console echo so dev-mode UX never blocks page render.
_devToast(message, kind = 'info') {
@ -163,6 +190,12 @@ class TopbarComponent {
// a full page refresh.
if (!window.systemConfigs) window.systemConfigs = {};
window.systemConfigs.CFG_DEV_MODE = value;
if (enabled) {
try { localStorage.removeItem('lp.devBannerDismissed'); } catch {}
this._updateDevBanner(true);
} else {
this._updateDevBanner(false);
}
if (!silent) {
this._devToast(
enabled