fix(ui): 自动刷新时静默更新卡片,不再重播进入动画导致闪烁 - renderAccounts/renderPlatforms 增加 animate 参数 - refresh 自动轮询传 false(无动画),首次渲染与用户操作保留 stagger 动画
This commit is contained in:
+12
-8
@@ -13,6 +13,7 @@
|
|||||||
let filterPlatform = 0;
|
let filterPlatform = 0;
|
||||||
const checkingIds = new Set();
|
const checkingIds = new Set();
|
||||||
let historyCache = {};
|
let historyCache = {};
|
||||||
|
let hasRendered = false; // 首次渲染保留进入动画,自动刷新静默更新
|
||||||
const accountWindows = {}; // {accountId: 'all'|'1h'|'1d'|'1w'|'1mo'|'1yr'}
|
const accountWindows = {}; // {accountId: 'all'|'1h'|'1d'|'1w'|'1mo'|'1yr'}
|
||||||
const windowCache = {}; // {'aid:win': [...]}
|
const windowCache = {}; // {'aid:win': [...]}
|
||||||
|
|
||||||
@@ -149,8 +150,9 @@
|
|||||||
platforms = plat;
|
platforms = plat;
|
||||||
historyCache = hist || {};
|
historyCache = hist || {};
|
||||||
providersList = provs || [];
|
providersList = provs || [];
|
||||||
renderAccounts();
|
renderAccounts(!hasRendered);
|
||||||
if (!document.getElementById("view-platforms").classList.contains("hidden")) renderPlatforms();
|
if (!document.getElementById("view-platforms").classList.contains("hidden")) renderPlatforms(!hasRendered);
|
||||||
|
hasRendered = true;
|
||||||
const d = new Date();
|
const d = new Date();
|
||||||
document.getElementById("refresh-time").textContent =
|
document.getElementById("refresh-time").textContent =
|
||||||
d.toLocaleTimeString("zh-CN", { hour12: false });
|
d.toLocaleTimeString("zh-CN", { hour12: false });
|
||||||
@@ -174,7 +176,7 @@
|
|||||||
return { cls: "pending", text: "待检查" };
|
return { cls: "pending", text: "待检查" };
|
||||||
}
|
}
|
||||||
|
|
||||||
function accountCard(a, idx) {
|
function accountCard(a, idx, animate = true) {
|
||||||
const st = statusInfo(a);
|
const st = statusInfo(a);
|
||||||
const plat = platforms.find((p) => p.id === a.platform_id) || {};
|
const plat = platforms.find((p) => p.id === a.platform_id) || {};
|
||||||
const b = brandStyle(plat.icon || "");
|
const b = brandStyle(plat.icon || "");
|
||||||
@@ -188,6 +190,7 @@
|
|||||||
st.cls === "disabled" ? "disabled" : "",
|
st.cls === "disabled" ? "disabled" : "",
|
||||||
st.cls === "pending" ? "pending" : "",
|
st.cls === "pending" ? "pending" : "",
|
||||||
].join(" ").trim();
|
].join(" ").trim();
|
||||||
|
const animStyle = animate ? `animation-delay:${Math.min(idx, 12) * 40}ms` : "animation:none";
|
||||||
const win = accountWindows[a.id] || "all";
|
const win = accountWindows[a.id] || "all";
|
||||||
let hist;
|
let hist;
|
||||||
if (win === "all") {
|
if (win === "all") {
|
||||||
@@ -203,7 +206,7 @@
|
|||||||
? `<button class="btn sm check-btn loading" disabled><span class="spinner"></span>检查中</button>`
|
? `<button class="btn sm check-btn loading" disabled><span class="spinner"></span>检查中</button>`
|
||||||
: `<button class="btn sm check-btn" data-act="check" data-id="${a.id}" ${!a.enabled ? "disabled title=启用后可用" : ""}>${ICONS.refresh}立即检查</button>`;
|
: `<button class="btn sm check-btn" data-act="check" data-id="${a.id}" ${!a.enabled ? "disabled title=启用后可用" : ""}>${ICONS.refresh}立即检查</button>`;
|
||||||
return `
|
return `
|
||||||
<div class="${cardCls}" style="animation-delay:${Math.min(idx, 12) * 40}ms">
|
<div class="${cardCls}" style="${animStyle}">
|
||||||
<div class="card-head">
|
<div class="card-head">
|
||||||
<div class="badge" style="background:${b.color}">${escapeHtml(b.abbr)}</div>
|
<div class="badge" style="background:${b.color}">${escapeHtml(b.abbr)}</div>
|
||||||
<div class="card-title">
|
<div class="card-title">
|
||||||
@@ -290,7 +293,7 @@
|
|||||||
return `<svg class="sparkline" viewBox="0 0 ${W} ${H}" preserveAspectRatio="none">${thLine}<polyline points="${pts.join(" ")}" fill="none" stroke="${lineColor}" stroke-width="1.5" stroke-linejoin="round" stroke-linecap="round" vector-effect="non-scaling-stroke"/></svg>`;
|
return `<svg class="sparkline" viewBox="0 0 ${W} ${H}" preserveAspectRatio="none">${thLine}<polyline points="${pts.join(" ")}" fill="none" stroke="${lineColor}" stroke-width="1.5" stroke-linejoin="round" stroke-linecap="round" vector-effect="non-scaling-stroke"/></svg>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderAccounts() {
|
function renderAccounts(animate = true) {
|
||||||
const grid = document.getElementById("account-grid");
|
const grid = document.getElementById("account-grid");
|
||||||
const stats = { total: accounts.length, ok: 0, below: 0, error: 0, disabled: 0, pending: 0 };
|
const stats = { total: accounts.length, ok: 0, below: 0, error: 0, disabled: 0, pending: 0 };
|
||||||
accounts.forEach((a) => {
|
accounts.forEach((a) => {
|
||||||
@@ -326,7 +329,7 @@
|
|||||||
});
|
});
|
||||||
list = [...list].sort((x, y) => STATUS_ORDER[statusInfo(x).cls] - STATUS_ORDER[statusInfo(y).cls]);
|
list = [...list].sort((x, y) => STATUS_ORDER[statusInfo(x).cls] - STATUS_ORDER[statusInfo(y).cls]);
|
||||||
|
|
||||||
grid.innerHTML = list.map(accountCard).join("");
|
grid.innerHTML = list.map((a, i) => accountCard(a, i, animate)).join("");
|
||||||
const hint = document.getElementById("empty-hint");
|
const hint = document.getElementById("empty-hint");
|
||||||
if (accounts.length > 0) {
|
if (accounts.length > 0) {
|
||||||
hint.classList.add("hidden");
|
hint.classList.add("hidden");
|
||||||
@@ -343,7 +346,7 @@
|
|||||||
|
|
||||||
/* ---------- 渲染:平台 ---------- */
|
/* ---------- 渲染:平台 ---------- */
|
||||||
|
|
||||||
function renderPlatforms() {
|
function renderPlatforms(animate = true) {
|
||||||
const list = document.getElementById("platform-list");
|
const list = document.getElementById("platform-list");
|
||||||
if (platforms.length === 0) {
|
if (platforms.length === 0) {
|
||||||
list.innerHTML = `<div class="empty-hint">暂无平台(代码内置平台会在启动时自动同步)。</div>`;
|
list.innerHTML = `<div class="empty-hint">暂无平台(代码内置平台会在启动时自动同步)。</div>`;
|
||||||
@@ -352,8 +355,9 @@
|
|||||||
list.innerHTML = platforms.map((p, i) => {
|
list.innerHTML = platforms.map((p, i) => {
|
||||||
const b = brandStyle(p.icon || "");
|
const b = brandStyle(p.icon || "");
|
||||||
const prov = providersList.find((x) => x.id === p.provider_id);
|
const prov = providersList.find((x) => x.id === p.provider_id);
|
||||||
|
const animStyle = animate ? `animation-delay:${Math.min(i, 10) * 35}ms` : "animation:none";
|
||||||
return `
|
return `
|
||||||
<div class="platform-row ${p.enabled ? "" : "platform-off"}" style="animation-delay:${Math.min(i, 10) * 35}ms">
|
<div class="platform-row ${p.enabled ? "" : "platform-off"}" style="${animStyle}">
|
||||||
<div class="badge" style="background:${b.color}">${escapeHtml(b.abbr)}</div>
|
<div class="badge" style="background:${b.color}">${escapeHtml(b.abbr)}</div>
|
||||||
<div class="platform-info">
|
<div class="platform-info">
|
||||||
<div class="platform-name">${escapeHtml(p.name)}
|
<div class="platform-name">${escapeHtml(p.name)}
|
||||||
|
|||||||
Reference in New Issue
Block a user