From 19a3fbb5b363c4bc0fe759167b75d02d5a40c40d Mon Sep 17 00:00:00 2001 From: Cheerego7 <48879533+Cheerego7@users.noreply.github.com> Date: Mon, 26 Jul 2021 14:07:37 +0800 Subject: [PATCH] feat(preview): add resource preview to flat-web. (#812) --- web/flat-web/package.json | 2 +- web/flat-web/src/AppRoutes/route-pages.ts | 4 + .../src/pages/CloudStoragePage/store.tsx | 18 +++- .../ResourcePreviewPage/DynamicPreview.less | 40 ++++++++ .../ResourcePreviewPage/DynamicPreview.tsx | 94 +++++++++++++++++++ .../ResourcePreviewPage/MediaPreview.less | 23 +++++ .../ResourcePreviewPage/MediaPreview.tsx | 42 +++++++++ .../ResourcePreviewPage/StaticPreview.less | 11 +++ .../ResourcePreviewPage/StaticPreview.tsx | 61 ++++++++++++ .../ResourcePreviewPage/image/next-step.svg | 13 +++ .../image/previous-step.svg | 13 +++ .../src/pages/ResourcePreviewPage/index.tsx | 50 ++++++++++ .../src/pages/ResourcePreviewPage/utils.ts | 3 + web/flat-web/src/route-config.ts | 4 + yarn.lock | 27 ++++++ 15 files changed, 400 insertions(+), 5 deletions(-) create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/DynamicPreview.less create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/DynamicPreview.tsx create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/MediaPreview.less create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/MediaPreview.tsx create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/StaticPreview.less create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/StaticPreview.tsx create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/image/next-step.svg create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/image/previous-step.svg create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/index.tsx create mode 100644 web/flat-web/src/pages/ResourcePreviewPage/utils.ts diff --git a/web/flat-web/package.json b/web/flat-web/package.json index 46ed9904488..ecf427d63d9 100644 --- a/web/flat-web/package.json +++ b/web/flat-web/package.json @@ -67,7 +67,7 @@ "react-virtualized": "^9.22.3", "uuid": "^8.3.2", "video.js": "7.10.2", - "white-web-sdk": "2.13.11" + "white-web-sdk": "2.13.12" }, "scripts": { "postinstall": "esbuild-dev ./scripts/post-install.ts", diff --git a/web/flat-web/src/AppRoutes/route-pages.ts b/web/flat-web/src/AppRoutes/route-pages.ts index 456091e72d7..6b3b12dd229 100644 --- a/web/flat-web/src/AppRoutes/route-pages.ts +++ b/web/flat-web/src/AppRoutes/route-pages.ts @@ -95,4 +95,8 @@ export const routePages: RoutePages = { title: "JoinPage", component: () => import("../pages/JoinPage"), }, + [RouteNameType.ResourcePreviewPage]: { + title: "ResourcePreviewPage", + component: () => import("../pages/ResourcePreviewPage"), + }, }; diff --git a/web/flat-web/src/pages/CloudStoragePage/store.tsx b/web/flat-web/src/pages/CloudStoragePage/store.tsx index 0e256e77257..b2f817a02c7 100644 --- a/web/flat-web/src/pages/CloudStoragePage/store.tsx +++ b/web/flat-web/src/pages/CloudStoragePage/store.tsx @@ -26,6 +26,7 @@ import { renameFile, } from "../../apiMiddleware/flatServer/storage"; import { errorTips } from "../../components/Tips/ErrorTips"; +import { INVITE_BASEURL } from "../../constants/Process"; import { getUploadTaskManager } from "../../utils/UploadTaskManager"; import { UploadStatusType, UploadTask } from "../../utils/UploadTaskManager/UploadTask"; @@ -357,6 +358,18 @@ export class CloudStorageStore extends CloudStorageStoreBase { } private previewCourseware(file: CloudStorageFile): void { + const { fileURL, taskToken, taskUUID } = file; + + const convertFileTypeList = [".pptx", ".ppt", ".pdf", ".doc", ".docx"]; + + const isConvertFileType = convertFileTypeList.some(type => fileURL.includes(type)); + + const encodeFileURL = encodeURIComponent(fileURL); + + const resourcePreviewURL = isConvertFileType + ? `${INVITE_BASEURL}/preview/${encodeFileURL}/${taskToken}/${taskUUID}/` + : `${INVITE_BASEURL}/preview/${encodeFileURL}/`; + switch (file.convert) { case "converting": { Modal.info({ content: this.i18n.t("please-wait-while-the-lesson-is-transcoded") }); @@ -367,10 +380,7 @@ export class CloudStorageStore extends CloudStorageStoreBase { return; } default: { - // @TODO preview courseware - Modal.info({ - content: this.i18n.t("please-go-to-the-room-to-view-the-courseware"), - }); + window.open(resourcePreviewURL, "_blank"); } } } diff --git a/web/flat-web/src/pages/ResourcePreviewPage/DynamicPreview.less b/web/flat-web/src/pages/ResourcePreviewPage/DynamicPreview.less new file mode 100644 index 00000000000..73c25f0737a --- /dev/null +++ b/web/flat-web/src/pages/ResourcePreviewPage/DynamicPreview.less @@ -0,0 +1,40 @@ +.dynamic-preview-container { + background-color: #eee; +} + +.ppt-preview-container { + .ppt-preview-main-container { + padding-top: 25px; + border: none; + } +} + +.ppt-preview-controls { + display: none; +} + +.dynamic-preview-pagination-previous { + cursor: pointer; +} + +.dynamic-preview-pagination-next { + cursor: pointer; +} + +.dynamic-preview-pagination-container { + position: absolute; + bottom: 24px; + z-index: 2; + left: 48%; + width: 140px; + height: 44px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(0, 0, 0, 0.5); + border-radius: 8px; +} + +.dynamic-preview-pagination-middle { + color: #fff; +} diff --git a/web/flat-web/src/pages/ResourcePreviewPage/DynamicPreview.tsx b/web/flat-web/src/pages/ResourcePreviewPage/DynamicPreview.tsx new file mode 100644 index 00000000000..70e9cf8aa4a --- /dev/null +++ b/web/flat-web/src/pages/ResourcePreviewPage/DynamicPreview.tsx @@ -0,0 +1,94 @@ +import "./DynamicPreview.less"; +import previousStepSVG from "./image/previous-step.svg"; +import nextStepSVG from "./image/next-step.svg"; + +import { observer } from "mobx-react-lite"; +import React, { useEffect, useRef, useState } from "react"; +import { ConversionResponse, previewPPT } from "white-web-sdk"; +import { queryConvertingTaskStatus } from "../../apiMiddleware/courseware-converting"; +import { useSafePromise } from "../../utils/hooks/lifecycle"; +import { EventEmitter } from "eventemitter3"; + +export interface DynamicPreviewProps { + taskUUID: string; + taskToken: string; +} + +export const DynamicPreview = observer(function PPTPreview({ + taskUUID, + taskToken, +}) { + const DynamicPreviewRef = useRef(null); + const sp = useSafePromise(); + + const [currentPage, setCurrentPage] = useState(1); + const [totalPage, setTotalPage] = useState(0); + const [eventEmit] = useState(() => new EventEmitter()); + + useEffect(() => { + async function getDynamicResource(): Promise { + const convertState = await sp( + queryConvertingTaskStatus({ + taskUUID, + taskToken, + dynamic: true, + }), + ); + + if (DynamicPreviewRef.current) { + previewPPT( + convertState as ConversionResponse, + DynamicPreviewRef.current, + {}, + true, + {}, + undefined, + undefined, + eventEmit, + ); + } + } + + getDynamicResource().catch(console.warn); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + eventEmit.on("update", data => { + setCurrentPage(data.index); + }); + eventEmit.once("update", data => { + setTotalPage(data.total); + }); + return () => { + eventEmit.removeAllListeners(); + }; + }, [eventEmit]); + + return ( +
+
+
+
{ + eventEmit.emit("preStep"); + }} + > + previous step +
+
+ {currentPage} / {totalPage} +
+
{ + eventEmit.emit("nextStep"); + }} + > + next step +
+
+
+ ); +}); diff --git a/web/flat-web/src/pages/ResourcePreviewPage/MediaPreview.less b/web/flat-web/src/pages/ResourcePreviewPage/MediaPreview.less new file mode 100644 index 00000000000..93549e7feb9 --- /dev/null +++ b/web/flat-web/src/pages/ResourcePreviewPage/MediaPreview.less @@ -0,0 +1,23 @@ +.media-preview-container { + height: 100vh; + background-color: #000000; + + video { + width: 100%; + height: 100%; + object-fit: contain; + } +} + +.audio-container { + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.img-container { + height: 100%; + display: flex; + justify-content: center; +} diff --git a/web/flat-web/src/pages/ResourcePreviewPage/MediaPreview.tsx b/web/flat-web/src/pages/ResourcePreviewPage/MediaPreview.tsx new file mode 100644 index 00000000000..9aaf71e2c86 --- /dev/null +++ b/web/flat-web/src/pages/ResourcePreviewPage/MediaPreview.tsx @@ -0,0 +1,42 @@ +import "./MediaPreview.less"; + +import React from "react"; +import { observer } from "mobx-react-lite"; +import { getFileSuffix } from "./utils"; + +export interface MediaPreviewProps { + fileURL: string; +} + +export const MediaPreview = observer(function PPTPreview({ fileURL }) { + const mediaFileURL = decodeURIComponent(fileURL); + + const mediaFileSuffix = getFileSuffix(mediaFileURL); + + return
{renderMediaPreview()}
; + + function renderMediaPreview(): React.ReactElement { + switch (mediaFileSuffix) { + case ".mp3": { + return ( +
+
+ ); + } + case ".jpg": + case ".jpeg": + case ".png": { + return ( +
+ img resource +
+ ); + } + + default: { + return