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