github.com/minio/console@v1.3.0/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          })
    55          .then((res) => {
    56            let metadata = get(res.data, "objectMetadata", {});
    57            setIsMetaDataLoaded(true);
    58            setMetaData(metadata);
    59          })
    60          .catch((err) => {
    61            console.error(
    62              "Error Getting Metadata Status: ",
    63              err,
    64              err?.detailedError,
    65            );
    66            setIsMetaDataLoaded(true);
    67          });
    68      }
    69    }, [bucketName, objectName, isMetaDataLoaded]);
    70  
    71    useEffect(() => {
    72      if (bucketName && objectName) {
    73        fetchMetadata();
    74      }
    75    }, [bucketName, objectName, fetchMetadata]);
    76  
    77    let path = "";
    78  
    79    if (actualInfo) {
    80      const encodedPath = encodeURLString(actualInfo.name || "");
    81      let basename = document.baseURI.replace(window.location.origin, "");
    82      path = `${window.location.origin}${basename}api/v1/buckets/${bucketName}/objects/download?preview=true&prefix=${encodedPath}`;
    83      if (actualInfo.version_id) {
    84        path = path.concat(`&version_id=${actualInfo.version_id}`);
    85      }
    86    }
    87  
    88    let objectType: AllowedPreviews = previewObjectType(metaData, objectName);
    89  
    90    const iframeLoaded = () => {
    91      setLoading(false);
    92    };
    93  
    94    return (
    95      <Fragment>
    96        {objectType !== "none" && loading && (
    97          <Grid item xs={12}>
    98            <ProgressBar />
    99          </Grid>
   100        )}
   101        {isMetaDataLoaded ? (
   102          <Box
   103            sx={{
   104              textAlign: "center",
   105              "& .iframeContainer": {
   106                border: "0px",
   107                flex: "1 1 auto",
   108                width: "100%",
   109                height: 250,
   110                backgroundColor: "transparent",
   111                borderRadius: 5,
   112  
   113                "&.image": {
   114                  height: 500,
   115                },
   116                "&.audio": {
   117                  height: 150,
   118                },
   119                "&.video": {
   120                  height: 350,
   121                },
   122                "&.fullHeight": {
   123                  height: "calc(100vh - 185px)",
   124                },
   125              },
   126              "& .iframeBase": {
   127                backgroundColor: "#fff",
   128              },
   129              "& .iframeHidden": {
   130                display: "none",
   131              },
   132            }}
   133          >
   134            {objectType === "video" && (
   135              <video
   136                style={{
   137                  width: "auto",
   138                  height: "auto",
   139                  maxWidth: "calc(100vw - 100px)",
   140                  maxHeight: "calc(100vh - 200px)",
   141                }}
   142                autoPlay={true}
   143                controls={true}
   144                muted={false}
   145                playsInline={true}
   146                onPlay={iframeLoaded}
   147              >
   148                <source src={path} type="video/mp4" />
   149              </video>
   150            )}
   151            {objectType === "audio" && (
   152              <audio
   153                style={{
   154                  width: "100%",
   155                  height: "auto",
   156                }}
   157                autoPlay={true}
   158                controls={true}
   159                muted={false}
   160                playsInline={true}
   161                onPlay={iframeLoaded}
   162              >
   163                <source src={path} type="audio/mpeg" />
   164              </audio>
   165            )}
   166            {objectType === "image" && (
   167              <img
   168                style={{
   169                  width: "auto",
   170                  height: "auto",
   171                  maxWidth: "100vw",
   172                  maxHeight: "100vh",
   173                }}
   174                src={path}
   175                alt={"preview"}
   176                onLoad={iframeLoaded}
   177              />
   178            )}
   179            {objectType === "pdf" && (
   180              <Fragment>
   181                <PreviewPDF
   182                  path={path}
   183                  onLoad={iframeLoaded}
   184                  loading={loading}
   185                  downloadFile={() =>
   186                    downloadObject(dispatch, bucketName, path, actualInfo)
   187                  }
   188                />
   189              </Fragment>
   190            )}
   191            {objectType === "none" && (
   192              <div>
   193                <InformativeMessage
   194                  message=" File couldn't be previewed using file extension or mime type. Please
   195              try Download instead"
   196                  title="Preview unavailable"
   197                  sx={{ margin: "15px 0" }}
   198                />
   199              </div>
   200            )}
   201            {objectType !== "none" &&
   202              objectType !== "video" &&
   203              objectType !== "audio" &&
   204              objectType !== "image" &&
   205              objectType !== "pdf" && (
   206                <div className={`iframeBase ${loading ? "iframeHidden" : ""}`}>
   207                  <iframe
   208                    src={path}
   209                    title="File Preview"
   210                    allowTransparency
   211                    className={`iframeContainer ${
   212                      isFullscreen ? "fullHeight" : objectType
   213                    }`}
   214                    onLoad={iframeLoaded}
   215                  >
   216                    File couldn't be loaded. Please try Download instead
   217                  </iframe>
   218                </div>
   219              )}
   220          </Box>
   221        ) : null}
   222      </Fragment>
   223    );
   224  };
   225  export default PreviewFile;