Pin skills to the top of the sidebar

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-20 20:06:16 +01:00
parent fb237cb686
commit be478f3b2e
5 changed files with 55 additions and 4 deletions

View file

@ -308,6 +308,16 @@ function nav(id, icon, label, meta = "", extra = "", tip = "") {
return `<button class="nav ${page === id ? "on" : ""}" data-nav="${id}"${tip ? ` title="${esc(tip)}"` : ""}><span class="ic">${icon}</span><span class="label">${label}</span>${extra}<span class="meta">${meta}</span></button>`;
}
function skillNav(skill, me, doing) {
const busy = doing?.skill === skill.id ? `<span class="dot"></span>` : "";
return nav("skill:" + skill.id, skill.icon, skill.name, `${me.levels[skill.id]}`, busy);
}
function pinnedNav(me, doing) {
const pinned = C.skills.filter((s) => me.pinned.includes(s.id) && (!s.class || s.class === me.cls));
return pinned.length ? `<div class="navhead">📌 Pinned</div>${pinned.map((s) => skillNav(s, me, doing)).join("")}` : "";
}
function sidebar() {
const me = S.me, cls = C.classes[me.cls];
const doing = me.action && C.actions.find((a) => a.id === me.action.id);
@ -320,6 +330,7 @@ function sidebar() {
<div class="cls">${cls.icon} ${cls.name} · ${HEART} <span data-live-hp>${fmt(me.hp)}</span>/${me.max_hp}</div>
<div class="purse"><span class="gold" title="Gold">${COIN} ${fmt(me.gold)}</span><span class="favour" title="Favour: earned by donating">${FAVOUR} ${fmt(me.favour)}</span></div>
</div>
${pinnedNav(me, doing)}
<div class="navhead">City</div>
${nav("town", "🏘️", "Town square", `${S.city.population}`, "", `Population ${S.city.population}`)}
${nav("council", "📜", "Council & threats", "", raid ? `<span class="alert"></span>` : "", raid ? "A threat is coming" : "")}
@ -336,8 +347,7 @@ function sidebar() {
group = skill.group;
html += `<div class="navhead">${group}</div>`;
}
const busy = doing?.skill === skill.id ? `<span class="dot"></span>` : "";
html += nav("skill:" + skill.id, skill.icon, skill.name, `${me.levels[skill.id]}`, busy);
html += skillNav(skill, me, doing);
}
return html + (S.dev ? devbar() : "")
+ `<p class="credit">Icons by Lorc, Delapouite and others at <a href="https://game-icons.net" target="_blank" rel="noopener">game-icons.net</a>, CC BY 3.0</p>`;
@ -423,7 +433,7 @@ function skillPage(id) {
<div class="panel"><div class="skill-head">
<div class="big">${skill.icon}</div>
<div class="info">
<h2>${skill.name}</h2>
<h2>${skill.name} <button class="pin ${me.pinned.includes(id) ? "on" : ""}" data-pin="${id}" title="${me.pinned.includes(id) ? "Unpin" : "Pin"}">📌</button></h2>
<div class="lv">Level ${level} / 99 · ${fmt(xp)}${ceil ? ` / ${fmt(ceil)}` : ""} XP</div>
<div class="bar xp thick"><span style="width:${pct}%"></span></div>
</div>
@ -1677,6 +1687,7 @@ document.addEventListener("click", (e) => {
if ("plot" in d) return act("/api/plot", { id: d.plot || null });
if (d.garrison) return act("/api/garrison", { join: d.garrison === "1" });
if (d.perk) return act("/api/perk", { perk: d.perk });
if (d.pin) return act("/api/pin", { skill: d.pin });
if (d.favour) return act("/api/favour", { kind: d.favour });
if (d.food) return act("/api/food", { item: d.food === "cheapest" ? null : d.food });
if (d.potion) return act("/api/potion", { item: d.potion });