Files
tkNewPageElectron/index.html
2025-10-10 19:41:11 +08:00

268 lines
8.1 KiB
HTML

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>YOLO 更新检查</title>
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; style-src 'unsafe-inline' 'self'; script-src 'self' 'unsafe-inline'; img-src 'self' data:;">
<meta name="color-scheme" content="light dark">
<style>
:root {
--bg: #0b1220;
--card: #0f172a;
--text: #e5e7eb;
--muted: #9ca3af;
--accent: #60a5fa;
--accent-2: #34d399;
--bar-bg: #1f2937;
--bar-fg: linear-gradient(90deg, var(--accent), var(--accent-2));
--ok: #34d399;
--error: #ef4444;
}
@media (prefers-color-scheme: light) {
:root {
--bg: #f8fafc;
--card: #ffffff;
--text: #0f172a;
--muted: #64748b;
--bar-bg: #e5e7eb;
}
}
* {
box-sizing: border-box;
}
html,
body {
height: 100%;
}
body {
margin: 0;
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial;
background: radial-gradient(1200px 600px at 20% -10%, rgba(96, 165, 250, .25), transparent 50%),
radial-gradient(1200px 600px at 120% 120%, rgba(52, 211, 153, .25), transparent 50%),
var(--bg);
color: var(--text);
display: grid;
place-items: center;
}
.card {
width: 560px;
max-width: calc(100% - 40px);
background: linear-gradient(180deg, rgba(255, 255, 255, .04), rgba(255, 255, 255, 0)), var(--card);
border: 1px solid rgba(255, 255, 255, .08);
border-radius: 20px;
padding: 28px;
box-shadow: 0 10px 40px rgba(0, 0, 0, .25);
backdrop-filter: blur(6px);
}
.header {
display: flex;
align-items: center;
gap: 14px;
margin-bottom: 12px;
}
.logo {
width: 36px;
height: 36px;
border-radius: 10px;
background: linear-gradient(135deg, var(--accent), var(--accent-2));
display: grid;
place-items: center;
color: white;
font-weight: 900;
text-shadow: 0 1px 2px rgba(0, 0, 0, .3);
}
h1 {
font-size: 18px;
margin: 0;
}
.sub {
color: var(--muted);
font-size: 13px;
margin-top: 2px;
}
.status {
margin: 20px 0 16px;
padding: 12px 14px;
background: rgba(255, 255, 255, .04);
border: 1px dashed rgba(255, 255, 255, .18);
border-radius: 12px;
font-size: 14px;
}
.progress-wrap {
background: var(--bar-bg);
border-radius: 999px;
overflow: hidden;
height: 14px;
width: 100%;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .25);
}
.progress-bar {
height: 100%;
width: 0%;
background: var(--bar-fg);
transition: width .25s ease;
}
.row {
display: flex;
justify-content: space-between;
gap: 14px;
margin-top: 10px;
font-size: 12px;
color: var(--muted);
}
.actions {
margin-top: 18px;
display: flex;
gap: 10px;
}
button {
appearance: none;
border: 0;
border-radius: 12px;
padding: 10px 14px;
cursor: pointer;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
color: white;
font-weight: 600;
font-size: 14px;
box-shadow: 0 6px 18px rgba(56, 189, 248, .35);
}
button.ghost {
background: transparent;
border: 1px solid rgba(255, 255, 255, .18);
color: var(--text);
}
.ok {
color: var(--ok);
}
.err {
color: var(--error);
}
.fade {
animation: fade .3s ease both;
}
@keyframes fade {
from {
opacity: .0;
transform: translateY(6px)
}
to {
opacity: 1;
transform: none
}
}
</style>
</head>
<body>
<div class="card fade">
<div class="header">
<div class="logo">PY</div>
<div>
<h1>YOLO 启动 / 更新检查</h1>
<div class="sub">为你自动检查可用更新并在后台下载</div>
</div>
</div>
<div id="status" class="status">正在初始化…</div>
<div class="progress-wrap" aria-label="下载进度">
<div id="bar" class="progress-bar"></div>
</div>
<div class="row">
<div>速度:<span id="speed">0</span> MB/s</div>
<div>已下:<span id="transferred">0</span>/<span id="total">0</span> MB</div>
<div>进度:<span id="percent">0</span>%</div>
</div>
<div class="actions">
<button id="btn-install" style="display:none;">立即重启安装</button>
<button id="btn-hide" class="ghost">最小化到托盘</button>
</div>
</div>
<script>
const $ = (id) => document.getElementById(id);
const statusEl = $('status');
const bar = $('bar');
const sp = $('speed'), tf = $('transferred'), tt = $('total'), pc = $('percent');
const btnInstall = $('btn-install');
const btnHide = $('btn-hide');
// 订阅主进程事件
window.electronAPI.onUpdateStatus(({ status, version, notes, currentVersion, message }) => {
switch (status) {
case 'checking':
statusEl.textContent = '正在检查更新…';
break;
case 'available':
statusEl.innerHTML = `检测到新版本 <b>v${version}</b>,正在下载…`;
break;
case 'none':
statusEl.innerHTML = `已是最新版本 <span class="ok">(v${currentVersion})</span>。3 秒后自动最小化。`;
bar.style.width = '100%'; pc.textContent = '100';
setTimeout(() => window.close(), 3000);
break;
case 'downloaded':
statusEl.innerHTML = `下载完成!可立即安装更新 <b>v${version}</b>。`;
bar.style.width = '100%'; pc.textContent = '100';
btnInstall.style.display = '';
// 也可自动倒计时安装:
// setTimeout(() => btnInstall.click(), 3000);
break;
case 'error':
statusEl.innerHTML = `更新失败:<span class="err">${message || '未知错误'}</span>`;
break;
default:
statusEl.textContent = '状态:' + status;
}
});
window.electronAPI.onUpdateProgress(({ percent, transferred, total, speed }) => {
bar.style.width = Math.max(0, Math.min(100, percent || 0)) + '%';
sp.textContent = speed ?? 0;
tf.textContent = transferred ?? 0;
tt.textContent = total ?? 0;
pc.textContent = (percent ?? 0).toFixed(1);
});
// 交互
btnInstall.addEventListener('click', () => {
statusEl.textContent = '即将重启并安装更新…';
window.electronAPI.installNow();
});
btnHide.addEventListener('click', () => {
window.close(); // 在 main.js 里拦截 close -> hide()
});
// 首次加载立即请求检查
window.electronAPI.checkForUpdates();
</script>
</body>
</html>