github.com/minio/console@v1.4.1/web-app/src/screens/Console/Buckets/ListBuckets/Objects/Preview/PreviewFileContent.tsx (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2021 MinIO, Inc.
     3  //
     4  // This program is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Affero General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // This program is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  // GNU Affero General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Affero General Public License
    15  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16  
    17  import React, { Fragment, useCallback, useEffect, useState } from "react";
    18  import { ProgressBar, Grid, Box, InformativeMessage } from "mds";
    19  import get from "lodash/get";
    20  import { AllowedPreviews, previewObjectType } from "../utils";
    21  import { encodeURLString } from "../../../../../../common/utils";
    22  import { api } from "../../../../../../api";
    23  import PreviewPDF from "./PreviewPDF";
    24  import { downloadObject } from "../../../../ObjectBrowser/utils";
    25  import { useAppDispatch } from "../../../../../../store";
    26  import { BucketObject } from "../../../../../../api/consoleApi";
    27  
    28  interface IPreviewFileProps {
    29    bucketName: string;
    30    actualInfo: BucketObject;
    31    isFullscreen?: boolean;
    32  }
    33  
    34  const PreviewFile = ({
    35    bucketName,
    36    actualInfo,
    37    isFullscreen = false,
    38  }: IPreviewFileProps) => {
    39    const dispatch = useAppDispatch();
    40  
    41    const [loading, setLoading] = useState<boolean>(true);
    42  
    43    const [metaData, setMetaData] = useState<any>(null);
    44    const [isMetaDataLoaded, setIsMetaDataLoaded] = useState(false);
    45  
    46    const objectName = actualInfo?.name || "";
    47  
    48    const fetchMetadata = useCallback(() => {
    49      if (!isMetaDataLoaded) {
    50        const encodedPath = encodeURLString(objectName);
    51        api.buckets
    52          .getObjectMetadata(bucketName, {
    53            prefix: encodedPath,
    54            versionID: actualInfo.version_id || "",
    55          })
    56          .then((res) => {
    57            let metadata = get(res.data, "objectMetadata", {});
    58            setIsMetaDataLoaded(true);
    59            setMetaData(metadata);
    60          })
    61          .catch((err) => {
    62            console.error(
    63              "Error Getting Metadata Status: ",
    64              err,
    65              err?.detailedError,
    66            );
    67            setIsMetaDataLoaded(true);
    68          });
    69      }
    70    }, [bucketName, objectName, isMetaDataLoaded, actualInfo.version_id]);
    71  
    72    useEffect(() => {
    73      if (bucketName && objectName) {
    74        fetchMetadata();
    75      }
    76    }, [bucketName, objectName, fetchMetadata]);
    77  
    78    let path = "";
    79  
    80    if (actualInfo) {
    81      const encodedPath = encodeURLString(actualInfo.name || "");
    82      let basename = document.baseURI.replace(window.location.origin, "");
    83      path = `${window.location.origin}${basename}api/v1/buckets/${bucketName}/objects/download?preview=true&prefix=${encodedPath}`;
    84      if (actualInfo.version_id) {
    85        path = path.concat(`&version_id=${actualInfo.version_id}`);
    86      }
    87    }
    88  
    89    let objectType: AllowedPreviews = previewObjectType(metaData, objectName);
    90  
    91    const iframeLoaded = () => {
    92      setLoading(false);
    93    };
    94  
    95    return (
    96      <Fragment>
    97        {objectType !== "none" && loading && (
    98          <Grid item xs={12}>
    99            <ProgressBar />
   100          </Grid>
   101        )}
   102        {isMetaDataLoaded ? (
   103          <Box
   104            sx={{
   105              textAlign: "center",
   106              "& .iframeContainer": {
   107                border: "0px",
   108                flex: "1 1 auto",
   109                width: "100%",
   110                height: 250,
   111                backgroundColor: "transparent",
   112                borderRadius: 5,
   113  
   114                "&.image": {
   115                  height: 500,
   116                },
   117                "&.audio": {
   118                  height: 150,
   119                },
   120                "&.video": {
   121                  height: 350,
   122                },
   123                "&.fullHeight": {
   124                  height: "calc(100vh - 185px)",
   125                },
   126              },
   127              "& .iframeBase": {
   128                backgroundColor: "#fff",
   129              },
   130              "& .iframeHidden": {
   131                display: "none",
   132              },
   133            }}
   134          >
   135            {objectType === "video" && (
   136              <video
   137                style={{
   138                  width: "auto",
   139                  height: "auto",
   140                  maxWidth: "calc(100vw - 100px)",
   141                  maxHeight: "calc(100vh - 200px)",
   142                }}
   143                autoPlay={true}
   144                controls={true}
   145                muted={false}
   146                playsInline={true}
   147                onPlay={iframeLoaded}
   148              >
   149                <source src={path} type="video/mp4" />
   150              </video>
   151            )}
   152            {objectType === "audio" && (
   153              <audio
   154                style={{
   155                  width: "100%",
   156                  height: "auto",
   157                }}
   158                autoPlay={true}
   159                controls={true}
   160                muted={false}
   161                playsInline={true}
   162                onPlay={iframeLoaded}
   163              >
   164                <source src={path} type="audio/mpeg" />
   165              </audio>
   166            )}
   167            {objectType === "image" && (
   168              <img
   169                style={{
   170                  width: "auto",
   171                  height: "auto",
   172                  maxWidth: "100vw",
   173                  maxHeight: "100vh",
   174                }}
   175                src={path}
   176                alt={"preview"}
   177                onLoad={iframeLoaded}
   178              />
   179            )}
   180            {objectType === "pdf" && (
   181              <Fragment>
   182                <PreviewPDF
   183                  path={path}
   184                  onLoad={iframeLoaded}
   185                  loading={loading}
   186                  downloadFile={() =>
   187                    downloadObject(dispatch, bucketName, path, actualInfo)
   188                  }
   189                />
   190              </Fragment>
   191            )}
   192            {objectType === "none" && (
   193              <div>
   194                <InformativeMessage
   195                  message=" File couldn't be previewed using file extension or mime type. Please
   196              try Download instead"
   197                  title="Preview unavailable"
   198                  sx={{ margin: "15px 0" }}
   199                />
   200              </div>
   201            )}
   202            {objectType !== "none" &&
   203              objectType !== "video" &&
   204              objectType !== "audio" &&
   205              objectType !== "image" &&
   206              objectType !== "pdf" && (
   207                <div className={`iframeBase ${loading ? "iframeHidden" : ""}`}>
   208                  <iframe
   209                    src={path}
   210                    title="File Preview"
   211                    allowTransparency
   212                    className={`iframeContainer ${
   213                      isFullscreen ? "fullHeight" : objectType
   214                    }`}
   215                    onLoad={iframeLoaded}
   216                  >
   217                    File couldn't be loaded. Please try Download instead
   218                  </iframe>
   219                </div>
   220              )}
   221          </Box>
   222        ) : null}
   223      </Fragment>
   224    );
   225  };
   226  export default PreviewFile;