diff --git a/packages/website/src/components/landing-page.tsx b/packages/website/src/components/landing-page.tsx index 357d22f5e..6987fcb51 100644 --- a/packages/website/src/components/landing-page.tsx +++ b/packages/website/src/components/landing-page.tsx @@ -1,73 +1,19 @@ import * as React from "react"; import { motion, AnimatePresence } from "framer-motion"; import { CursorFieldProvider } from "~/components/butterfly"; -import websitePackage from "../../package.json"; +import { + appStoreUrl, + playStoreUrl, + webAppUrl, + downloadOptions, + useDetectedPlatform, + AppleIcon, + AndroidIcon, + TerminalIcon, + GlobeIcon, +} from "~/downloads"; import "~/styles.css"; -const desktopVersion = websitePackage.version; -const releaseBase = `https://github.com/getpaseo/paseo/releases/download/v${desktopVersion}`; - - -type Platform = "mac-silicon" | "mac-intel" | "windows" | "linux"; - -interface DownloadOption { - platform: Platform; - label: string; - href: string; - icon: (props: React.SVGProps) => React.ReactElement; -} - -const downloadOptions: DownloadOption[] = [ - { - platform: "mac-silicon", - label: "Mac", - href: `${releaseBase}/Paseo-${desktopVersion}-arm64.dmg`, - icon: AppleIcon, - }, - { - platform: "mac-intel", - label: "Mac Intel", - href: `${releaseBase}/Paseo-${desktopVersion}.dmg`, - icon: AppleIcon, - }, - { - platform: "windows", - label: "Windows", - href: `${releaseBase}/Paseo-Setup-${desktopVersion}.exe`, - icon: WindowsIcon, - }, - { - platform: "linux", - label: "Linux", - href: `${releaseBase}/Paseo-${desktopVersion}.AppImage`, - icon: LinuxIcon, - }, -]; - -function useDetectedPlatform(): Platform { - const [platform, setPlatform] = React.useState("mac-silicon"); - - React.useEffect(() => { - const ua = navigator.userAgent.toLowerCase(); - if (ua.includes("win")) { - setPlatform("windows"); - } else if (ua.includes("linux")) { - setPlatform("linux"); - } else if (ua.includes("mac")) { - // Check for Apple Silicon vs Intel - // navigator.platform is deprecated but still the most reliable check - const isARM = - /arm|aarch64/i.test(navigator.platform) || - // Chrome/Edge on Apple Silicon report x86 platform but have ARM in userAgentData - (navigator as unknown as { userAgentData?: { architecture?: string } }).userAgentData - ?.architecture === "arm"; - setPlatform(isARM ? "mac-silicon" : "mac-silicon"); // Default to Silicon for modern Macs - } - }, []); - - return platform; -} - interface LandingPageProps { title: React.ReactNode; subtitle: string; @@ -193,7 +139,7 @@ export function LandingPage({ title, subtitle }: LandingPageProps) {

Download

) { ); } -function AppleIcon(props: React.SVGProps) { - return ( - - ); -} - -function AndroidIcon(props: React.SVGProps) { - return ( - - ); -} - function AppStoreIcon(props: React.SVGProps) { return ( ) { ); } -function WindowsIcon(props: React.SVGProps) { - return ( - - ); -} - -function LinuxIcon(props: React.SVGProps) { - return ( - - ); -} - -function TerminalIcon(props: React.SVGProps) { - return ( - - ); -} - function ChevronDownIcon(props: React.SVGProps) { return ( ) { ); } -function GlobeIcon(props: React.SVGProps) { - return ( - - ); -} - function Step({ number, children }: { number: number; children: React.ReactNode }) { return (
diff --git a/packages/website/src/downloads.tsx b/packages/website/src/downloads.tsx new file mode 100644 index 000000000..431a9ee51 --- /dev/null +++ b/packages/website/src/downloads.tsx @@ -0,0 +1,169 @@ +import * as React from "react"; +import websitePackage from "../package.json"; + +export const desktopVersion = websitePackage.version; +export const releaseBase = `https://github.com/getpaseo/paseo/releases/download/v${desktopVersion}`; + +export const appStoreUrl = "https://apps.apple.com/app/paseo-pocket-engineer/id6758887924"; +export const playStoreUrl = "https://play.google.com/store/apps/details?id=sh.paseo"; +export const webAppUrl = "https://app.paseo.sh"; + +type Platform = "mac-silicon" | "mac-intel" | "windows" | "linux"; + +export interface DownloadOption { + platform: Platform; + label: string; + href: string; + icon: (props: React.SVGProps) => React.ReactElement; +} + +export const downloadOptions: DownloadOption[] = [ + { + platform: "mac-silicon", + label: "Mac", + href: `${releaseBase}/Paseo-${desktopVersion}-arm64.dmg`, + icon: AppleIcon, + }, + { + platform: "mac-intel", + label: "Mac Intel", + href: `${releaseBase}/Paseo-${desktopVersion}.dmg`, + icon: AppleIcon, + }, + { + platform: "windows", + label: "Windows", + href: `${releaseBase}/Paseo-Setup-${desktopVersion}.exe`, + icon: WindowsIcon, + }, + { + platform: "linux", + label: "Linux", + href: `${releaseBase}/Paseo-${desktopVersion}.AppImage`, + icon: LinuxIcon, + }, +]; + +export function useDetectedPlatform(): Platform { + const [platform, setPlatform] = React.useState("mac-silicon"); + + React.useEffect(() => { + const ua = navigator.userAgent.toLowerCase(); + if (ua.includes("win")) { + setPlatform("windows"); + } else if (ua.includes("linux")) { + setPlatform("linux"); + } else if (ua.includes("mac")) { + // Check for Apple Silicon vs Intel + // navigator.platform is deprecated but still the most reliable check + const isARM = + /arm|aarch64/i.test(navigator.platform) || + // Chrome/Edge on Apple Silicon report x86 platform but have ARM in userAgentData + (navigator as unknown as { userAgentData?: { architecture?: string } }).userAgentData + ?.architecture === "arm"; + setPlatform(isARM ? "mac-silicon" : "mac-silicon"); // Default to Silicon for modern Macs + } + }, []); + + return platform; +} + +export function AppleIcon(props: React.SVGProps) { + return ( + + ); +} + +export function AndroidIcon(props: React.SVGProps) { + return ( + + ); +} + +export function WindowsIcon(props: React.SVGProps) { + return ( + + ); +} + +export function LinuxIcon(props: React.SVGProps) { + return ( + + ); +} + +export function TerminalIcon(props: React.SVGProps) { + return ( + + ); +} + +export function GlobeIcon(props: React.SVGProps) { + return ( + + ); +} diff --git a/packages/website/src/routes/download.tsx b/packages/website/src/routes/download.tsx index 304aeb800..e5a6bb8e4 100644 --- a/packages/website/src/routes/download.tsx +++ b/packages/website/src/routes/download.tsx @@ -1,11 +1,20 @@ import { Link, createFileRoute } from "@tanstack/react-router"; import { pageMeta } from "~/meta"; -import websitePackage from "../../package.json"; +import { + desktopVersion, + releaseBase, + appStoreUrl, + playStoreUrl, + webAppUrl, + AppleIcon, + AndroidIcon, + WindowsIcon, + LinuxIcon, + TerminalIcon, + GlobeIcon, +} from "~/downloads"; import "~/styles.css"; -const desktopVersion = websitePackage.version; -const releaseBase = `https://github.com/getpaseo/paseo/releases/download/v${desktopVersion}`; - export const Route = createFileRoute("/download")({ head: () => ({ meta: pageMeta( @@ -161,7 +170,7 @@ function Download() {
@@ -180,7 +189,7 @@ function Download() {
@@ -204,7 +213,7 @@ function Download() {
@@ -279,66 +288,6 @@ function DownloadPill({ ); } -function AppleIcon(props: React.SVGProps) { - return ( - - ); -} - -function AndroidIcon(props: React.SVGProps) { - return ( - - ); -} - -function WindowsIcon(props: React.SVGProps) { - return ( - - ); -} - -function LinuxIcon(props: React.SVGProps) { - return ( - - ); -} - function MonitorIcon(props: React.SVGProps) { return ( ) { ); } - -function TerminalIcon(props: React.SVGProps) { - return ( - - ); -} - -function GlobeIcon(props: React.SVGProps) { - return ( - - ); -}