稳定测试版
This commit is contained in:
274
waiting.html
Normal file
274
waiting.html
Normal file
@@ -0,0 +1,274 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' data:;">
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: dark light;
|
||||
--bg: #0b1220;
|
||||
--card: #111827;
|
||||
--fg: #e6eaf2;
|
||||
--muted: #9ca3af;
|
||||
--accent1: #60a5fa;
|
||||
--accent2: #34d399;
|
||||
--error: #fca5a5;
|
||||
--ok: #86efac;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial;
|
||||
background: radial-gradient(1200px 600px at 10% 0%, rgba(96, 165, 250, .2), transparent 70%),
|
||||
radial-gradient(1200px 600px at 100% 120%, rgba(52, 211, 153, .15), transparent 70%),
|
||||
var(--bg);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
.card {
|
||||
width: min(540px, 92vw);
|
||||
background: var(--card);
|
||||
border-radius: 18px;
|
||||
padding: 32px 26px;
|
||||
box-shadow: 0 20px 48px rgba(0, 0, 0, .35);
|
||||
text-align: center;
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
margin: 0 auto 18px;
|
||||
border: 4px solid rgba(255, 255, 255, .15);
|
||||
border-top-color: var(--accent1);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg)
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 6px 0 10px;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
background: linear-gradient(90deg, var(--accent1), var(--accent2));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 10px;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.muted {
|
||||
opacity: .75;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tips {
|
||||
margin-top: 16px;
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
opacity: .9;
|
||||
background: #0f172a;
|
||||
border-radius: 12px;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid rgba(255, 255, 255, .08);
|
||||
}
|
||||
|
||||
code {
|
||||
background: #0b1220;
|
||||
padding: 1px 6px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 18px;
|
||||
margin: 6px 0 0;
|
||||
}
|
||||
|
||||
/* 更新视图样式 */
|
||||
.progress {
|
||||
margin: 18px auto 10px;
|
||||
width: 100%;
|
||||
max-width: 440px;
|
||||
height: 12px;
|
||||
background: #0b1220;
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
|
||||
}
|
||||
|
||||
.progress__bar {
|
||||
height: 100%;
|
||||
width: 0%;
|
||||
background: linear-gradient(90deg, var(--accent1), var(--accent2));
|
||||
transition: width .15s ease;
|
||||
}
|
||||
|
||||
.row {
|
||||
opacity: .9;
|
||||
font-size: 14px;
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
appearance: none;
|
||||
border: 0;
|
||||
padding: 9px 16px;
|
||||
border-radius: 10px;
|
||||
background: var(--accent1);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.btn[disabled] {
|
||||
opacity: .6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.warn {
|
||||
color: var(--error);
|
||||
font-size: 13px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.ok {
|
||||
color: var(--ok);
|
||||
font-size: 13px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="card">
|
||||
<!-- 等待视图 -->
|
||||
<div id="wait-view">
|
||||
<div class="spinner"></div>
|
||||
<h2>正在检查更新…</h2>
|
||||
<p class="muted">系统会自动检测可用的新版本</p>
|
||||
<div class="tips">
|
||||
<strong>如果长时间停留在此页面,可尝试:</strong>
|
||||
<ul>
|
||||
<li>检查网络是否可用</li>
|
||||
<li>确认杀软/防火墙没有拦截本应用</li>
|
||||
<li>重启应用后再试</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 更新视图 -->
|
||||
<div id="update-view" hidden>
|
||||
<h2 id="upd-title">检测到新版本,正在下载…</h2>
|
||||
<div class="progress" aria-label="下载进度">
|
||||
<div id="upd-bar" class="progress__bar"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div id="upd-percent">0.00%</div>
|
||||
<div id="upd-meta"><small>—</small></div>
|
||||
</div>
|
||||
<div id="upd-msg" class="ok" hidden>下载完成,准备安装</div>
|
||||
<div id="upd-err" class="warn" hidden></div>
|
||||
<div class="actions">
|
||||
<button id="btn-install" class="btn" hidden>立即重启安装</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function bindUpdaterUI() {
|
||||
const bridge = window.appUpdater;
|
||||
if (!bridge) return;
|
||||
|
||||
const $ = (id) => document.getElementById(id);
|
||||
const waitView = $('wait-view');
|
||||
const updView = $('update-view');
|
||||
const updBar = $('upd-bar');
|
||||
const updPercent = $('upd-percent');
|
||||
const updMeta = $('upd-meta');
|
||||
const updTitle = $('upd-title');
|
||||
const updMsg = $('upd-msg');
|
||||
const updErr = $('upd-err');
|
||||
const btnInstall = $('btn-install');
|
||||
|
||||
const fmtMB = b => (b / 1024 / 1024).toFixed(1) + ' MB';
|
||||
const fmtSpeed = bps => (bps / 1024).toFixed(0) + ' KB/s';
|
||||
|
||||
const showUpdateView = (titleText) => {
|
||||
if (titleText) updTitle.textContent = titleText;
|
||||
waitView.hidden = true;
|
||||
updView.hidden = false;
|
||||
};
|
||||
|
||||
bridge.onAvailable((info) => {
|
||||
const ver = info?.version || '';
|
||||
showUpdateView(ver ? `检测到新版本 v${ver},正在下载…` : '检测到新版本,正在下载…');
|
||||
});
|
||||
|
||||
bridge.onProgress((p) => {
|
||||
if (updView.hidden) showUpdateView('正在下载更新…');
|
||||
const percent = Math.max(0, Math.min(100, p?.percent || 0));
|
||||
updBar.style.width = percent.toFixed(2) + '%';
|
||||
updPercent.textContent = percent.toFixed(2) + '%';
|
||||
const transferred = typeof p?.transferred === 'number' ? fmtMB(p.transferred) : '-';
|
||||
const total = typeof p?.total === 'number' ? fmtMB(p.total) : '-';
|
||||
const speed = typeof p?.bytesPerSecond === 'number' ? fmtSpeed(p.bytesPerSecond) : '-';
|
||||
updMeta.innerHTML = `<small>${transferred} / ${total} · ${speed}</small>`;
|
||||
updMsg.hidden = true;
|
||||
updErr.hidden = true;
|
||||
});
|
||||
|
||||
bridge.onDownloaded(() => {
|
||||
updTitle.textContent = '更新下载完成';
|
||||
updBar.style.width = '100%';
|
||||
updPercent.textContent = '100%';
|
||||
updMsg.hidden = false;
|
||||
btnInstall.hidden = false;
|
||||
});
|
||||
|
||||
bridge.onError((err) => {
|
||||
updTitle.textContent = '更新出错';
|
||||
updErr.hidden = false;
|
||||
updErr.textContent = (err && (err.message || err)) || '发生未知错误';
|
||||
btnInstall.hidden = true;
|
||||
});
|
||||
|
||||
btnInstall.addEventListener('click', () => {
|
||||
btnInstall.disabled = true;
|
||||
try { bridge.quitAndInstallNow?.(); } catch (e) { }
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user