diff --git a/frontend/src/components/share/FileList.tsx b/frontend/src/components/share/FileList.tsx
index b822f6aa..9918c630 100644
--- a/frontend/src/components/share/FileList.tsx
+++ b/frontend/src/components/share/FileList.tsx
@@ -1,5 +1,6 @@
import {
ActionIcon,
+ Box,
Group,
Skeleton,
Stack,
@@ -8,9 +9,6 @@ import {
} from "@mantine/core";
import { useClipboard } from "@mantine/hooks";
import { useModals } from "@mantine/modals";
-import mime from "mime-types";
-
-import Link from "next/link";
import { TbDownload, TbEye, TbLink } from "react-icons/tb";
import useConfig from "../../hooks/config.hook";
import shareService from "../../services/share.service";
@@ -18,6 +16,7 @@ import { FileMetaData } from "../../types/File.type";
import { Share } from "../../types/share.type";
import { byteToHumanSizeString } from "../../utils/fileSize.util";
import toast from "../../utils/toast.util";
+import showFilePreviewModal from "./modals/showFilePreviewModal";
const FileList = ({
files,
@@ -53,54 +52,57 @@ const FileList = ({
};
return (
-
-
-
- Name |
- Size |
- |
-
-
-
- {isLoading
- ? skeletonRows
- : files!.map((file) => (
-
- {file.name} |
- {byteToHumanSizeString(parseInt(file.size))} |
-
-
- {shareService.doesFileSupportPreview(file.name) && (
+
+
+
+
+ Name |
+ Size |
+ |
+
+
+
+ {isLoading
+ ? skeletonRows
+ : files!.map((file) => (
+
+ {file.name} |
+ {byteToHumanSizeString(parseInt(file.size))} |
+
+
+ {shareService.doesFileSupportPreview(file.name) && (
+
+ showFilePreviewModal(share.id, file, modals)
+ }
+ size={25}
+ >
+
+
+ )}
+ {!share.hasPassword && (
+ copyFileLink(file)}
+ >
+
+
+ )}
{
+ await shareService.downloadFile(share.id, file.id);
+ }}
>
-
+
- )}
- {!share.hasPassword && (
- copyFileLink(file)}>
-
-
- )}
- {
- await shareService.downloadFile(share.id, file.id);
- }}
- >
-
-
-
- |
-
- ))}
-
-
+
+ |
+
+ ))}
+
+
+
);
};
diff --git a/frontend/src/components/share/FilePreview.tsx b/frontend/src/components/share/FilePreview.tsx
new file mode 100644
index 00000000..789b8f2c
--- /dev/null
+++ b/frontend/src/components/share/FilePreview.tsx
@@ -0,0 +1,154 @@
+import { Button, Center, Stack, Text, Title } from "@mantine/core";
+import { modals } from "@mantine/modals";
+import Link from "next/link";
+import React, { Dispatch, SetStateAction, useEffect, useState } from "react";
+
+const FilePreviewContext = React.createContext<{
+ shareId: string;
+ fileId: string;
+ mimeType: string;
+ setIsNotSupported: Dispatch>;
+}>({
+ shareId: "",
+ fileId: "",
+ mimeType: "",
+ setIsNotSupported: () => {},
+});
+
+const FilePreview = ({
+ shareId,
+ fileId,
+ mimeType,
+}: {
+ shareId: string;
+ fileId: string;
+ mimeType: string;
+}) => {
+ const [isNotSupported, setIsNotSupported] = useState(false);
+ if (isNotSupported) return ;
+
+ return (
+
+
+
+
+
+
+ );
+};
+
+const FileDecider = () => {
+ const { mimeType, setIsNotSupported } = React.useContext(FilePreviewContext);
+
+ if (mimeType == "application/pdf") {
+ return ;
+ } else if (mimeType.startsWith("video/")) {
+ return ;
+ } else if (mimeType.startsWith("image/")) {
+ return ;
+ } else if (mimeType.startsWith("audio/")) {
+ return ;
+ } else if (mimeType == "text/plain") {
+ return ;
+ } else {
+ setIsNotSupported(true);
+ return null;
+ }
+};
+
+const AudioPreview = () => {
+ const { shareId, fileId, setIsNotSupported } =
+ React.useContext(FilePreviewContext);
+ return (
+
+
+
+
+
+ );
+};
+
+const VideoPreview = () => {
+ const { shareId, fileId, setIsNotSupported } =
+ React.useContext(FilePreviewContext);
+ return (
+
+ );
+};
+
+const ImagePreview = () => {
+ const { shareId, fileId, setIsNotSupported } =
+ React.useContext(FilePreviewContext);
+ return (
+ // eslint-disable-next-line @next/next/no-img-element
+ setIsNotSupported(true)}
+ />
+ );
+};
+
+const TextPreview = () => {
+ const { shareId, fileId } = React.useContext(FilePreviewContext);
+ const [text, setText] = useState(null);
+
+ useEffect(() => {
+ fetch(`/api/shares/${shareId}/files/${fileId}?download=false`)
+ .then((res) => res.text())
+ .then((text) => setText(text));
+ }, [shareId, fileId]);
+
+ return (
+
+
+ {text}
+
+
+ );
+};
+
+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 (
+
+
+ Preview not supported
+
+ A preview for thise file type is unsupported. Please download the file
+ to view it.
+
+
+
+ );
+};
+
+export default FilePreview;
diff --git a/frontend/src/components/share/modals/showFilePreviewModal.tsx b/frontend/src/components/share/modals/showFilePreviewModal.tsx
new file mode 100644
index 00000000..ef5a1c90
--- /dev/null
+++ b/frontend/src/components/share/modals/showFilePreviewModal.tsx
@@ -0,0 +1,21 @@
+import { ModalsContextProps } from "@mantine/modals/lib/context";
+import mime from "mime-types";
+import { FileMetaData } from "../../../types/File.type";
+import FilePreview from "../FilePreview";
+
+const showFilePreviewModal = (
+ shareId: string,
+ file: FileMetaData,
+ modals: ModalsContextProps
+) => {
+ const mimeType = (mime.contentType(file.name) || "").split(";")[0];
+ return modals.openModal({
+ size: "xl",
+ title: file.name,
+ children: (
+
+ ),
+ });
+};
+
+export default showFilePreviewModal;
diff --git a/frontend/src/pages/share/[shareId]/preview/[fileId].tsx b/frontend/src/pages/share/[shareId]/preview/[fileId].tsx
deleted file mode 100644
index 6d6c00b7..00000000
--- a/frontend/src/pages/share/[shareId]/preview/[fileId].tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import { Center, Stack, Text, Title } from "@mantine/core";
-import { GetServerSidePropsContext } from "next";
-import { useState } from "react";
-
-export function getServerSideProps(context: GetServerSidePropsContext) {
- const { shareId, fileId } = context.params!;
-
- const mimeType = context.query.type as string;
-
- return {
- props: { shareId, fileId, mimeType },
- };
-}
-
-const UnSupportedFile = () => {
- return (
-
-
- Preview not supported
-
- A preview for thise file type is unsupported. Please download the file
- to view it.
-
-
-
- );
-};
-
-const FilePreview = ({
- shareId,
- fileId,
- mimeType,
-}: {
- shareId: string;
- fileId: string;
- mimeType: string;
-}) => {
- const [isNotSupported, setIsNotSupported] = useState(false);
-
- if (isNotSupported) return ;
-
- if (mimeType == "application/pdf") {
- if (typeof window !== "undefined") {
- window.location.href = `/api/shares/${shareId}/files/${fileId}?download=false`;
- }
- return null;
- } else if (mimeType.startsWith("video/")) {
- return (
-
- );
- } else if (mimeType.startsWith("image/")) {
- return (
- // eslint-disable-next-line @next/next/no-img-element
- {
- setIsNotSupported(true);
- }}
- src={`/api/shares/${shareId}/files/${fileId}?download=false`}
- alt={`${fileId}_preview`}
- width="100%"
- />
- );
- } else if (mimeType.startsWith("audio/")) {
- return (
-
-
-
-
-
- );
- } else {
- return ;
- }
-};
-
-export default FilePreview;
diff --git a/frontend/src/services/share.service.ts b/frontend/src/services/share.service.ts
index a7454312..0e045a29 100644
--- a/frontend/src/services/share.service.ts
+++ b/frontend/src/services/share.service.ts
@@ -53,7 +53,7 @@ const isShareIdAvailable = async (id: string): Promise => {
};
const doesFileSupportPreview = (fileName: string) => {
- const mimeType = mime.contentType(fileName);
+ const mimeType = (mime.contentType(fileName) || "").split(";")[0];
if (!mimeType) return false;
@@ -61,6 +61,7 @@ const doesFileSupportPreview = (fileName: string) => {
mimeType.startsWith("video/"),
mimeType.startsWith("image/"),
mimeType.startsWith("audio/"),
+ mimeType == "text/plain",
mimeType == "application/pdf",
];