AppImage only + clickable OSes (#1495)

* AppImage only + clickable OSes

* disbaled
This commit is contained in:
Brendan Allan 2023-10-11 19:04:44 +08:00 committed by GitHub
parent 6bdf0e0158
commit b758d3865c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 34 deletions

View file

@ -3,14 +3,15 @@ import { z } from 'zod';
import { env } from '~/env'; import { env } from '~/env';
const version = z.union([z.literal('stable'), z.literal('alpha')]); const version = z.union([z.literal('stable'), z.literal('alpha')]);
const tauriTarget = z.union([ const tauriTarget = z.union([z.literal('linux'), z.literal('windows'), z.literal('darwin')]);
z.literal('linux_deb'),
z.literal('linux_appimage'),
z.literal('windows'),
z.literal('darwin')
]);
const tauriArch = z.union([z.literal('x86_64'), z.literal('aarch64')]); const tauriArch = z.union([z.literal('x86_64'), z.literal('aarch64')]);
const extensions = {
linux: 'AppImage',
windows: 'msi',
darwin: 'dmg'
} as const satisfies Record<z.infer<typeof tauriTarget>, string>;
const paramsSchema = z.object({ const paramsSchema = z.object({
target: tauriTarget, target: tauriTarget,
arch: tauriArch, arch: tauriArch,
@ -39,14 +40,9 @@ export async function GET(
params.version = release.tag_name; params.version = release.tag_name;
const releaseName = const name = `Spacedrive-${params.target}-${params.arch}.${extensions[params.target]}` as const;
params.target === 'linux_deb'
? `Spacedrive-linux-${params.arch}.deb`
: params.target === 'linux_appimage'
? `Spacedrive-linux-${params.arch}.AppImage`
: `Spacedrive-${params.target}-${params.arch}`;
const asset = release.assets?.find(({ name }: any) => name.startsWith(releaseName)); const asset = release.assets?.find((asset: any) => asset.name === name);
if (!asset) return NextResponse.json({ error: 'Asset not found' }, { status: 404 }); if (!asset) return NextResponse.json({ error: 'Asset not found' }, { status: 404 });

View file

@ -10,7 +10,7 @@ import { motion } from 'framer-motion';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import Head from 'next/head'; import Head from 'next/head';
import Image from 'next/image'; import Image from 'next/image';
import { useEffect, useState } from 'react'; import { ComponentProps, useEffect, useState } from 'react';
import { Tooltip, TooltipProvider, tw } from '@sd/ui'; import { Tooltip, TooltipProvider, tw } from '@sd/ui';
import NewBanner from '~/components/NewBanner'; import NewBanner from '~/components/NewBanner';
import PageWrapper from '~/components/PageWrapper'; import PageWrapper from '~/components/PageWrapper';
@ -25,29 +25,18 @@ const HomeCTA = dynamic(() => import('~/components/HomeCTA'), {
const AppFrameOuter = tw.div`relative m-auto flex w-full max-w-7xl rounded-lg transition-opacity`; const AppFrameOuter = tw.div`relative m-auto flex w-full max-w-7xl rounded-lg transition-opacity`;
const AppFrameInner = tw.div`z-30 flex w-full rounded-lg border-t border-app-line/50 backdrop-blur`; const AppFrameInner = tw.div`z-30 flex w-full rounded-lg border-t border-app-line/50 backdrop-blur`;
const platforms = [
{ name: 'iOS and macOS', icon: Apple },
{ name: 'Windows', icon: WindowsLogo },
{ name: 'Linux', icon: LinuxLogo },
{ name: 'Android', icon: AndroidLogo },
{ name: 'Web', icon: Globe }
];
const BASE_DL_LINK = '/api/releases/desktop/stable'; const BASE_DL_LINK = '/api/releases/desktop/stable';
const downloadEntries = { const downloadEntries = {
linux: { linux: {
name: 'Linux', name: 'Linux',
icon: <LinuxLogo />, icon: <LinuxLogo />,
links: { links: 'linux/x86_64'
Deb: 'linux_deb/x86_64',
AppImage: 'linux_appimage/x86_64'
}
}, },
macOS: { macOS: {
name: 'Mac', name: 'Mac',
icon: <Apple />, icon: <Apple />,
links: { links: {
'Apple Intel': 'darwin/x86_64', 'Intel': 'darwin/x86_64',
'Apple Silicon': 'darwin/aarch64' 'Apple Silicon': 'darwin/aarch64'
} }
}, },
@ -56,7 +45,19 @@ const downloadEntries = {
icon: <WindowsLogo />, icon: <WindowsLogo />,
links: 'windows/x86_64' links: 'windows/x86_64'
} }
}; } as const;
const platforms = [
{ name: 'iOS and macOS', icon: Apple, clickable: true },
{
name: 'Windows',
icon: WindowsLogo,
href: `${BASE_DL_LINK}/${downloadEntries.windows.links}`
},
{ name: 'Linux', icon: LinuxLogo, href: `${BASE_DL_LINK}/${downloadEntries.linux.links}` },
{ name: 'Android', icon: AndroidLogo },
{ name: 'Web', icon: Globe }
] as const;
export default function HomePage() { export default function HomePage() {
const [opacity, setOpacity] = useState(0.6); const [opacity, setOpacity] = useState(0.6);
@ -235,7 +236,19 @@ export default function HomePage() {
transition={{ delay: i * 0.2, ease: 'easeInOut' }} transition={{ delay: i * 0.2, ease: 'easeInOut' }}
key={platform.name} key={platform.name}
> >
<Platform icon={platform.icon} label={platform.name} /> <Platform
icon={platform.icon}
label={platform.name}
href={'href' in platform ? platform.href : undefined}
clickable={
'clickable' in platform ? platform.clickable : undefined
}
onClick={() => {
if (platform.name === 'iOS and macOS') {
setMultipleDownloads(downloadEntries.macOS.links);
}
}}
/>
</motion.div> </motion.div>
))} ))}
</div> </div>
@ -301,17 +314,23 @@ export default function HomePage() {
} }
interface Props { interface Props {
icon: any;
href?: string;
label: string; label: string;
icon: any;
clickable?: true;
} }
const Platform = ({ icon: Icon, href, label }: Props) => { const Platform = ({ icon: Icon, label, ...props }: ComponentProps<'a'> & Props) => {
const Outer = props.href
? (props: any) => <a aria-label={label} target="_blank" {...props} />
: props.clickable
? (props: any) => <button {...props} />
: ({ children }: any) => <>{children}</>;
return ( return (
<Tooltip label={label}> <Tooltip label={label}>
<a aria-label={label} href={href} target="_blank"> <Outer {...props}>
<Icon size={25} className="h-[25px] opacity-80" weight="fill" /> <Icon size={25} className="h-[25px] opacity-80" weight="fill" />
</a> </Outer>
</Tooltip> </Tooltip>
); );
}; };