diff --git a/frontends/main/package.json b/frontends/main/package.json index 7a4aa92817..4817890415 100644 --- a/frontends/main/package.json +++ b/frontends/main/package.json @@ -40,6 +40,7 @@ "@tiptap/react": "^3.13.0", "@tiptap/starter-kit": "^3.13.0", "@tiptap/static-renderer": "^3.13.0", + "@types/video.js": "^7.3.58", "api": "workspace:*", "classnames": "^2.5.1", "formik": "^2.4.6", @@ -62,6 +63,7 @@ "sharp": "0.34.4", "slick-carousel": "^1.8.1", "tiny-invariant": "^1.3.3", + "video.js": "8.23.7", "yup": "^1.4.0" }, "devDependencies": { diff --git a/frontends/main/src/page-components/TiptapEditor/extensions/node/MediaEmbed/MediaDisplay.tsx b/frontends/main/src/page-components/TiptapEditor/extensions/node/MediaEmbed/MediaDisplay.tsx new file mode 100644 index 0000000000..56cd9fb39c --- /dev/null +++ b/frontends/main/src/page-components/TiptapEditor/extensions/node/MediaEmbed/MediaDisplay.tsx @@ -0,0 +1,71 @@ +import React from "react" +import styled from "@emotion/styled" +import { isVideoUrl } from "./lib" +import { VideoJsPlayer } from "./VideoJsPlayer" + +const MediaContainer = styled.div(({ theme }) => ({ + position: "relative", + width: "100%", + aspectRatio: "16 / 9", + overflow: "hidden", + + iframe: { + width: "100%", + height: "100%", + borderRadius: "6px", + display: "block", + }, + + video: { + width: "100%", + height: "100%", + borderRadius: "6px", + display: "block", + objectFit: "contain", + backgroundColor: "#000", + }, + + // Video.js player styling + ".video-js": { + width: "100%", + height: "100%", + borderRadius: "6px", + }, + + ".layout-full & iframe, .layout-full & video, .layout-full & .video-js": { + borderRadius: 0, + }, + ".ProseMirror-selectednode .layout-wide &": { + border: `1px solid ${theme.custom.colors.red}`, + padding: "8px", + borderRadius: "10px", + }, + ".ProseMirror-selectednode .layout-full &": { + border: `1px solid ${theme.custom.colors.red}`, + padding: "8px 0", + borderWidth: "1px 0", + }, +})) + +interface MediaDisplayProps { + src: string + caption?: string +} + +export const MediaDisplay = ({ src, caption }: MediaDisplayProps) => { + return ( + + {isVideoUrl(src) ? ( + + ) : ( +