Web: Added PDF viewer
This commit is contained in:
parent
266b3c73b5
commit
a42103b2bd
@ -37,7 +37,7 @@ class MediaViewerDataStore {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!file.canOpenPlayer) return;
|
||||
if (!file.canOpenPlayer && !file.fileExst === ".pdf") return;
|
||||
|
||||
this.previewFile = file;
|
||||
this.id = file.id;
|
||||
@ -140,7 +140,9 @@ class MediaViewerDataStore {
|
||||
if (filesList.length > 0) {
|
||||
filesList.forEach((file) => {
|
||||
const canOpenPlayer =
|
||||
file.viewAccessability.ImageView || file.viewAccessability.MediaView;
|
||||
file.viewAccessability.ImageView ||
|
||||
file.viewAccessability.MediaView ||
|
||||
file.fileExst === ".pdf";
|
||||
|
||||
if (canOpenPlayer) {
|
||||
playlist.push({
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
export const mediaTypes = Object.freeze({
|
||||
audio: 1,
|
||||
video: 2,
|
||||
pdf: 3,
|
||||
});
|
||||
|
||||
export enum KeyboardEventKeys {
|
||||
@ -56,6 +57,7 @@ export const mapSupplied = {
|
||||
".avi": { supply: "m4v", type: mediaTypes.video, convertable: true },
|
||||
".mpeg": { supply: "m4v", type: mediaTypes.video, convertable: true },
|
||||
".mpg": { supply: "m4v", type: mediaTypes.video, convertable: true },
|
||||
".pdf": { supply: "pdf", type: mediaTypes.pdf },
|
||||
} as Record<string, { supply: string; type: number } | undefined>;
|
||||
|
||||
export function isVideo(fileExst: string): boolean {
|
||||
|
@ -284,8 +284,9 @@ function MediaViewer({
|
||||
const onDelete = () => {
|
||||
const { playlist, onDelete } = props;
|
||||
|
||||
let currentFileId = playlist.find((file) => file.id === playlistPos)
|
||||
?.fileId;
|
||||
let currentFileId = playlist.find(
|
||||
(file) => file.id === playlistPos
|
||||
)?.fileId;
|
||||
|
||||
if (currentFileId === lastRemovedFileId) return;
|
||||
|
||||
@ -302,8 +303,9 @@ function MediaViewer({
|
||||
const onDownload = () => {
|
||||
const { playlist, onDownload } = props;
|
||||
|
||||
let currentFileId = playlist.find((file) => file.id === playlistPos)
|
||||
?.fileId;
|
||||
let currentFileId = playlist.find(
|
||||
(file) => file.id === playlistPos
|
||||
)?.fileId;
|
||||
|
||||
if (!isNullOrUndefined(currentFileId)) onDownload(currentFileId);
|
||||
};
|
||||
@ -394,6 +396,7 @@ function MediaViewer({
|
||||
let isAudio = false;
|
||||
let canOpen = true;
|
||||
let isImage = false;
|
||||
let isPdf = false;
|
||||
|
||||
const archiveRoom =
|
||||
props.archiveRoomsId === targetFile?.rootFolderId ||
|
||||
@ -408,12 +411,16 @@ function MediaViewer({
|
||||
isImage = true;
|
||||
} else {
|
||||
isImage = false;
|
||||
|
||||
isVideo = mapSupplied[ext]
|
||||
? mapSupplied[ext]?.type == mediaTypes.video
|
||||
: false;
|
||||
|
||||
isAudio = mapSupplied[ext]
|
||||
? mapSupplied[ext]?.type == mediaTypes.audio
|
||||
: false;
|
||||
|
||||
isPdf = mapSupplied[ext] ? mapSupplied[ext]?.type == mediaTypes.pdf : false;
|
||||
}
|
||||
|
||||
return (
|
||||
@ -437,6 +444,7 @@ function MediaViewer({
|
||||
isImage={isImage}
|
||||
isAudio={isAudio}
|
||||
isVideo={isVideo}
|
||||
isPdf={isPdf}
|
||||
isPreviewFile={props.isPreviewFile}
|
||||
onDownloadClick={onDownload}
|
||||
archiveRoom={archiveRoom}
|
||||
|
@ -0,0 +1,5 @@
|
||||
interface PDFViewerProps {
|
||||
src: string;
|
||||
}
|
||||
|
||||
export default PDFViewerProps;
|
@ -0,0 +1,164 @@
|
||||
import React, { useEffect, useLayoutEffect, useState, useRef } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { loadScript, combineUrl } from "@docspace/common/utils";
|
||||
|
||||
import PDFViewerProps from "./PDFViewer.props";
|
||||
import ViewerLoader from "../ViewerLoader";
|
||||
|
||||
import "./lib/AllFonts.js";
|
||||
|
||||
import "./lib/device_scale.js";
|
||||
import "./lib/browser.js";
|
||||
import "./lib/stringserialize.js";
|
||||
import "./lib/skin.js";
|
||||
|
||||
import "./lib/font/loader.js";
|
||||
import "./lib/font/map.js";
|
||||
import "./lib/font/character.js";
|
||||
|
||||
import "./lib/SerializeCommonWordExcel.js";
|
||||
import "./lib/Externals.js";
|
||||
import "./lib/GlobalLoaders.js";
|
||||
import "./lib/scroll.js";
|
||||
import "./lib/WorkEvents.js";
|
||||
import "./lib/Overlay.js";
|
||||
|
||||
// import "./lib/bookmarks.js";
|
||||
|
||||
import "./lib/file.js";
|
||||
import "./lib/api.js";
|
||||
|
||||
const pdfViewerId = "pdf-viewer";
|
||||
|
||||
const PdfViewrWrapper = styled.div`
|
||||
position: fixed;
|
||||
z-index: 305;
|
||||
|
||||
inset: 0;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
#mainPanel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.block_elem {
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const ErrorMessage = styled.p`
|
||||
padding: 20px 30px;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
`;
|
||||
function PDFViewer({ src }: PDFViewerProps) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [file, setFile] = useState<ArrayBuffer | string | null>();
|
||||
|
||||
const [isError, setIsError] = useState<boolean>(false);
|
||||
|
||||
const [isLoadedViewerScript, setIsLoadedViewerScript] = useState<boolean>(
|
||||
() => {
|
||||
const result = document.getElementById(pdfViewerId);
|
||||
return result !== null;
|
||||
}
|
||||
);
|
||||
|
||||
const [isLoadingScript, setIsLoadingScript] = useState<boolean>(false);
|
||||
const [isLoadingFile, setIsLoadingFile] = useState<boolean>(false);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const origin = window.location.origin;
|
||||
const path = window.DocSpaceConfig.pdfViewerUrl;
|
||||
|
||||
if (!isLoadedViewerScript) {
|
||||
setIsLoadingScript(true);
|
||||
loadScript(
|
||||
combineUrl(origin, path),
|
||||
pdfViewerId,
|
||||
() => {
|
||||
//@ts-ignore
|
||||
window.Viewer = new window.AscViewer.CViewer("mainPanel", {});
|
||||
setIsLoadedViewerScript(true);
|
||||
setIsLoadingScript(false);
|
||||
},
|
||||
(event) => {
|
||||
setIsLoadingScript(false);
|
||||
setIsError(true);
|
||||
console.error(event);
|
||||
}
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoadingFile(true);
|
||||
fetch(src)
|
||||
.then((value) => {
|
||||
return value.blob();
|
||||
})
|
||||
.then((value) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
setFile(e.target?.result);
|
||||
};
|
||||
reader.readAsArrayBuffer(value);
|
||||
})
|
||||
.catch((event) => {
|
||||
setIsError(true);
|
||||
console.error(event);
|
||||
})
|
||||
.finally(() => {
|
||||
setIsLoadingFile(false);
|
||||
});
|
||||
}, [src]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoadedViewerScript && !isLoadingFile && file) {
|
||||
try {
|
||||
if (!containerRef.current?.hasChildNodes()) {
|
||||
//@ts-ignore
|
||||
window.Viewer = new window.AscViewer.CViewer("mainPanel", {});
|
||||
}
|
||||
//@ts-ignore
|
||||
window.Viewer.open(file);
|
||||
} catch (error) {
|
||||
setIsError(true);
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}, [file, isLoadedViewerScript, isLoadingFile]);
|
||||
|
||||
if (isError) {
|
||||
return (
|
||||
<PdfViewrWrapper>
|
||||
<ErrorMessage>Something went wrong</ErrorMessage>
|
||||
</PdfViewrWrapper>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<PdfViewrWrapper>
|
||||
<ViewerLoader isLoading={isLoadingFile || isLoadingScript} />
|
||||
<div
|
||||
ref={containerRef}
|
||||
style={{
|
||||
visibility: isLoadingFile || isLoadingScript ? "hidden" : "visible",
|
||||
}}
|
||||
id="mainPanel"
|
||||
></div>
|
||||
</PdfViewrWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default PDFViewer;
|
@ -8,6 +8,7 @@ interface ViewerProps {
|
||||
isVideo: boolean;
|
||||
visible: boolean;
|
||||
isImage: boolean;
|
||||
isPdf: boolean;
|
||||
|
||||
playlist: PlaylistType[];
|
||||
inactive: boolean;
|
||||
|
@ -14,6 +14,7 @@ import DesktopDetails from "../DesktopDetails";
|
||||
import ViewerPlayer from "../ViewerPlayer";
|
||||
|
||||
import type ViewerProps from "./Viewer.props";
|
||||
import PDFViewer from "../PDFViewer";
|
||||
|
||||
function Viewer(props: ViewerProps) {
|
||||
const timerIDRef = useRef<NodeJS.Timeout>();
|
||||
@ -197,8 +198,8 @@ function Viewer(props: ViewerProps) {
|
||||
/>,
|
||||
containerRef.current
|
||||
)
|
||||
: (props.isVideo || props.isAudio) &&
|
||||
ReactDOM.createPortal(
|
||||
: props.isVideo || props.isAudio
|
||||
? ReactDOM.createPortal(
|
||||
<ViewerPlayer
|
||||
isError={isError}
|
||||
src={props.fileUrl}
|
||||
@ -228,6 +229,11 @@ function Viewer(props: ViewerProps) {
|
||||
restartToolbarVisibleTimer={restartToolbarVisibleTimer}
|
||||
/>,
|
||||
containerRef.current
|
||||
)
|
||||
: props.isPdf &&
|
||||
ReactDOM.createPortal(
|
||||
<PDFViewer src={props.fileUrl ?? ""} />,
|
||||
containerRef.current
|
||||
)}
|
||||
</StyledViewerContainer>
|
||||
);
|
||||
|
@ -13,6 +13,7 @@ interface ViewerWrapperProps {
|
||||
isImage: boolean;
|
||||
isAudio: boolean;
|
||||
isVideo: boolean;
|
||||
isPdf: boolean;
|
||||
isPreviewFile: boolean;
|
||||
|
||||
archiveRoom: boolean;
|
||||
|
@ -86,6 +86,7 @@ function ViewerWrapper(props: ViewerWrapperProps) {
|
||||
fileUrl={props.fileUrl}
|
||||
isAudio={props.isAudio}
|
||||
isVideo={props.isVideo}
|
||||
isPdf={props.isPdf}
|
||||
visible={props.visible}
|
||||
isImage={props.isImage}
|
||||
playlist={props.playlist}
|
||||
|
@ -1,6 +1,7 @@
|
||||
declare global {
|
||||
interface Window {
|
||||
Tiff: new (arg: object) => any;
|
||||
DocSpaceConfig: any;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user