Files
cinny/src/app/components/video-viewer/VideoViewer.tsx

80 lines
2.3 KiB
TypeScript

import React from 'react';
import FileSaver from 'file-saver';
import classNames from 'classnames';
import { Box, Chip, Header, IconButton, Text, as } from 'folds';
import { Icon, Icons } from '../icons';
import * as css from './VideoViewer.css';
import { downloadMedia } from '../../utils/matrix';
import { getCurrentAccessToken } from '../../utils/auth';
export type VideoViewerProps = {
alt: string;
src: string;
requestClose: () => void;
};
export const VideoViewer = as<'div', VideoViewerProps>(
({ className, alt, src, requestClose, ...props }, ref) => { const handleDownload = async () => {
try {
const fileContent = await downloadMedia(src, getCurrentAccessToken());
FileSaver.saveAs(fileContent, alt);
} catch (error) {
console.warn('[VideoViewer] Failed to download media:', error);
try {
const response = await fetch(src);
if (response.ok) {
const blob = await response.blob();
FileSaver.saveAs(blob, alt);
}
} catch {
window.open(src, '_blank');
}
}
};
return (
<Box
className={classNames(css.VideoViewer, className)}
direction="Column"
{...props}
ref={ref}
>
<Header className={css.VideoViewerHeader} size="400">
<Box grow="Yes" alignItems="Center" gap="200">
<IconButton size="300" radii="300" onClick={requestClose}>
<Icon size="50" src={Icons.ArrowLeft} />
</IconButton>
<Text size="T300" truncate>
{alt}
</Text>
</Box>
<Box shrink="No" alignItems="Center" gap="200">
<Chip
variant="Primary"
onClick={handleDownload}
radii="300"
before={<Icon size="50" src={Icons.Download} />}
>
<Text size="B300">Download</Text>
</Chip>
</Box>
</Header>
<Box
grow="Yes"
className={css.VideoViewerContent}
justifyContent="Center"
alignItems="Center"
>
<video
className={css.VideoViewerVideo}
src={src}
title={alt}
controls
autoPlay
/>
</Box>
</Box>
);
}
);