From 9040d21a9f6c66e2494c121dde2a92a9eb5d5554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladan=20Tomi=C4=87?= Date: Tue, 19 Sep 2023 15:25:48 +0200 Subject: [PATCH 1/3] feat: new file preview --- src/components/FilePreview/FilePreview.tsx | 124 +++++++++++++++--- .../PreviewFileModal/PreviewFileModal.tsx | 15 +-- 2 files changed, 109 insertions(+), 30 deletions(-) diff --git a/src/components/FilePreview/FilePreview.tsx b/src/components/FilePreview/FilePreview.tsx index 4e8c9c27..6aa75224 100644 --- a/src/components/FilePreview/FilePreview.tsx +++ b/src/components/FilePreview/FilePreview.tsx @@ -2,7 +2,7 @@ import { Button } from '@components/Buttons'; import ConsentViewer from '@components/ConsentViewer/ConsentViewer'; import { useLocales } from '@context/LocalesContext'; import { FileItem } from '@fairdatasociety/fdp-storage'; -import { FC } from 'react'; +import { FC, useEffect, useState } from 'react'; interface FilePreviewProps { file: FileItem; @@ -13,6 +13,26 @@ interface FilePreviewProps { onError: () => void; } +enum PreviewType { + Consent, + Text, + Video, + Image, + Unknown, +} + +const TEXT_FILE_EXTENSIONS = [ + '.txt', + '.srt', + '.log', + '.csv', + '.sub', + '.md', + '.json', +]; + +const IMAGE_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.svg', '.gif', '.bmp']; + const VIDEO_FILE_EXTENSIONS = [ '.mpg', '.mp2', @@ -36,6 +56,23 @@ function isString(data: unknown): boolean { return typeof data === 'string'; } +function checkFileExtension(fileName: string, extensions: string[]): boolean { + const lowercaseFileName = fileName.toLowerCase(); + return extensions.some((extension) => lowercaseFileName.endsWith(extension)); +} + +function isTextFile(fileName: string): boolean { + return checkFileExtension(fileName, TEXT_FILE_EXTENSIONS); +} + +function isFileImage(fileName: string): boolean { + return checkFileExtension(fileName, IMAGE_FILE_EXTENSIONS); +} + +function isFileVideo(fileName: string): boolean { + return checkFileExtension(fileName, VIDEO_FILE_EXTENSIONS); +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any function isFileConsent(data: any): boolean { return ( @@ -54,13 +91,6 @@ function isFileConsent(data: any): boolean { ); } -function isFileVideo(fileName: string): boolean { - const lowercaseFileName = fileName.toLowerCase(); - return VIDEO_FILE_EXTENSIONS.some((extension) => - lowercaseFileName.endsWith(extension) - ); -} - const FilePreview: FC = ({ file, pod, @@ -69,12 +99,56 @@ const FilePreview: FC = ({ onError, }) => { const { intl } = useLocales(); + const [type, setType] = useState(null); + const [content, setContent] = useState(source); - if (isFileConsent(source)) { + const preparePreview = async () => { + try { + const fileName = file.name; + + if (isFileVideo(fileName)) { + setContent(window.URL.createObjectURL(source)); + return setType(PreviewType.Video); + } + + if (isFileImage(fileName)) { + setContent(window.URL.createObjectURL(source)); + return setType(PreviewType.Image); + } + + if (isTextFile(fileName)) { + const text = await source.text(); + + if (fileName.endsWith('.json')) { + const json = JSON.parse(text); + + if (isFileConsent(json)) { + setType(PreviewType.Consent); + return setContent(json); + } + } + + setContent(text); + return setType(PreviewType.Text); + } + + throw new Error('Unknown type'); + } catch (error) { + setType(PreviewType.Unknown); + + onError(); + } + }; + + useEffect(() => { + preparePreview(); + }, [file, source]); + + if (type === PreviewType.Consent) { return ( <>
- +
{(!directory || !directory.includes('/')) && (
@@ -97,22 +171,32 @@ const FilePreview: FC = ({ ); } - if (isFileVideo(file.name || '')) { + if (type === PreviewType.Text) { + return ( +

{content}

+ ); + } + + if (type === PreviewType.Video) { return ( ); } - return ( - Preview Image - ); + if (type === PreviewType.Image) { + return ( + Preview Image + ); + } + + return null; }; export default FilePreview; diff --git a/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx b/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx index 828a967c..dd5bdd94 100644 --- a/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx +++ b/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx @@ -54,7 +54,7 @@ const PreviewFileModal: FC = ({ const { activePod, directoryName } = useContext(PodContext); const [loading, setLoading] = useState(false); - const [imageSource, setImageSource] = useState(''); + const [fileContent, setFileContent] = useState(null); const [errorMessage, setErrorMessage] = useState(''); const [showShareFileModal, setShowShareFileModal] = useState(false); const [showConfirmDeleteModal, setShowConfirmDeleteModal] = useState(false); @@ -71,12 +71,7 @@ const PreviewFileModal: FC = ({ const blob = await response.arrayBuffer(); const content = new Blob([blob]); - if (previewFile?.name.endsWith('.json')) { - const json = await content.text(); - return setImageSource(JSON.parse(json)); - } - - setImageSource(window.URL.createObjectURL(content)); + setFileContent(content); }) .catch((e) => { setErrorMessage(intl.get('FILE_PREVIEW_ERROR')); @@ -152,16 +147,16 @@ const PreviewFileModal: FC = ({ headerTitle={intl.get('PREVIEW_FILE')} className="w-full md:w-98" > - {imageSource ? ( + {fileContent ? ( setErrorMessage(intl.get('FILE_PREVIEW_ERROR'))} /> ) : null} - + {errorMessage ? (
From 48ff9adb3312a98c557773178275cf9070d99cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladan=20Tomi=C4=87?= Date: Wed, 20 Sep 2023 10:33:32 +0200 Subject: [PATCH 2/3] fix: file preview --- src/components/FilePreview/FilePreview.tsx | 11 ++++++++++- .../Modals/PreviewFileModal/PreviewFileModal.tsx | 9 ++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/components/FilePreview/FilePreview.tsx b/src/components/FilePreview/FilePreview.tsx index 6aa75224..470ead03 100644 --- a/src/components/FilePreview/FilePreview.tsx +++ b/src/components/FilePreview/FilePreview.tsx @@ -13,6 +13,8 @@ interface FilePreviewProps { onError: () => void; } +const MAX_TEXT_PREVIEW_LENGTH = 500; + enum PreviewType { Consent, Text, @@ -52,6 +54,10 @@ const VIDEO_FILE_EXTENSIONS = [ '.swf', ]; +export function isFilePreviewSupported(fileName: string): boolean { + return isTextFile(fileName) || isFileImage(fileName) || isFileVideo(fileName); +} + function isString(data: unknown): boolean { return typeof data === 'string'; } @@ -128,7 +134,10 @@ const FilePreview: FC = ({ } } - setContent(text); + setContent( + text.substring(0, MAX_TEXT_PREVIEW_LENGTH) + + (text.length > MAX_TEXT_PREVIEW_LENGTH ? '...' : '') + ); return setType(PreviewType.Text); } diff --git a/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx b/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx index dd5bdd94..926c961f 100644 --- a/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx +++ b/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx @@ -30,7 +30,9 @@ import ShareDarkIcon from '@media/UI/share-dark.svg'; import DeleteLightIcon from '@media/UI/delete-light.svg'; import DeleteDarkIcon from '@media/UI/delete-dark.svg'; import Spinner from '@components/Spinner/Spinner'; -import FilePreview from '@components/FilePreview/FilePreview'; +import FilePreview, { + isFilePreviewSupported, +} from '@components/FilePreview/FilePreview'; import { FileItem } from '@fairdatasociety/fdp-storage'; import { extractFileExtension } from '@utils/filename'; import { useLocales } from '@context/LocalesContext'; @@ -61,6 +63,11 @@ const PreviewFileModal: FC = ({ const { intl } = useLocales(); useEffect(() => { + if (!isFilePreviewSupported(previewFile?.name)) { + setErrorMessage(intl.get('FILE_PREVIEW_ERROR')); + return; + } + setLoading(true); downloadFile(fdpClientRef.current, { filename: previewFile?.name, From 6cef18c378fcfc4dfa8b6cd9e9d4938c8edcc8b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladan=20Tomi=C4=87?= Date: Wed, 20 Sep 2023 13:15:46 +0200 Subject: [PATCH 3/3] fix: file preview --- src/components/Modals/PreviewFileModal/PreviewFileModal.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx b/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx index 926c961f..2d6b64f3 100644 --- a/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx +++ b/src/components/Modals/PreviewFileModal/PreviewFileModal.tsx @@ -64,7 +64,6 @@ const PreviewFileModal: FC = ({ useEffect(() => { if (!isFilePreviewSupported(previewFile?.name)) { - setErrorMessage(intl.get('FILE_PREVIEW_ERROR')); return; } @@ -171,7 +170,7 @@ const PreviewFileModal: FC = ({
) : null} -

+

{previewFile?.name}