From ea87161a91db9df9a06a35c4324fbdb586df7236 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Fri, 26 Sep 2025 22:40:27 +0300 Subject: [PATCH] feat(website): smart download now button --- apps/website2/src/index.html | 6 + apps/website2/src/script.ts | 208 +++++++++++++++++++++++++++++++++++ apps/website2/src/style.css | 20 +++- 3 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 apps/website2/src/script.ts diff --git a/apps/website2/src/index.html b/apps/website2/src/index.html index ee0ac53b6..2d4927a45 100644 --- a/apps/website2/src/index.html +++ b/apps/website2/src/index.html @@ -16,6 +16,10 @@

Organize your thoughts. Build your personal knowledge base.

Trilium is an open-source solution for note-taking and organizing a personal knowledge base. Use it locally on your desktop, or sync it with your self-hosted server to keep your notes everywhere you go.

+ + Download now + +
@@ -201,6 +205,8 @@

+ + \ No newline at end of file diff --git a/apps/website2/src/script.ts b/apps/website2/src/script.ts new file mode 100644 index 000000000..8e0592ba5 --- /dev/null +++ b/apps/website2/src/script.ts @@ -0,0 +1,208 @@ +type App = "desktop" | "server"; + +type Architecture = 'x64' | 'arm64'; + +type Platform = "macos" | "windows" | "linux" | "pikapod"; + +const version = "0.99.0"; + +interface DownloadInfo { + recommended?: boolean; + name: string; + url?: string; +} + +interface DownloadMatrixEntry { + title: Record | string; + description: Record | string; + downloads: Record; +} + +type DownloadMatrix = Record; + +// Keep compatibility info inline with https://github.com/electron/electron/blob/main/README.md#platform-support. +const downloadMatrix: DownloadMatrix = { + desktop: { + windows: { + title: { + x64: "Windows 64-bit", + arm64: "Windows on ARM" + }, + description: { + x64: "Compatible with Intel or AMD devices running Windows 10 and 11.", + arm64: "Compatible with ARM devices (e.g. with Qualcomm Snapdragon).", + }, + downloads: { + exe: { + recommended: true, + name: "Download Installer (.exe)" + }, + zip: { + name: "Portable (.zip)" + }, + scoop: { + name: "Scoop", + url: "https://scoop.sh/#/apps?q=triliumnext" + }, + winget: { + name: "Winget", + url: "https://github.com/microsoft/winget-pkgs/tree/master/manifests/t/TriliumNext/Notes/" + } + } + }, + linux: { + title: { + x64: "Linux 64-bit", + arm64: "Linux on ARM" + }, + description: { + x64: "For most Linux distributions, compatible with x86_64 architecture.", + arm64: "For ARM-based Linux distributions, compatible with aarch64 architecture.", + }, + downloads: { + deb: { + recommended: true, + name: "Download .deb" + }, + rpm: { + name: ".rpm" + }, + flatpak: { + name: ".flatpak" + }, + zip: { + name: "Portable (.zip)" + }, + nixpkgs: { + name: "nixpkgs", + url: "https://search.nixos.org/packages?query=trilium-next" + }, + aur: { + name: "AUR", + url: "https://aur.archlinux.org/packages/triliumnext-bin" + } + } + }, + macos: { + title: { + x64: "macOS for Intel", + arm64: "macOS for Apple Silicon" + }, + description: { + x64: "For Intel-based Macs running macOS Big Sur or later.", + arm64: "For Apple Silicon Macs such as those with M1 and M2 chips.", + }, + downloads: { + dmg: { + recommended: true, + name: "Download Installer (.dmg)" + }, + zip: { + name: "Portable (.zip)" + } + } + } + }, + server: { + linux: { + title: "Self-hosted (Linux)", + description: "Deploy Trilium Notes on your own server or VPS, compatible with most Linux distributions.", + downloads: { + docker: { + recommended: true, + name: "View on Docker Hub", + url: "https://hub.docker.com/r/triliumnext/notes" + }, + tarX64: { + name: "x86 (.tar.xz)", + url: `https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-x64.tar.xz` + }, + tarArm64: { + name: "ARM (.tar.xz)", + url: `https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-arm64.tar.xz` + }, + nixos: { + name: "NixOS module", + url: "https://search.nixos.org/options?query=trilium-server" + } + } + }, + pikapod: { + title: "Paid hosting", + description: "Trilium Notes hosted on PikaPods, a paid service for easy access and management.", + downloads: { + pikapod: { + recommended: true, + name: "Set up on PikaPods", + url: "https://www.pikapods.com/pods?run=trilium-next" + }, + triliumcc: { + name: "Alternatively see trilium.cc", + url: "https://trilium.cc/" + } + } + } + } +}; + +function buildDownloadUrl(app: App, platform: Platform, format: string, architecture: Architecture): string { + if (app === "desktop") { + return downloadMatrix.desktop[platform]?.downloads[format].url ?? + `https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-v${version}-${platform}-${architecture}.${format}`; + } else if (app === "server") { + return downloadMatrix.server[platform]?.downloads[format].url ?? "#"; + } else { + return "#"; + } +} + +function getArchitecture(): Architecture { + const userAgent = navigator.userAgent.toLowerCase(); + if (userAgent.includes('arm64') || userAgent.includes('aarch64')) { + return 'arm64'; + } + + return "x64"; +} + +function getPlatform(): Platform { + const userAgent = navigator.userAgent.toLowerCase(); + if (userAgent.includes('macintosh') || userAgent.includes('mac os x')) { + return "macos"; + } else if (userAgent.includes('windows') || userAgent.includes('win32')) { + return "windows"; + } else { + return "linux"; + } +} + +function getRecommendedDownload() { + const architecture = getArchitecture(); + const platform = getPlatform(); + + const downloadInfo = downloadMatrix.desktop[platform]?.downloads; + const recommendedDownload = Object.entries(downloadInfo || {}).find(d => d[1].recommended); + const format = recommendedDownload?.[0]; + const url = buildDownloadUrl("desktop", platform, format || 'zip', architecture); + + return { + architecture, + platform, + url + } +} + +function applyAutomaticDownloadButtons() { + const buttons = document.querySelectorAll(".download-button"); + const { url, architecture, platform } = getRecommendedDownload(); + + for (const button of buttons) { + button.href = url; + + const platformEl = button.querySelector(".platform"); + if (!platformEl) continue; + platformEl.textContent = [ architecture, platform ].join(" "); + } +} + +applyAutomaticDownloadButtons(); diff --git a/apps/website2/src/style.css b/apps/website2/src/style.css index 390be2174..da19c8c10 100644 --- a/apps/website2/src/style.css +++ b/apps/website2/src/style.css @@ -193,4 +193,22 @@ footer { span.text-big { font-size: 1.25em; -} \ No newline at end of file +} + +/* #region Download button */ +.download-button { + text-decoration: none; + background: var(--brand-1); + padding: 1em 2em; + border-radius: 6px; + margin: 1em 0; + color: white; + box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3); + display: inline-block; +} + +.download-button .platform { + font-size: 0.75em; + opacity: 0.75; +} +/* #endregion */ \ No newline at end of file