Merge claude/2

This commit is contained in:
librelad 2026-05-28 14:12:29 +01:00
commit 1c5ee82a31
3 changed files with 81 additions and 0 deletions

View File

@ -1116,3 +1116,34 @@ body.setup-wizard-open {
color: rgba(var(--text-rgb), 0.65);
line-height: 1.45;
}
/* Dev-mode easter egg strip revealed by 10 taps on the Advanced card
(see setup-wizard.js). [hidden] keeps it out of layout (no phantom gap
from the parent flex column) until JS clears the attribute, at which
point the entrance keyframes play. */
.setup-dev-strip {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 14px;
border-radius: 12px;
background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.16) 0%, rgba(var(--accent-rgb), 0.05) 100%);
border: 1px solid rgba(var(--accent-rgb), 0.5);
box-shadow: 0 6px 22px rgba(var(--accent-rgb), 0.16);
overflow: hidden;
animation: swDevStripIn .4s cubic-bezier(.2, .7, .3, 1) both;
}
/* Author display:flex above outranks the UA [hidden] rule, so re-hide. */
.setup-dev-strip[hidden] { display: none; }
.setup-dev-strip-icon { font-size: 1.5rem; line-height: 1; }
.setup-dev-strip-text { display: flex; flex-direction: column; gap: 2px; }
.setup-dev-strip-text strong { font-size: 0.95rem; font-weight: 700; color: var(--text-primary); }
.setup-dev-strip-text span { font-size: 0.8rem; color: rgba(var(--text-rgb), 0.65); }
@keyframes swDevStripIn {
from { opacity: 0; transform: translateY(-6px); max-height: 0; padding-top: 0; padding-bottom: 0; }
to { opacity: 1; transform: translateY(0); max-height: 160px; padding-top: 12px; padding-bottom: 12px; }
}
@media (prefers-reduced-motion: reduce) {
.setup-dev-strip { animation-duration: .01ms; }
}

View File

@ -23,6 +23,7 @@ class SetupWizard {
this.installLevel = 'beginner';
this.totalSteps = this._effectiveTotalSteps();
this.domainCount = 0; // tracked dynamically as the user adds rows
this.devMode = false; // unlocked by the Advanced-card 10-tap easter egg
}
_effectiveTotalSteps() {
@ -118,6 +119,13 @@ class SetupWizard {
</div>
</label>
</div>
<div class="setup-dev-strip" id="sw-dev-strip" role="status" hidden>
<span class="setup-dev-strip-icon" aria-hidden="true">🛠</span>
<div class="setup-dev-strip-text">
<strong>Dev mode activated</strong>
<span>Developer fields will be unlocked after install.</span>
</div>
</div>
</div>
</section>
@ -270,6 +278,34 @@ class SetupWizard {
});
});
// Easter egg: 10 taps on the Advanced card toggles Developer mode and
// reveals a strip beneath the cards — same 10-tap pattern as the topbar
// logo and services-manager unlocks (CFG_DEV_MODE), persisted on install
// via the setup payload's dev_mode field. Counting the radio's click
// (not the label's) avoids the label→input double-fire: the radio is
// pointer-events:none, so each tap reaches it exactly once via the label.
// A 3s idle gap resets the streak.
const advRadio = this.container.querySelector('input[name="sw-level"][value="advanced"]');
const devStrip = this.container.querySelector('#sw-dev-strip');
if (advRadio && devStrip) {
const TARGET = 10;
let taps = 0;
let resetTimer = null;
advRadio.addEventListener('click', () => {
taps++;
if (resetTimer) clearTimeout(resetTimer);
resetTimer = setTimeout(() => { taps = 0; }, 3000);
if (taps >= TARGET) {
taps = 0;
clearTimeout(resetTimer);
this.devMode = !this.devMode;
// Toggling [hidden] (display:none → flex) replays the entrance
// animation each time it's revealed.
devStrip.hidden = !this.devMode;
}
});
}
$('#setup-form').addEventListener('submit', (e) => {
e.preventDefault();
console.log('[setup] form submit fired');
@ -676,6 +712,7 @@ class SetupWizard {
install_name: $('#sw-name').value.trim(),
timezone: $('#sw-timezone').value,
install_level: this.installLevel,
dev_mode: this.devMode,
domains,
apps,
appOptions,
@ -692,6 +729,11 @@ class SetupWizard {
try { localStorage.setItem('lp.ui.seeded', '1'); } catch {}
} catch {}
}
// Same in-process mirror for the dev-mode easter egg (LpUi.dev enabling
// dev also enables advanced); the bash applier persists CFG_DEV_MODE.
if (this.devMode && window.LpUi?.dev) {
try { window.LpUi.dev.set(true); } catch {}
}
const submitBtn = $('#sw-submit');
submitBtn.disabled = true;

View File

@ -21,6 +21,7 @@ setupApplyConfig()
local install_name=$(echo "$payload" | jq -r '.install_name // empty')
local timezone=$(echo "$payload" | jq -r '.timezone // empty')
local install_level=$(echo "$payload" | jq -r '.install_level // empty')
local dev_mode=$(echo "$payload" | jq -r '.dev_mode // empty')
local traefik_email=$(echo "$payload" | jq -r '.traefik_email // empty')
local domains_json=$(echo "$payload" | jq -c '.domains // []')
@ -43,6 +44,13 @@ setupApplyConfig()
isSuccessful "Experience level set to '$install_level'"
fi
# Developer mode — opt-in via the wizard's Advanced-card easter egg (10
# taps). Unlocks the **DEV**-marked CFG_* fields across the WebUI.
if [[ "$dev_mode" == "true" ]]; then
updateConfigOption "CFG_DEV_MODE" "true"
isSuccessful "Developer mode enabled"
fi
local domains_count=$(echo "$domains_json" | jq -r 'length')
if [[ "$domains_count" -gt 0 ]]; then
local i=0