feat(docs): add Windows offline download options

This commit is contained in:
t8y2
2026-08-12 15:42:06 +08:00
parent 5737bb497f
commit 26dd569afc
4 changed files with 137 additions and 32 deletions
+14 -1
View File
@@ -651,7 +651,7 @@ a {
/* Install dropdown */
.landing-install::after {
.landing-install-control::after {
content: "";
position: absolute;
top: 100%;
@@ -1119,6 +1119,19 @@ a {
}
@media (max-width: 760px) {
.landing-install-menu {
position: static;
display: none;
width: min(380px, calc(100vw - 32px));
margin-top: 12px;
translate: none;
transform: none;
}
.landing-install[data-open="true"] .landing-install-menu {
display: grid;
}
.landing-nav-inner {
padding-right: max(14px, env(safe-area-inset-right));
padding-left: max(14px, env(safe-area-inset-left));
+55 -30
View File
@@ -10,6 +10,10 @@ type InstallTabsProps = {
};
const downloadLabel = { en: "Download DBX", cn: "下载 DBX" };
const offlineHint = {
en: "Offline network or Windows 7? Choose an offline installer",
cn: "无法联网或使用 Windows 7?选择专用离线安装包",
};
const platformIconPaths = {
dark: {
@@ -63,7 +67,10 @@ export function InstallTabs({ lang, version }: InstallTabsProps) {
}, [open]);
const primary = useMemo(() => options.find((o) => o.id === platformId) ?? options[0], [options, platformId]);
const menuOptions = useMemo(() => options.filter((o) => o.id !== platformId), [options, platformId]);
const menuOptions = useMemo(
() => options.filter((option) => option.id !== primary.id).sort((a, b) => Number(b.iconId === primary.iconId) - Number(a.iconId === primary.iconId)),
[options, primary],
);
return (
<div
@@ -75,40 +82,58 @@ export function InstallTabs({ lang, version }: InstallTabsProps) {
}
}}
>
<div className="landing-install-trigger grid grid-cols-[minmax(0,1fr)_52px] items-stretch w-[min(340px,calc(100vw-36px))] min-h-[68px] border-0 rounded-full mx-auto overflow-hidden">
<a className="landing-install-primary grid grid-cols-[auto_minmax(0,1fr)] gap-4 items-center min-w-0 px-6 max-[360px]:gap-3 max-[360px]:px-5" href={primary.href}>
<PlatformIcon id={primary.id} size={30} variant="dark" />
<span className="grid gap-0.5 min-w-0 text-left">
<strong className="overflow-hidden text-[15px] font-[780] leading-[1.2] truncate">{downloadLabel[lang]}</strong>
<small className="overflow-hidden text-xs font-[520] leading-tight truncate text-[color-mix(in_srgb,#0f172a_48%,#94a3b8)]">{primary.label}</small>
</span>
</a>
<div className="landing-install-control relative">
<div className="landing-install-trigger grid grid-cols-[minmax(0,1fr)_52px] items-stretch w-[min(340px,calc(100vw-36px))] min-h-[68px] border-0 rounded-full mx-auto overflow-hidden">
<a className="landing-install-primary grid grid-cols-[auto_minmax(0,1fr)] gap-4 items-center min-w-0 px-6 max-[360px]:gap-3 max-[360px]:px-5" href={primary.href}>
<PlatformIcon id={primary.iconId} size={30} variant="dark" />
<span className="grid gap-0.5 min-w-0 text-left">
<strong className="overflow-hidden text-[15px] font-[780] leading-[1.2] truncate">{downloadLabel[lang]}</strong>
<small className="overflow-hidden text-xs font-[520] leading-tight truncate text-[color-mix(in_srgb,#0f172a_48%,#94a3b8)]">{primary.label}</small>
</span>
</a>
<button
type="button"
aria-controls="landing-install-menu"
aria-expanded={open}
aria-haspopup="menu"
aria-label={lang === "cn" ? "显示其他下载选项" : "Show other download options"}
className="landing-install-toggle grid place-items-center border-0 border-l border-l-[rgba(15,23,42,0.12)] bg-transparent text-[#5f6876] cursor-pointer"
onClick={() => setOpen((current) => !current)}
>
<ChevronDown size={18} />
</button>
</div>
<div
className="landing-install-menu absolute z-30 top-[calc(100%+12px)] left-1/2 -translate-x-1/2 grid w-[min(380px,calc(100vw-32px))] border border-[rgba(155,176,205,0.17)] rounded-xl py-1.5 max-[760px]:left-auto max-[760px]:translate-x-0"
id="landing-install-menu"
role="menu"
aria-label={lang === "cn" ? "下载选项" : "Download options"}
>
{menuOptions.map((item) => (
<a className="landing-install-option grid grid-cols-[24px_minmax(0,1fr)_18px] gap-3 items-center min-h-11 min-w-0 border-0 px-[18px] py-3 bg-transparent text-left cursor-pointer" href={item.href} key={item.id} role="menuitem">
<PlatformIcon id={item.iconId} size={20} variant="light" />
<span className="grid min-w-0 gap-1">
<span className="flex min-w-0 items-center gap-2">
<strong className="overflow-hidden text-sm font-[640] leading-[1.2] truncate">{item.label}</strong>
{item.badge ? <small className="shrink-0 rounded-full bg-white/10 px-2 py-0.5 text-[10px] font-[680] leading-none text-white/70">{item.badge}</small> : null}
</span>
{item.description ? <small className="overflow-hidden text-xs leading-[1.3] text-white/45 truncate">{item.description}</small> : null}
</span>
<Download size={15} aria-hidden="true" />
</a>
))}
</div>
</div>
{platformId === "windows" && !open ? (
<button
type="button"
aria-controls="landing-install-menu"
aria-expanded={open}
aria-haspopup="menu"
aria-label={lang === "cn" ? "显示其他下载选项" : "Show other download options"}
className="landing-install-toggle grid place-items-center border-0 border-l border-l-[rgba(15,23,42,0.12)] bg-transparent text-[#5f6876] cursor-pointer"
onClick={() => setOpen((current) => !current)}
className="mt-3 w-[min(340px,calc(100vw-36px))] border-0 bg-transparent px-2 text-center text-xs leading-relaxed text-[color-mix(in_srgb,var(--color-landing-ink)_62%,var(--color-landing-muted))] underline decoration-[color-mix(in_srgb,var(--color-landing-muted)_48%,transparent)] underline-offset-4 cursor-pointer hover:text-[var(--color-landing-ink)]"
onClick={() => setOpen(true)}
>
<ChevronDown size={18} />
{offlineHint[lang]}
</button>
</div>
<div
className="landing-install-menu absolute z-30 top-[calc(100%+12px)] left-1/2 -translate-x-1/2 grid w-[min(300px,calc(100vw-48px))] border border-[rgba(155,176,205,0.17)] rounded-xl py-1.5"
id="landing-install-menu"
role="menu"
aria-label={lang === "cn" ? "下载选项" : "Download options"}
>
{menuOptions.map((item) => (
<a className="landing-install-option grid grid-cols-[24px_minmax(0,1fr)_18px] gap-3 items-center min-h-11 min-w-0 border-0 px-[18px] py-3 bg-transparent text-left cursor-pointer" href={item.href} key={item.id} role="menuitem">
<PlatformIcon id={item.id} size={20} variant="light" />
<strong className="overflow-hidden text-sm font-[640] leading-[1.2] truncate">{item.label}</strong>
<Download size={15} aria-hidden="true" />
</a>
))}
</div>
) : null}
</div>
);
}
+35
View File
@@ -0,0 +1,35 @@
import assert from "node:assert/strict";
import { test } from "vitest";
import { createInstallOptions } from "./downloadLinks";
test("Windows downloads include standard, offline, and Windows 7 installers", () => {
const windowsOptions = createInstallOptions("cn", "0.5.82").filter((option) => option.iconId === "windows");
assert.deepEqual(
windowsOptions.map(({ id, label, description, badge, href }) => ({ id, label, description, badge, href })),
[
{
id: "windows",
label: "Windows 10/11 (x64)",
description: "标准在线安装包",
badge: "推荐",
href: "https://dl.dbxio.com/releases/latest/DBX_0.5.82_x64-setup.exe?v=0.5.82",
},
{
id: "windows-offline",
label: "Windows 10/11 离线安装包",
description: "内置 WebView2 · 适用于无网络环境",
badge: "离线",
href: "https://dl.dbxio.com/releases/latest/DBX_0.5.82_x64-webview2-offline-setup.exe?v=0.5.82",
},
{
id: "windows-7-offline",
label: "Windows 7 离线安装包",
description: "内置 WebView2 109 · 仅支持 x64",
badge: "旧系统",
href: "https://dl.dbxio.com/releases/latest/DBX_0.5.82_x64-win7-webview2-109-offline-setup.exe?v=0.5.82",
},
],
);
});
+33 -1
View File
@@ -2,13 +2,19 @@ export type InstallLang = "en" | "cn";
export type InstallOption = {
id: string;
iconId: string;
label: string;
description?: string;
badge?: string;
href: string;
};
type DownloadArtifact = {
id: string;
iconId: string;
labels: Record<InstallLang, string>;
descriptions?: Record<InstallLang, string>;
badges?: Record<InstallLang, string>;
suffix: string;
};
@@ -17,26 +23,49 @@ const DOWNLOAD_BASE_URL = "https://dl.dbxio.com/releases/latest";
const downloadArtifacts: DownloadArtifact[] = [
{
id: "macos-arm",
iconId: "macos-arm",
labels: { en: "For macOS (Apple Silicon)", cn: "适用于 macOS (Apple Silicon)" },
suffix: "aarch64.dmg",
},
{
id: "macos-intel",
iconId: "macos-intel",
labels: { en: "For macOS (Intel)", cn: "适用于 macOS (Intel)" },
suffix: "x64.dmg",
},
{
id: "windows",
labels: { en: "For Windows", cn: "适用于 Windows" },
iconId: "windows",
labels: { en: "Windows 10/11 (x64)", cn: "Windows 10/11 (x64)" },
descriptions: { en: "Standard online installer", cn: "标准在线安装包" },
badges: { en: "Recommended", cn: "推荐" },
suffix: "x64-setup.exe",
},
{
id: "windows-offline",
iconId: "windows",
labels: { en: "Windows 10/11 offline installer", cn: "Windows 10/11 离线安装包" },
descriptions: { en: "Includes WebView2 · For offline networks", cn: "内置 WebView2 · 适用于无网络环境" },
badges: { en: "Offline", cn: "离线" },
suffix: "x64-webview2-offline-setup.exe",
},
{
id: "windows-7-offline",
iconId: "windows",
labels: { en: "Windows 7 offline installer", cn: "Windows 7 离线安装包" },
descriptions: { en: "Includes WebView2 109 · x64 only", cn: "内置 WebView2 109 · 仅支持 x64" },
badges: { en: "Legacy", cn: "旧系统" },
suffix: "x64-win7-webview2-109-offline-setup.exe",
},
{
id: "linux",
iconId: "linux",
labels: { en: "For Linux x64", cn: "适用于 Linux x64" },
suffix: "amd64.AppImage",
},
{
id: "linux-arm",
iconId: "linux-arm",
labels: { en: "For Linux ARM64", cn: "适用于 Linux ARM64" },
suffix: "aarch64.AppImage",
},
@@ -45,7 +74,10 @@ const downloadArtifacts: DownloadArtifact[] = [
export function createInstallOptions(lang: InstallLang, version: string): InstallOption[] {
return downloadArtifacts.map((artifact) => ({
id: artifact.id,
iconId: artifact.iconId,
label: artifact.labels[lang],
description: artifact.descriptions?.[lang],
badge: artifact.badges?.[lang],
href: `${DOWNLOAD_BASE_URL}/DBX_${version}_${artifact.suffix}?v=${version}`,
}));
}