feat(setup): dev-mode easter egg on the Experience step
Tap the Advanced card 10 times and a full-width "Dev mode activated" strip slides in beneath the two cards — the same 10-tap pattern as the topbar logo and services-manager unlocks, now at install time. The choice rides the setup payload (dev_mode) so setup_apply.sh persists CFG_DEV_MODE=true, and it's mirrored in-process via LpUi.dev so the next surface already reflects it. 10 more taps toggles it back off. Counting the Advanced radio's click (not the label's) sidesteps the label->input double-fire; the radio is pointer-events:none, so each tap reaches it exactly once. The strip is [hidden] by default (no phantom gap in the flex column) and replays its entrance keyframes each reveal. Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
af8a4cb22e
commit
5be49b67c6
@ -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; }
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user