From b1d4bca90f8dd1e8123772254ec5953237b8b4f2 Mon Sep 17 00:00:00 2001 From: yetone Date: Tue, 29 Sep 2026 12:43:50 +0800 Subject: [PATCH] =?UTF-8?q?routing:=20picking=20Live=20or=20a=20day=20keep?= =?UTF-8?q?s=20the=20page=20where=20it=20is,=20and=20a=20list=20with=20no?= =?UTF-8?q?=20requests=20says=20what=20it=20is=20for=20(Image=20#59)=20?= =?UTF-8?q?=E2=80=94=20a=20day=20or=20Live=20picked=20in=20the=20requests'?= =?UTF-8?q?=20bar=20picked=20its=20first=20request=20as=20a=20click=20on?= =?UTF-8?q?=20a=20request=20does,=20which=20brings=20the=20stage=20at=20th?= =?UTF-8?q?e=20top=20into=20view,=20so=20every=20switch=20sent=20the=20rea?= =?UTF-8?q?der=20up=20to=20the=20top=20and=20back=20down;=20the=20stage=20?= =?UTF-8?q?now=20comes=20into=20view=20only=20for=20a=20request=20picked?= =?UTF-8?q?=20in=20the=20list.=20With=20no=20requests,=20the=20list=20is?= =?UTF-8?q?=20a=20quiet=20note=20(none=20since=20magpie=20started:=20each?= =?UTF-8?q?=20request=20an=20agent=20sends=20shows=20who=20answered=20it,?= =?UTF-8?q?=20why=20and=20each=20try;=20earlier=20ones=20are=20under=20the?= =?UTF-8?q?=20days)=20in=20place=20of=20an=20empty=20box,=20and=20the=20ac?= =?UTF-8?q?counts=20and=20keys=20column,=20tallying=20nothing,=20is=20left?= =?UTF-8?q?=20out.=20Checked=20in=20a=20stub=20magpie=20web=20with=20the?= =?UTF-8?q?=20day's=20history:=20scroll=20stays=20put=20over=20five=20swit?= =?UTF-8?q?ches=20(it=20moved=20before),=20dark?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/gui/assets/i18n.js | 4 ++++ internal/gui/assets/routing.css | 4 ++++ internal/gui/assets/routing.js | 26 ++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/internal/gui/assets/i18n.js b/internal/gui/assets/i18n.js index 4cedeccb..825b31ea 100644 --- a/internal/gui/assets/i18n.js +++ b/internal/gui/assets/i18n.js @@ -1037,6 +1037,10 @@ const I18N = { "the last {n} the gateway keeps": "网关保留的最近 {n} 个", "Accounts and keys": "账号与密钥", "over those requests": "统计自这些请求", + "Nothing on {day}": "{day}没有请求", + "No requests since magpie started": "magpie 启动以来还没有请求", + "Each request an agent sends through magpie shows up here: who answered it, why, and each try.": "agent 经 magpie 发出的每个请求都会列在这里:谁应答的、为什么选它,以及每一次尝试。", + "Earlier ones are kept by day, in the bar above.": "更早的请求按天保存,在上面的日期里查看。", "tried {n}": "尝试 {n}", "answered {n}": "应答 {n}", "last answered {time}": "最近应答 {time}", diff --git a/internal/gui/assets/routing.css b/internal/gui/assets/routing.css index 355c30d2..42ff4a9e 100644 --- a/internal/gui/assets/routing.css +++ b/internal/gui/assets/routing.css @@ -168,6 +168,10 @@ .rt-req .meta { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; } @container (max-width: 520px) { .rt-reqs { grid-template-columns: auto minmax(0, 1fr); } .rt-req { row-gap: 2px; } .rt-req .to { grid-column: 2; } .rt-req .meta { grid-column: 2; text-align: left; } } .rt-acts { padding: 4px 0; } +.rt-cols.solo { grid-template-columns: minmax(0, 1fr); } +.rt-reqs.none { display: block; background: none; border-color: transparent; } +.rt-reqs.none .empty-state { padding: 14px 12px 18px; font-size: 12px; line-height: 1.6; } +.rt-reqs.none .empty-state b { font-size: 13px; } .rt-prov { display: flex; align-items: center; gap: 7px; padding: 8px 12px 4px; font-size: 12px; } .rt-prov .ic, .rt-prov .ic img, .rt-prov .ic svg { width: 14px; height: 14px; } .rt-prov > span:last-child { margin-left: auto; font-size: 10.5px; color: var(--muted); border: 1px solid var(--line); border-radius: 999px; padding: 0 7px; } diff --git a/internal/gui/assets/routing.js b/internal/gui/assets/routing.js index 5eb5d04e..8561365b 100644 --- a/internal/gui/assets/routing.js +++ b/internal/gui/assets/routing.js @@ -884,15 +884,17 @@ steps.replaceChildren(...items.map(([s, c]) => el("li", c, s))); } - // pick sets the stage to a past request, or back to live with the newest - function pick(r) { + // pick sets the stage to a past request, or back to live with the newest; + // the page goes up to the stage only when the reader picked a request in + // the list (look), never on a day or Live picked in the list's own bar + function pick(r, look = true) { pinned = r.id === newest()?.id ? null : r; if (rp) { rp = null; rbar.hidden = true; } stopPlays(); cur = r; sync(true); renderAll(); say(affWhy(r, true) || ruleWhy(r, true) || firstWhy(r)); - if (pinned) { scrollOnPurpose(); box.scrollIntoView({ block: "nearest", behavior: still() ? "auto" : "smooth" }); } + if (pinned && look) { scrollOnPurpose(); box.scrollIntoView({ block: "nearest", behavior: still() ? "auto" : "smooth" }); } } // who answered a request, or what its agent got @@ -931,7 +933,7 @@ if (d) await loadDays(d); pinned = null; const r = d ? listed()[0] : newest(); - if (r && d) pick(r); + if (r && d) pick(r, false); else if (r) { stopPlays(); cur = r; sync(true); say(affWhy(r, true) || ruleWhy(r, true) || firstWhy(r)); } renderAll(); } @@ -961,6 +963,22 @@ reqNote.textContent = day ? t(pastCut ? "the last {n} of {day}" : "{n} on {day}", { n: rs.length, day: dayName(day) }) : t("the last {n} the gateway keeps", { n: rs.length }); renderDays(); + // none yet: what the list is for in its place, and no accounts column + // to tally nothing + const none = !rs.length; + reqNote.hidden = none; + reqs.classList.toggle("none", none); + colB.hidden = none; + hist.classList.toggle("solo", none); + if (none) { + const p = el("div", "empty-state"); + p.append(el("b", "", day ? t("Nothing on {day}", { day: dayName(day) }) : t("No requests since magpie started")), + t("Each request an agent sends through magpie shows up here: who answered it, why, and each try.")); + if (!day && days.length) p.append(" " + t("Earlier ones are kept by day, in the bar above.")); + reqs.replaceChildren(p); + renderActs(rs); + return; + } reqs.replaceChildren(...rs.map((r) => { const [said, how, tr] = outcome(r); const b = el("button", "rt-req " + how);