commit 0c8eaff808437374fb56fc7e4236fa300b3539a6
parent 1685bc8eb6148d3a45b5f00dd11beb8e9b2d352a
Author: SageAzakaela <106701693+SageAzakaela@users.noreply.github.com>
Date: Mon, 23 Feb 2026 00:20:09 -0700
second onboarding pass
Diffstat:
3 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/public/app.js b/public/app.js
@@ -118,6 +118,7 @@ const mobileSortCycleBtn = document.getElementById("mobileSortCycle");
const clearFilterBtn = document.getElementById("clearFilter");
const feedEl = document.getElementById("feed");
const hiveTabsEl = document.getElementById("hiveTabs");
+const onboardingGateHintEl = document.getElementById("onboardingGateHint");
const onboardingPanelEl = document.getElementById("onboardingPanel");
const onboardingPanelBodyEl = document.getElementById("onboardingPanelBody");
const onboardingPanelAcceptBtn = document.getElementById("onboardingPanelAccept");
@@ -6680,6 +6681,57 @@ function onboardingNeedsAcceptanceNow() {
return Boolean(onboardingState.needsAcceptance || Number(onboardingState.acceptedRulesVersion || 0) < Number(onboardingState.rulesVersion || 1));
}
+function onboardingBlocksReadingNow() {
+ return Boolean(loggedInUser && onboardingNeedsAcceptanceNow() && onboardingState.blockReadUntilAccepted);
+}
+
+function openOnboardingView() {
+ onboardingViewerTab = "about";
+ renderOnboardingPanel();
+ if (isMobileScreenMode()) {
+ const layout = loadMobileLayout();
+ layout.active = "onboarding";
+ saveMobileLayout(layout);
+ setMobileScreen("onboarding");
+ renderMobileNav();
+ return;
+ }
+ if (rackLayoutEnabled) {
+ try {
+ if (
+ layoutPresetEl instanceof HTMLSelectElement &&
+ Array.from(layoutPresetEl.options || []).some((opt) => String(opt.value || "") === "onboardingDefault")
+ ) {
+ if (layoutPresetEl.value !== "onboardingDefault") layoutPresetEl.value = "onboardingDefault";
+ applyPreset("onboardingDefault");
+ }
+ restorePanelToWorkspaceSlot("onboarding", "workspaceLeftSlot");
+ restorePanelToWorkspaceSlot("hives", "workspaceRightSlot");
+ } catch {
+ // ignore layout failures
+ }
+ }
+ try {
+ onboardingPanelEl?.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
+ } catch {
+ // ignore
+ }
+}
+
+function renderOnboardingGateHint() {
+ if (!(onboardingGateHintEl instanceof HTMLElement)) return;
+ const show = onboardingBlocksReadingNow();
+ onboardingGateHintEl.classList.toggle("hidden", !show);
+ if (!show) {
+ onboardingGateHintEl.innerHTML = "";
+ return;
+ }
+ onboardingGateHintEl.innerHTML = `
+ <div class="onboardingGateText">This instance requires that you read and accept its guidelines before you can view posts.</div>
+ <button type="button" class="ghost smallBtn" data-onboarding-open="1">Go to Onboarding</button>
+ `;
+}
+
function onboardingSeverityLabel(severity) {
const s = String(severity || "").toLowerCase();
if (s === "critical") return "Critical";
@@ -6907,6 +6959,7 @@ function setAuthUi() {
codeRow.classList.toggle("hidden", !registrationEnabled);
registerBtn.classList.toggle("hidden", !(registrationEnabled || canRegisterFirstUser));
if (appRoot) appRoot.classList.toggle("authLockedWorkspace", !loggedInUser);
+ renderOnboardingGateHint();
renderOnboardingCard();
renderModPanel();
if (tourBtn instanceof HTMLButtonElement) {
@@ -10888,6 +10941,12 @@ feedEl.addEventListener("click", (e) => {
}
});
+onboardingGateHintEl?.addEventListener("click", (e) => {
+ const btn = e.target?.closest?.("button[data-onboarding-open]");
+ if (!btn) return;
+ openOnboardingView();
+});
+
window.addEventListener("keydown", (e) => {
if (e.key !== "Escape") return;
if (!openPostMenuId) return;
diff --git a/public/index.html b/public/index.html
@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bzl - Hives</title>
- <link rel="stylesheet" href="/styles.css?v=132" />
+ <link rel="stylesheet" href="/styles.css?v=133" />
</head>
<body>
<div class="app">
@@ -218,6 +218,7 @@
</div>
</div>
<div class="uiHint">Use filters to narrow posts, then tap <b>Chat</b> on a hive card. Cards now show latest chat/typing. Shortcut: <b>-</b>/<b>=</b> cycles collections/views.</div>
+ <div id="onboardingGateHint" class="onboardingGateHint hidden"></div>
<div class="hiveTabs" id="hiveTabs">
<button type="button" data-hiveview="all" class="primary">All</button>
<button type="button" data-hiveview="starred" class="ghost">Starred</button>
diff --git a/public/styles.css b/public/styles.css
@@ -3841,6 +3841,25 @@ button:disabled {
pointer-events: none;
}
+.onboardingGateHint {
+ margin-top: 8px;
+ margin-bottom: 8px;
+ border-radius: 12px;
+ border: 1px solid color-mix(in oklab, var(--bad) 55%, var(--line) 45%);
+ background: linear-gradient(180deg, rgba(255, 77, 138, 0.16), rgba(255, 77, 138, 0.07));
+ padding: 10px 12px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+}
+
+.onboardingGateText {
+ color: color-mix(in oklab, var(--text) 92%, white 8%);
+ font-size: 13px;
+ line-height: 1.35;
+}
+
.guidedTourCard {
position: absolute;
left: 50%;