mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-07 09:03:27 +00:00
AppImage only + clickable OSes (#1495)
* AppImage only + clickable OSes * disbaled
This commit is contained in:
parent
6bdf0e0158
commit
b758d3865c
|
@ -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 });
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue