feat: 安装页改为移动端卡片样式并支持深色模式
- 抽出 DOWNLOAD_PAGE_TEMPLATE,卡片布局 + 大按钮,适配 iPhone 安全区 - 通过 prefers-color-scheme 切换配色,主色沿用 #50a0ff - 展示构建版本/Bundle ID/分支,补充 Safari 打开与信任描述文件提示 - 动态字段统一 html.escape,修正 install_url 中裸 & 未转义的问题 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import plistlib
|
|||||||
import posixpath
|
import posixpath
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
from html import escape
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from urllib.parse import quote, unquote, urlparse
|
from urllib.parse import quote, unquote, urlparse
|
||||||
|
|
||||||
@@ -54,14 +55,139 @@ def _write_manifest(config: dict, manifest: Path, ipa_url: str):
|
|||||||
plistlib.dump(data, f)
|
plistlib.dump(data, f)
|
||||||
|
|
||||||
|
|
||||||
|
DOWNLOAD_PAGE_TEMPLATE = """<!doctype html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<title>{title} - 安装</title>
|
||||||
|
<style>
|
||||||
|
:root {{
|
||||||
|
--bg: #f2f3f7;
|
||||||
|
--card: #ffffff;
|
||||||
|
--text: #1c1c1e;
|
||||||
|
--muted: #8a8a8e;
|
||||||
|
--line: rgba(60, 60, 67, .12);
|
||||||
|
--brand: #50a0ff;
|
||||||
|
}}
|
||||||
|
@media (prefers-color-scheme: dark) {{
|
||||||
|
:root {{
|
||||||
|
--bg: #000000;
|
||||||
|
--card: #1c1c1e;
|
||||||
|
--text: #f5f5f7;
|
||||||
|
--muted: #98989d;
|
||||||
|
--line: rgba(255, 255, 255, .12);
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
* {{ box-sizing: border-box; }}
|
||||||
|
body {{
|
||||||
|
margin: 0;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 10vh 20px calc(32px + env(safe-area-inset-bottom));
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
background: var(--bg);
|
||||||
|
color: var(--text);
|
||||||
|
font: 16px/1.5 -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", Arial, sans-serif;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}}
|
||||||
|
.card {{
|
||||||
|
width: 100%;
|
||||||
|
max-width: 420px;
|
||||||
|
background: var(--card);
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 28px 24px 24px;
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, .08);
|
||||||
|
text-align: center;
|
||||||
|
}}
|
||||||
|
.name {{
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
word-break: break-word;
|
||||||
|
}}
|
||||||
|
.version {{
|
||||||
|
margin: 6px 0 22px;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 15px;
|
||||||
|
}}
|
||||||
|
.install {{
|
||||||
|
display: block;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: var(--brand);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
}}
|
||||||
|
.install:active {{ opacity: .75; }}
|
||||||
|
.meta {{
|
||||||
|
margin: 22px 0 0;
|
||||||
|
padding-top: 16px;
|
||||||
|
border-top: 1px solid var(--line);
|
||||||
|
text-align: left;
|
||||||
|
font-size: 14px;
|
||||||
|
}}
|
||||||
|
.meta div {{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 5px 0;
|
||||||
|
}}
|
||||||
|
.meta dt {{ color: var(--muted); flex: none; }}
|
||||||
|
.meta dd {{
|
||||||
|
margin: 0;
|
||||||
|
text-align: right;
|
||||||
|
word-break: break-all;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}}
|
||||||
|
.tips {{
|
||||||
|
margin: 18px 0 0;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.7;
|
||||||
|
text-align: left;
|
||||||
|
}}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="card">
|
||||||
|
<h1 class="name">{title}</h1>
|
||||||
|
<p class="version">版本 {version}</p>
|
||||||
|
<a class="install" href="{install_url}">安装 App</a>
|
||||||
|
<dl class="meta">{meta}</dl>
|
||||||
|
<p class="tips">请使用 iPhone 自带的 Safari 浏览器打开本页面安装。<br>
|
||||||
|
安装后如提示“未受信任的开发者”,请前往「设置 → 通用 → VPN 与设备管理」信任该描述文件。</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _write_download_page(config: dict, html: Path, manifest_url: str):
|
def _write_download_page(config: dict, html: Path, manifest_url: str):
|
||||||
install_url = f"itms-services://?action=download-manifest&url={quote(manifest_url, safe=':/?=&')}"
|
install_url = f"itms-services://?action=download-manifest&url={quote(manifest_url, safe=':/?=&')}"
|
||||||
title = config.get("APPID_NAME", "iOS App")
|
title = config.get("APPID_NAME") or "iOS App"
|
||||||
|
meta_items = [
|
||||||
|
("构建版本", config.get("BUILD_VERSION", "")),
|
||||||
|
("Bundle ID", config.get("BUNDLE_ID", "")),
|
||||||
|
("分支", config.get("SOURCE_BRANCH", "")),
|
||||||
|
]
|
||||||
|
meta = "".join(
|
||||||
|
f"<div><dt>{escape(label)}</dt><dd>{escape(str(value))}</dd></div>"
|
||||||
|
for label, value in meta_items
|
||||||
|
if value
|
||||||
|
)
|
||||||
html.write_text(
|
html.write_text(
|
||||||
"<!doctype html><html lang=\"zh-CN\"><meta charset=\"utf-8\">"
|
DOWNLOAD_PAGE_TEMPLATE.format(
|
||||||
f"<title>{title}</title><body><h2>{title}</h2>"
|
title=escape(title),
|
||||||
f"<p>版本 {config.get('VERSION', '')}</p><a href=\"{install_url}\">安装 App</a>"
|
version=escape(str(config.get("VERSION", ""))),
|
||||||
"</body></html>",
|
install_url=escape(install_url, quote=True),
|
||||||
|
meta=meta,
|
||||||
|
),
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user