forked from Rosetta/landing
158 lines
5.8 KiB
TypeScript
158 lines
5.8 KiB
TypeScript
import {
|
|
Button,
|
|
Card,
|
|
Container,
|
|
Flex,
|
|
Text,
|
|
Title,
|
|
useMantineTheme,
|
|
} from '@mantine/core';
|
|
import classes from './DownloadCenter.module.css';
|
|
import { RosettaLogo } from '../RosettaLogo/RosettaLogo';
|
|
import { useEffect, useState } from 'react';
|
|
import { FaWindows } from 'react-icons/fa';
|
|
import { FcAndroidOs, FcLinux } from 'react-icons/fc';
|
|
import { Switch } from '../Switch/Switch';
|
|
import { IconDownload } from '@tabler/icons-react';
|
|
|
|
interface DownloadFeature {
|
|
platform: string;
|
|
arch: string;
|
|
link: string;
|
|
version: string;
|
|
}
|
|
|
|
interface UpdateItem {
|
|
platform: string;
|
|
arch: string;
|
|
version: string;
|
|
downloadUrl: string;
|
|
}
|
|
|
|
const fetchUpdates = async (): Promise<DownloadFeature[]> => {
|
|
try {
|
|
const response = await fetch('https://sdu.rosetta.im/updates/all');
|
|
const data = (await response.json()) as { items?: UpdateItem[] };
|
|
|
|
return (data.items || []).map((item) => ({
|
|
platform: item.platform,
|
|
arch: item.arch,
|
|
version: item.version,
|
|
link: new URL(item.downloadUrl, 'https://sdu.rosetta.im').toString(),
|
|
})).sort((a, b) => {
|
|
const platformOrder = ['linux', 'win32', 'android'];
|
|
const archOrder = ['arm64', 'x64', 'universal']
|
|
const platformComparison = platformOrder.indexOf(a.platform) - platformOrder.indexOf(b.platform);
|
|
if (platformComparison !== 0) {
|
|
return platformComparison;
|
|
}
|
|
return archOrder.indexOf(a.arch) - archOrder.indexOf(b.arch);
|
|
});
|
|
} catch (error) {
|
|
console.error('Failed to fetch updates:', error);
|
|
return [];
|
|
}
|
|
};
|
|
|
|
export function DownloadCenter() {
|
|
const theme = useMantineTheme();
|
|
const [kernels, setKernels] = useState<DownloadFeature[]>([]);
|
|
const [targetPlatforms, setTargetPlatforms] = useState<string[]>(['linux', 'win32', 'android']);
|
|
|
|
useEffect(() => {
|
|
fetchUpdates().then(setKernels);
|
|
}, []);
|
|
|
|
const switchTarget = (value: string) => {
|
|
let targetPlatforms: string[] = [];
|
|
switch(value){
|
|
case 'All':
|
|
targetPlatforms = ['linux', 'win32', 'android'];
|
|
break;
|
|
case 'Windows':
|
|
targetPlatforms = ['win32'];
|
|
break;
|
|
case 'Android':
|
|
targetPlatforms = ['android'];
|
|
break;
|
|
case 'Linux':
|
|
targetPlatforms = ['linux'];
|
|
break;
|
|
}
|
|
setTargetPlatforms(targetPlatforms);
|
|
}
|
|
|
|
const translatePlatformToOsName = (platform: string) => {
|
|
switch(platform){
|
|
case 'linux':
|
|
return 'Linux';
|
|
case 'win32':
|
|
return 'Windows';
|
|
case 'android':
|
|
return 'Android';
|
|
default:
|
|
return platform;
|
|
}
|
|
}
|
|
|
|
const translatePlatformAndArchToCpuName = (platform : string, arch: string) => {
|
|
switch(platform){
|
|
case 'linux':
|
|
return arch === 'arm64' ? 'ARM64' : 'x64';
|
|
case 'win32':
|
|
return arch === 'arm64' ? 'ARM64' : 'x64';
|
|
case 'android':
|
|
return 'universal';
|
|
default:
|
|
return arch;
|
|
}
|
|
}
|
|
|
|
|
|
const features = kernels.filter((v) => targetPlatforms.includes(v.platform)).map((feature) => (
|
|
<Card key={feature.link} radius="md" className={classes.card} padding="xl">
|
|
<Flex direction={'column'} align="center" justify={'center'}>
|
|
{feature.platform === 'linux' && <FcLinux size={50} />}
|
|
{feature.platform === 'win32' && <FaWindows size={50} color={theme.colors.blue[6]} />}
|
|
{feature.platform === 'android' && <FcAndroidOs size={50} />}
|
|
<Text fz="lg" ta={'center'} fw={500} mt="md">
|
|
{translatePlatformToOsName(feature.platform)} - {translatePlatformAndArchToCpuName(feature.platform, feature.arch)}
|
|
</Text>
|
|
<Text c="dimmed" fz="sm" ta={'center'} mt="xs">
|
|
{feature.platform == 'linux' && <>This version is for Linux and comes as an AppImage for the GUI versions.</>}
|
|
{feature.platform == 'win32' && <>Download this version of you have computer on Windows 10 or later.</>}
|
|
{feature.platform == 'android' && <>This version is for Android devices and all architectures.</>}
|
|
</Text>
|
|
<Button component={'a'} href={feature.link} variant={'subtle'} mt={'sm'} leftSection={
|
|
<IconDownload size={16}></IconDownload>
|
|
}>Get {feature.version} now</Button>
|
|
</Flex>
|
|
</Card>
|
|
));
|
|
|
|
return (
|
|
<div className={classes.wrapper}>
|
|
<Container id={'kernels'} mb={'xl'} size="lg" mt={'xl'}>
|
|
<Flex justify="center" align="center" direction="row" gap={'md'}>
|
|
<Title order={2} className={classes.title} ta="center">
|
|
Download
|
|
</Title>
|
|
<RosettaLogo size={35}></RosettaLogo>
|
|
</Flex>
|
|
|
|
<Text c="dimmed" className={classes.description} ta="center" mt="md">
|
|
Choose your platform and get started with Rosetta today. Enjoy secure and fast messaging across all your devices.
|
|
</Text>
|
|
|
|
<Flex justify={'center'} mt={'lg'}>
|
|
<Switch onChange={switchTarget} data={['All', 'Windows', 'Linux', 'Android']}></Switch>
|
|
</Flex>
|
|
|
|
<Flex gap="xl" justify={'center'} wrap={'wrap'} align={'center'} mt={50}>
|
|
{features}
|
|
</Flex>
|
|
</Container>
|
|
</div>
|
|
);
|
|
}
|