diff --git a/frontend/package.json b/frontend/package.json index 6e2d891..5c49dc8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,6 +22,7 @@ "clsx": "^2.1.1", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-icons": "^5.5.0", "react-tooltip": "^5.28.0", "react-use-websocket": "^4.11.1", "tailwind-merge": "^2.5.5", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 9aae4f2..187d6fd 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: react-dom: specifier: ^19.0.0 version: 19.0.0(react@19.0.0) + react-icons: + specifier: ^5.5.0 + version: 5.5.0(react@19.0.0) react-tooltip: specifier: ^5.28.0 version: 5.28.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -2086,6 +2089,11 @@ packages: peerDependencies: react: ^19.0.0 + react-icons@5.5.0: + resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} + peerDependencies: + react: '*' + react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} @@ -5086,6 +5094,10 @@ snapshots: react: 19.0.0 scheduler: 0.25.0 + react-icons@5.5.0(react@19.0.0): + dependencies: + react: 19.0.0 + react-refresh@0.14.2: {} react-tooltip@5.28.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): diff --git a/frontend/src/components/DownloadButton.tsx b/frontend/src/components/DownloadButton.tsx index 7131134..5c84458 100644 --- a/frontend/src/components/DownloadButton.tsx +++ b/frontend/src/components/DownloadButton.tsx @@ -9,10 +9,10 @@ import { MenuSeparator, } from "@headlessui/react"; import { - ArrowDownTrayIcon, BeakerIcon, ChevronDownIcon, } from "@heroicons/react/16/solid"; +import { FaWindows, FaApple, FaLinux } from "react-icons/fa"; import { useRef } from "react"; type DownloadButtonProps = { @@ -36,6 +36,34 @@ function getSystemType(): SystemType | null { } } +function getPlatformIcon(id: string, className?: string) { + const platformId = id.toLowerCase(); + switch (platformId) { + case "windows": + return ; + case "macos": + return ; + case "linux": + return ; + default: + return null; + } +} + +function getPlatformDisplayName(id: string): string { + const platformId = id.toLowerCase(); + switch (platformId) { + case "windows": + return "Windows"; + case "macos": + return "macOS"; + case "linux": + return "Linux"; + default: + return id; + } +} + export default function DownloadButton({ disabled, executables, @@ -47,6 +75,10 @@ export default function DownloadButton({ return executables?.find((e) => e.id.toLowerCase() === id.toLowerCase()); } + const detectedPlatform = getSystemType(); + const platformExecutable = detectedPlatform ? getExecutable(detectedPlatform) : null; + const canAutoDownload = platformExecutable != null; + async function handleDownload(id: string) { const executable = getExecutable(id); if (executable == null) { @@ -59,16 +91,8 @@ export default function DownloadButton({ } function handleDownloadAutomatic() { - const systemType = getSystemType(); - - // If the system type is unknown/unavailable, open the menu for manual selection - if (systemType == null || getExecutable(systemType) == null) { - menuRef.current?.click(); - } - - // Otherwise, download the executable automatically - else { - handleDownload(systemType); + if (canAutoDownload && detectedPlatform) { + handleDownload(detectedPlatform); } } @@ -83,14 +107,17 @@ export default function DownloadButton({ )} > handleDownload(executable.id)} >
- - {executable.id} + {getPlatformIcon(executable.id, "size-4 fill-white/40")} + {getPlatformDisplayName(executable.id)}
{(executable.size / 1024 / 1024).toFixed(1)} MiB