fix: 网页播种/重置在嵌入预览里没反应——弃用 window.prompt/confirm

播种按钮原来弹 window.prompt 选作物,重置弹 confirm——这俩在
sandbox iframe(内置预览面板)里会被静默屏蔽:不弹窗、直接返回
null,表现为"点了没反应"。普通浏览器没事,所以一直没暴露。

改成页面内交互:播种弹 #pickmask 弹层,列出未锁定作物的按钮 +
取消,点遮罩关闭;重置改两步确认,第一次点变"再点一次确认",
3 秒不点自动还原。
This commit is contained in:
snowy-yang committed 2026-09-23 20:54:11 +08:00
1 parent cb292f9f53
commit 305ef0dcbe
1 file changed
+51 -11
+51 -11
View File
@@ -82,6 +82,15 @@ DASHBOARD_HTML = r"""<!DOCTYPE html>
.k-good { color: var(--green); } .k-bad { color: var(--red); } .k-good { color: var(--green); } .k-bad { color: var(--red); }
.k-warn { color: var(--gold); } .k-action { color: var(--cyan); } .k-warn { color: var(--gold); } .k-action { color: var(--cyan); }
.notice { font-size: 12px; color: var(--dim); min-height: 18px; } .notice { font-size: 12px; color: var(--dim); min-height: 18px; }
/* 播种选作物 / 二次确认的页面内弹层(不依赖 window.prompt,嵌入预览里也能用) */
.mask { position: fixed; inset: 0; background: rgba(30,40,30,.35);
display: none; align-items: center; justify-content: center; z-index: 30; }
.mask.show { display: flex; }
.pick { background: var(--card); border: 1px solid var(--line); border-radius: 12px;
padding: 14px 16px; min-width: 230px; box-shadow: 0 10px 30px rgba(0,0,0,.18); }
.pick h3 { margin: 0 0 10px; font-size: 14px; }
.pick .row { display: flex; flex-wrap: wrap; gap: 8px; }
.pick button.danger { border-color: var(--red); color: var(--red); }
.toast { .toast {
position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
background: #23301f; color: #fff; padding: 9px 18px; border-radius: 20px; background: #23301f; color: #fff; padding: 9px 18px; border-radius: 20px;
@@ -167,6 +176,13 @@ DASHBOARD_HTML = r"""<!DOCTYPE html>
<div class="toast" id="toast"></div> <div class="toast" id="toast"></div>
<div class="mask" id="pickmask">
<div class="pick">
<h3 id="picktitle">要种什么?</h3>
<div class="row" id="pickcrops"></div>
</div>
</div>
<script> <script>
const $ = (id) => document.getElementById(id); const $ = (id) => document.getElementById(id);
let es = null, state = null, catalog = null, pollTimer = null; let es = null, state = null, catalog = null, pollTimer = null;
@@ -421,17 +437,12 @@ document.addEventListener("click", (ev) => {
if (t.tagName !== "BUTTON") return; if (t.tagName !== "BUTTON") return;
if (t.dataset.w) act("water", { plot: +t.dataset.w }); if (t.dataset.w) act("water", { plot: +t.dataset.w });
else if (t.dataset.h) act("harvest", { plot: +t.dataset.h }); else if (t.dataset.h) act("harvest", { plot: +t.dataset.h });
else if (t.dataset.plant !== undefined) {
$("pickmask").classList.remove("show");
if (t.dataset.plant && pickPlot) act("plant", { plot: pickPlot, crop: t.dataset.plant });
}
else if (t.dataset.p) { else if (t.dataset.p) {
const plot = +t.dataset.p; openCropPick(+t.dataset.p);
const pool = state ? Object.keys(cropNames).filter((k) => {
const c = (catalog || { crops: [] }).crops.find((x) => x.key === k);
return !c || !c.locked;
}) : [];
const pick = window.prompt("要种什么?输入编号:\n" +
pool.map((k, i) => (i + 1) + ". " + cropNames[k]).join("\n"), "1");
const idx = parseInt(pick, 10);
if (!idx || idx < 1 || idx > pool.length) return;
act("plant", { plot: plot, crop: pool[idx - 1] });
} }
else if (t.dataset.f) act("feed", { animal_id: +t.dataset.f }); else if (t.dataset.f) act("feed", { animal_id: +t.dataset.f });
else if (t.dataset.c) act("collect", { animal_id: +t.dataset.c }); else if (t.dataset.c) act("collect", { animal_id: +t.dataset.c });
@@ -439,10 +450,39 @@ document.addEventListener("click", (ev) => {
else if (t.dataset.b) act("build", { key: t.dataset.b }); else if (t.dataset.b) act("build", { key: t.dataset.b });
else if (t.dataset.act === "buy_animal") act("buy_animal", { kind: $("buyanimal").value }); else if (t.dataset.act === "buy_animal") act("buy_animal", { kind: $("buyanimal").value });
else if (t.dataset.act === "buy_feed") act("buy_feed", { quantity: 10 }); else if (t.dataset.act === "buy_feed") act("buy_feed", { quantity: 10 });
else if (t.dataset.act === "reset") { if (confirm("确定重置牧场?所有进度都会清空")) act("reset"); } else if (t.dataset.act === "reset") {
if (t.dataset.armed) {
t.dataset.armed = ""; t.textContent = "重置";
act("reset");
} else {
t.dataset.armed = "1"; t.textContent = "再点一次确认";
setTimeout(() => { t.dataset.armed = ""; t.textContent = "重置"; }, 3000);
}
}
else if (t.dataset.act) act(t.dataset.act); else if (t.dataset.act) act(t.dataset.act);
}); });
/* 播种选作物:页面内弹层。window.prompt 在 sandbox iframe(内置预览面板)里
会被静默屏蔽——不弹窗、直接返回 null,表现为"点播种没反应"。 */
let pickPlot = 0;
function openCropPick(plot) {
if (!state) { toast("还没连接上服务器"); return; }
const pool = Object.keys(cropNames).filter((k) => {
const c = (catalog || { crops: [] }).crops.find((x) => x.key === k);
return !c || !c.locked;
});
if (!pool.length) { toast("还没有可种的作物"); return; }
pickPlot = plot;
$("picktitle").textContent = plot + " 号地 · 要种什么?";
$("pickcrops").innerHTML = pool.map((k) =>
'<button data-plant="' + k + '">' + cropNames[k] + "</button>").join("") +
'<button class="danger" data-plant="">取消</button>';
$("pickmask").classList.add("show");
}
$("pickmask").addEventListener("click", (ev) => {
if (ev.target.id === "pickmask") $("pickmask").classList.remove("show");
});
$("join").addEventListener("click", () => { $("join").addEventListener("click", () => {
localStorage.setItem("sf.farm", farmName()); localStorage.setItem("sf.farm", farmName());
localStorage.setItem("sf.token", token()); localStorage.setItem("sf.token", token());