2024-02-05 16:11:49 +01:00
|
|
|
import {
|
|
|
|
Button,
|
|
|
|
Center,
|
|
|
|
Stack,
|
|
|
|
Text,
|
|
|
|
Title,
|
|
|
|
useMantineTheme,
|
|
|
|
} from "@mantine/core";
|
2023-03-14 12:09:21 +01:00
|
|
|
import { modals } from "@mantine/modals";
|
|
|
|
import Link from "next/link";
|
|
|
|
import React, { Dispatch, SetStateAction, useEffect, useState } from "react";
|
2023-07-20 15:32:07 +02:00
|
|
|
import { FormattedMessage } from "react-intl";
|
2023-03-14 16:08:57 +01:00
|
|
|
import api from "../../services/api.service";
|
2024-02-04 18:50:43 +01:00
|
|
|
import Markdown from "markdown-to-jsx";
|
2023-03-14 12:09:21 +01:00
|
|
|
|
|
|
|
const FilePreviewContext = React.createContext<{
|
|
|
|
shareId: string;
|
|
|
|
fileId: string;
|
|
|
|
mimeType: string;
|
|
|
|
setIsNotSupported: Dispatch<SetStateAction<boolean>>;
|
|
|
|
}>({
|
|
|
|
shareId: "",
|
|
|
|
fileId: "",
|
|
|
|
mimeType: "",
|
|
|
|
setIsNotSupported: () => {},
|
|
|
|
});
|
|
|
|
|
|
|
|
const FilePreview = ({
|
|
|
|
shareId,
|
|
|
|
fileId,
|
|
|
|
mimeType,
|
|
|
|
}: {
|
|
|
|
shareId: string;
|
|
|
|
fileId: string;
|
|
|
|
mimeType: string;
|
|
|
|
}) => {
|
|
|
|
const [isNotSupported, setIsNotSupported] = useState(false);
|
|
|
|
if (isNotSupported) return <UnSupportedFile />;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Stack>
|
|
|
|
<FilePreviewContext.Provider
|
|
|
|
value={{ shareId, fileId, mimeType, setIsNotSupported }}
|
|
|
|
>
|
|
|
|
<FileDecider />
|
|
|
|
</FilePreviewContext.Provider>
|
|
|
|
<Button
|
|
|
|
variant="subtle"
|
|
|
|
component={Link}
|
|
|
|
onClick={() => modals.closeAll()}
|
|
|
|
target="_blank"
|
|
|
|
href={`/api/shares/${shareId}/files/${fileId}?download=false`}
|
|
|
|
>
|
|
|
|
View original file
|
2023-08-17 14:54:26 +02:00
|
|
|
{/* Add translation? */}
|
2023-03-14 12:09:21 +01:00
|
|
|
</Button>
|
|
|
|
</Stack>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const FileDecider = () => {
|
|
|
|
const { mimeType, setIsNotSupported } = React.useContext(FilePreviewContext);
|
|
|
|
|
|
|
|
if (mimeType == "application/pdf") {
|
|
|
|
return <PdfPreview />;
|
|
|
|
} else if (mimeType.startsWith("video/")) {
|
|
|
|
return <VideoPreview />;
|
|
|
|
} else if (mimeType.startsWith("image/")) {
|
|
|
|
return <ImagePreview />;
|
|
|
|
} else if (mimeType.startsWith("audio/")) {
|
|
|
|
return <AudioPreview />;
|
2023-03-14 16:08:57 +01:00
|
|
|
} else if (mimeType.startsWith("text/")) {
|
2023-03-14 12:09:21 +01:00
|
|
|
return <TextPreview />;
|
|
|
|
} else {
|
|
|
|
setIsNotSupported(true);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const AudioPreview = () => {
|
|
|
|
const { shareId, fileId, setIsNotSupported } =
|
|
|
|
React.useContext(FilePreviewContext);
|
|
|
|
return (
|
|
|
|
<Center style={{ minHeight: 200 }}>
|
|
|
|
<Stack align="center" spacing={10} style={{ width: "100%" }}>
|
|
|
|
<audio controls style={{ width: "100%" }}>
|
|
|
|
<source
|
|
|
|
src={`/api/shares/${shareId}/files/${fileId}?download=false`}
|
|
|
|
onError={() => setIsNotSupported(true)}
|
|
|
|
/>
|
|
|
|
</audio>
|
|
|
|
</Stack>
|
|
|
|
</Center>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const VideoPreview = () => {
|
|
|
|
const { shareId, fileId, setIsNotSupported } =
|
|
|
|
React.useContext(FilePreviewContext);
|
|
|
|
return (
|
|
|
|
<video width="100%" controls>
|
|
|
|
<source
|
|
|
|
src={`/api/shares/${shareId}/files/${fileId}?download=false`}
|
|
|
|
onError={() => setIsNotSupported(true)}
|
|
|
|
/>
|
|
|
|
</video>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const ImagePreview = () => {
|
|
|
|
const { shareId, fileId, setIsNotSupported } =
|
|
|
|
React.useContext(FilePreviewContext);
|
|
|
|
return (
|
|
|
|
// eslint-disable-next-line @next/next/no-img-element
|
|
|
|
<img
|
|
|
|
src={`/api/shares/${shareId}/files/${fileId}?download=false`}
|
|
|
|
alt={`${fileId}_preview`}
|
|
|
|
width="100%"
|
|
|
|
onError={() => setIsNotSupported(true)}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const TextPreview = () => {
|
|
|
|
const { shareId, fileId } = React.useContext(FilePreviewContext);
|
2024-02-05 16:11:49 +01:00
|
|
|
const [text, setText] = useState<string>("");
|
2024-02-04 18:50:43 +01:00
|
|
|
const { colorScheme } = useMantineTheme();
|
2023-03-14 12:09:21 +01:00
|
|
|
|
|
|
|
useEffect(() => {
|
2023-05-09 08:45:30 +02:00
|
|
|
api
|
|
|
|
.get(`/shares/${shareId}/files/${fileId}?download=false`)
|
2024-02-04 18:50:43 +01:00
|
|
|
.then((res) => setText(res.data ?? "Preview couldn't be fetched."));
|
2024-02-05 16:11:49 +01:00
|
|
|
}, [shareId, fileId]);
|
2024-02-04 18:50:43 +01:00
|
|
|
|
|
|
|
const options = {
|
|
|
|
overrides: {
|
|
|
|
pre: {
|
|
|
|
props: {
|
|
|
|
style: {
|
2024-02-05 16:11:49 +01:00
|
|
|
backgroundColor:
|
|
|
|
colorScheme == "dark"
|
|
|
|
? "rgba(50, 50, 50, 0.5)"
|
|
|
|
: "rgba(220, 220, 220, 0.5)",
|
2024-02-04 18:50:43 +01:00
|
|
|
padding: "0.75em",
|
|
|
|
whiteSpace: "pre-wrap",
|
2024-02-05 16:11:49 +01:00
|
|
|
},
|
|
|
|
},
|
2024-02-04 18:50:43 +01:00
|
|
|
},
|
|
|
|
table: {
|
|
|
|
props: {
|
2024-02-05 16:11:49 +01:00
|
|
|
className: "md",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-02-04 18:50:43 +01:00
|
|
|
};
|
2023-03-14 12:09:21 +01:00
|
|
|
|
2024-02-05 16:11:49 +01:00
|
|
|
return <Markdown options={options}>{text}</Markdown>;
|
2023-03-14 12:09:21 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const PdfPreview = () => {
|
|
|
|
const { shareId, fileId } = React.useContext(FilePreviewContext);
|
|
|
|
if (typeof window !== "undefined") {
|
|
|
|
window.location.href = `/api/shares/${shareId}/files/${fileId}?download=false`;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
const UnSupportedFile = () => {
|
|
|
|
return (
|
|
|
|
<Center style={{ minHeight: 200 }}>
|
|
|
|
<Stack align="center" spacing={10}>
|
2023-07-20 15:32:07 +02:00
|
|
|
<Title order={3}>
|
|
|
|
<FormattedMessage id="share.modal.file-preview.error.not-supported.title" />
|
|
|
|
</Title>
|
2023-03-14 12:09:21 +01:00
|
|
|
<Text>
|
2023-07-20 15:32:07 +02:00
|
|
|
<FormattedMessage id="share.modal.file-preview.error.not-supported.description" />
|
2023-03-14 12:09:21 +01:00
|
|
|
</Text>
|
|
|
|
</Stack>
|
|
|
|
</Center>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default FilePreview;
|