Files
desktop/app/components/MessageAttachments/MessageFile.tsx
rosetta 83f38dc63f 'init'
2026-01-30 05:01:05 +02:00

133 lines
6.1 KiB
TypeScript

import { DownloadStatus, useAttachment } from "@/app/providers/AttachmentProvider/useAttachment";
import { AttachmentProps } from "./MessageAttachments";
import { useRosettaColors } from "@/app/hooks/useRosettaColors";
import { Avatar, Box, Flex, Loader, Text } from "@mantine/core";
import { IconArrowDown, IconFile, IconX } from "@tabler/icons-react";
import { dotCenterIfNeeded, humanFilesize } from "@/app/utils/utils";
import { AnimatedRoundedProgress } from "../AnimatedRoundedProgress/AnimatedRoundedProgress";
import { DeliveredMessageState } from "@/app/providers/DialogProvider/DialogProvider";
export function MessageFile(props : AttachmentProps) {
const colors = useRosettaColors();
const {
downloadPercentage,
downloadStatus,
uploadedPercentage,
download,
getPreview,
} =
useAttachment(
props.attachment,
props.chacha_key_plain,
);
const preview = getPreview();
const error = downloadStatus == DownloadStatus.ERROR;
const filesize = parseInt(preview.split("::")[0]);
const filename = preview.split("::")[1];
const filetype = filename.split(".")[filename.split(".").length - 1];
const isEncrypting = props.delivered == DeliveredMessageState.WAITING && uploadedPercentage <= 0;
const isUploading = props.delivered == DeliveredMessageState.WAITING && uploadedPercentage > 0 && uploadedPercentage < 100;
const onClick = async () => {
if(downloadStatus == DownloadStatus.ERROR){
return;
}
if(downloadStatus == DownloadStatus.DOWNLOADED){
//let content = await getBlob();
//let buffer = Buffer.from(content.split(",")[1], 'base64');
let pathInDownloads = window.downloadsPath + "/Rosetta Downloads/" + filename;
//await writeFile(pathInDownloads, buffer, false);
window.shell.showItemInFolder(pathInDownloads);
return;
}
if(downloadStatus == DownloadStatus.NOT_DOWNLOADED){
download();
return;
}
}
return (
<Box p={'sm'} onClick={onClick} style={{
background: colors.mainColor,
border: '1px solid ' + colors.borderColor,
borderRadius: 8,
minWidth: 200,
minHeight: 60
}}>
<Flex gap={'sm'} direction={'row'}>
<Avatar bg={error ? colors.error : colors.brandColor} size={40}>
{!error && <>
{(downloadStatus == DownloadStatus.DOWNLOADING && downloadPercentage > 0 && downloadPercentage < 100) && (
<div style={{
position: 'absolute',
top: 0,
left: 0,
}}>
<AnimatedRoundedProgress size={40} value={downloadPercentage}></AnimatedRoundedProgress>
</div>
)}
{downloadStatus != DownloadStatus.DOWNLOADED && (
<IconArrowDown color={'white'} size={22}></IconArrowDown>
)}
{isUploading && (
<div style={{
position: 'absolute',
top: 0,
left: 0,
}}>
<AnimatedRoundedProgress size={40} value={uploadedPercentage}></AnimatedRoundedProgress>
</div>
)}
{downloadStatus == DownloadStatus.DOWNLOADED && <IconFile color={'white'} size={22}></IconFile>}
</>}
{error && <>
<IconX color={'white'} size={22}></IconX>
</>}
</Avatar>
<Flex direction={'column'} gap={5}>
<Text size={'sm'}>{dotCenterIfNeeded(filename, 25, 8)}</Text>
{!error && !isEncrypting && !isUploading && (downloadStatus == DownloadStatus.DOWNLOADED || downloadStatus == DownloadStatus.NOT_DOWNLOADED) &&
<Text size={'xs'} c={colors.chevrons.active}>
{humanFilesize(filesize)} {filetype.toUpperCase()}
</Text>
}
{downloadStatus == DownloadStatus.DOWNLOADING &&
<Flex gap={5} align={'center'}>
<Loader size={10}></Loader>
<Text size={'xs'} c={colors.chevrons.active}>
Downloading... {downloadPercentage}%
</Text>
</Flex>
}
{isEncrypting &&
<Flex gap={5} align={'center'}>
<Loader size={10}></Loader>
<Text size={'xs'} c={colors.chevrons.active}>
Encrypting...
</Text>
</Flex>
}
{isUploading &&
<Flex gap={5} align={'center'}>
<Loader size={10}></Loader>
<Text size={'xs'} c={colors.chevrons.active}>
Uploading... {uploadedPercentage}%
</Text>
</Flex>
}
{downloadStatus == DownloadStatus.DECRYPTING &&
<Flex gap={5} align={'center'}>
<Loader size={10}></Loader>
<Text size={'xs'} c={colors.chevrons.active}>
Decrypting...
</Text>
</Flex>
}
{error && <Text size={'xs'} c={colors.error}>
File expired
</Text>}
</Flex>
</Flex>
</Box>
)
}