v0.5.84: matches origin filter, mobile gate, refresh reliability.

Ship Web refresh cache/lock, mobile demand gate, matches 职业/国服 filter, and related site updates through 0.5.84.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
voson
2026-07-29 18:31:55 +08:00
co-authored by Cursor
parent 7681fdb069
commit b01552ee6e
50 changed files with 3406 additions and 487 deletions
+98
View File
@@ -0,0 +1,98 @@
/**
* Early mobile client gate (loaded from <head>).
* Sets html.mobile-client before paint; wires the demand button after DOM ready.
* Exposes window.__CLIMPEROR_MOBILE__ for app.js to skip the desktop boot path.
*/
(function () {
function isMobileClient() {
var ua = navigator.userAgent || "";
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua)) {
return true;
}
// iPadOS 13+ reports as MacIntel with touch.
if (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1) {
return true;
}
return false;
}
var mobile = isMobileClient();
window.__CLIMPEROR_MOBILE__ = mobile;
if (!mobile) return;
document.documentElement.classList.add("mobile-client");
var STORAGE_KEY = "climperor_mobile_demand_voted";
function $(id) {
return document.getElementById(id);
}
function markVoted(btn) {
try {
localStorage.setItem(STORAGE_KEY, "1");
} catch (_) {
/* ignore quota / private mode */
}
if (btn) {
btn.disabled = true;
btn.textContent = "已记录催更";
}
}
function alreadyVoted() {
try {
return localStorage.getItem(STORAGE_KEY) === "1";
} catch (_) {
return false;
}
}
function setCount(n) {
var el = $("mobile-demand-count-n");
if (el) el.textContent = String(n);
var wrap = $("mobile-demand-count");
if (wrap) wrap.hidden = false;
}
async function refreshCount() {
try {
var res = await fetch("/api/mobile-demand");
if (!res.ok) return;
var data = await res.json();
var n = Number(data && data.count);
if (Number.isFinite(n) && n >= 0) setCount(Math.floor(n));
} catch (_) {
/* soft-fail: keep count hidden */
}
}
document.addEventListener("DOMContentLoaded", function () {
var logo = document.querySelector(".mobile-gate-logo");
if (logo && typeof STATIC_ASSET_BASE === "string") {
var base = STATIC_ASSET_BASE.trim().replace(/\/+$/, "");
if (base) logo.src = base + "/ui-icon/dota2_logo_wordmark.png";
}
var btn = $("mobile-demand-btn");
var voted = alreadyVoted();
if (voted) markVoted(btn);
refreshCount();
if (!btn || voted) return;
btn.addEventListener("click", async function () {
btn.disabled = true;
try {
var res = await fetch("/api/mobile-demand", { method: "POST" });
if (!res.ok) {
btn.disabled = false;
return;
}
var data = await res.json();
var n = Number(data && data.count);
if (Number.isFinite(n) && n >= 0) setCount(Math.floor(n));
markVoted(btn);
} catch (_) {
btn.disabled = false;
}
});
});
})();