feat: Doing more polishing (M8b)

This commit is contained in:
gauvainboiche
2026-10-25 18:50:17 +01:00
parent c2103c32e7
commit c55e5a2484
34 changed files with 1605 additions and 106 deletions
+56
View File
@@ -0,0 +1,56 @@
// Phone layout only: the shelf along the top of the desk. It shows the date and a small dial,
// cycles the speed, and picks which single paper is on the desk (tray, briefing, news,
// calendar, and the ledger while a budget review is open).
import { t, dateParts } from "../i18n/i18n.js";
import { dateOfDay } from "../engine/index.js";
import { $, dialSvg, setDial } from "./desk.js";
const VIEWS = ["tray", "brief", "news", "clock"];
export function createShelf(root, bal, { getView, onView, onSpeed, onMenu }) {
const speeds = [0, ...bal.time.speeds];
root.innerHTML = `
<div class="shelf__time">
${dialSvg("shelf__dial")}
<div class="shelf__date"><b></b><span></span></div>
<button class="brass shelf__speed" data-speed-cycle></button>
</div>
<div class="shelf__tabs" role="group" aria-label="${t("shelf.nav")}">
${VIEWS.map((v) => `<button class="shelf__tab" data-view="${v}"><span>${t("shelf." + v)}</span>${v === "tray" ? `<i class="shelf__badge" data-badge></i>` : ""}</button>`).join("")}
<button class="shelf__tab shelf__tab--ledger" data-view="ledger" hidden><span>${t("shelf.ledger")}</span></button>
<button class="shelf__tab shelf__tab--menu" data-menu><span>${t("shelf.menu")}</span></button>
</div>`;
const dial = $(root, ".shelf__dial");
let speed = 0;
root.addEventListener("click", (e) => {
const b = e.target.closest("button");
if (!b) return;
if (b.dataset.menu !== undefined) onMenu();
else if (b.dataset.speedCycle !== undefined) onSpeed(speeds[(speeds.indexOf(speed) + 1) % speeds.length]);
else if (b.dataset.view) onView(b.dataset.view);
});
function update(state) {
const d = dateParts(dateOfDay(state.startDate, state.day).iso);
$(root, ".shelf__date b").textContent = `${d.weekday} ${d.day} ${d.month}`;
$(root, ".shelf__date span").textContent = d.year;
speed = state.speed;
const sp = $(root, ".shelf__speed");
sp.textContent = speed === 0 ? "II" : `${speed}×`;
sp.setAttribute("aria-label", speed === 0 ? t("cal.pause") : t("cal.speed", { n: speed }));
const view = getView();
const ledger = Boolean(state.pending.review && !state.pending.profile && !state.over);
$(root, '[data-view="ledger"]').hidden = !ledger;
for (const b of root.querySelectorAll("[data-view]")) b.setAttribute("aria-pressed", String(b.dataset.view === view));
const badge = $(root, "[data-badge]");
badge.textContent = state.inbox.length || "";
badge.hidden = state.inbox.length === 0;
badge.classList.toggle("is-warn", state.inbox.length >= bal.cards.inboxMax - 2);
}
return { update, clockHand: (p) => setDial(dial, p) };
}