diff --git a/package-lock.json b/package-lock.json
index 91cda4503..70e44180a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -40,6 +40,7 @@
"react-dom": "^18.2.0",
"react-katex": "^3.0.1",
"react-markdown": "^9.0.1",
+ "react-player": "^2.14.1",
"react-resizable-panels": "^2.0.3",
"react-timeago": "^7.2.0",
"remark-gfm": "^4.0.0",
@@ -2461,6 +2462,14 @@
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
},
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/define-data-property": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz",
@@ -4530,6 +4539,11 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
+ "node_modules/load-script": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz",
+ "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA=="
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -6201,6 +6215,11 @@
"react": "^18.2.0"
}
},
+ "node_modules/react-fast-compare": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
+ },
"node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
@@ -6243,6 +6262,21 @@
"react": ">=18"
}
},
+ "node_modules/react-player": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.14.1.tgz",
+ "integrity": "sha512-jILj7F9o+6NHzrJ1GqZIxfJgskvGmKeJ05FNhPvgiCpvMZFmFneKEkukywHcULDO2lqITm+zcEkLSq42mX0FbA==",
+ "dependencies": {
+ "deepmerge": "^4.0.0",
+ "load-script": "^1.0.0",
+ "memoize-one": "^5.1.1",
+ "prop-types": "^15.7.2",
+ "react-fast-compare": "^3.0.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0"
+ }
+ },
"node_modules/react-redux": {
"version": "7.2.9",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz",
diff --git a/package.json b/package.json
index ccad98163..3f48100e0 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"react-dom": "^18.2.0",
"react-katex": "^3.0.1",
"react-markdown": "^9.0.1",
+ "react-player": "^2.14.1",
"react-resizable-panels": "^2.0.3",
"react-timeago": "^7.2.0",
"remark-gfm": "^4.0.0",
diff --git a/src/common/components/VideoPlayer.tsx b/src/common/components/VideoPlayer.tsx
new file mode 100644
index 000000000..c1d38e732
--- /dev/null
+++ b/src/common/components/VideoPlayer.tsx
@@ -0,0 +1,46 @@
+import * as React from 'react';
+
+import type { ReactPlayerProps } from 'react-player';
+
+
+type VideoPlayerProps = ReactPlayerProps & {
+ // make the player responsive
+ responsive?: boolean;
+ // set this to not set the full URL
+ youTubeVideoId?: string;
+};
+
+const VideoPlayerDynamic = React.lazy(async () => {
+
+ // dynamically import react-player (saves 7kb but still..)
+ const { default: ReactPlayer } = await import('react-player');
+
+ return {
+ default: (props: ReactPlayerProps) => {
+
+ const { responsive, youTubeVideoId, ...baseProps } = props;
+
+ // responsive patch
+ if (responsive) {
+ baseProps.width = '100%';
+ baseProps.height = '100%';
+ }
+
+ // fill in the URL if we have a YouTube video ID
+ if (youTubeVideoId) {
+ baseProps.url = `https://www.youtube.com/watch?v=${youTubeVideoId}`;
+ }
+
+ return ;
+ },
+ };
+});
+
+
+export function VideoPlayer(props: VideoPlayerProps) {
+ return (
+ Loading...}>
+
+
+ );
+}
\ No newline at end of file