diff --git a/package.json b/package.json
index ca720cff..43e726e8 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,7 @@
"react-lazyload": "^3.2.0",
"react-masonry-css": "^1.0.16",
"react-popper": "^2.2.3",
+ "react-resize-detector": "^12.0.2",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-sticky-box": "^1.0.2",
diff --git a/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/components/CommentVideoFrame/index.tsx b/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/components/CommentVideoFrame/index.tsx
new file mode 100644
index 00000000..686e6dd1
--- /dev/null
+++ b/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/components/CommentVideoFrame/index.tsx
@@ -0,0 +1,28 @@
+import classNames from 'classnames';
+import { useResizeDetector } from 'react-resize-detector';
+
+import styles from './styles.module.scss';
+
+interface Props {
+ id: string;
+ title: string;
+ className?: string;
+}
+
+export const CommentVideoFrame = ({ id, title, className }: Props) => {
+ const { ref, width = 0, height = 0 } = useResizeDetector();
+
+ return (
+
+
+
+ );
+};
diff --git a/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/components/CommentVideoFrame/styles.module.scss b/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/components/CommentVideoFrame/styles.module.scss
new file mode 100644
index 00000000..26849291
--- /dev/null
+++ b/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/components/CommentVideoFrame/styles.module.scss
@@ -0,0 +1,8 @@
+@import '~/styles/variables';
+
+.wrap {
+ width: 100%;
+ aspect-ratio: calc(16 / 9);
+ overflow: hidden;
+ border-radius: $radius;
+}
diff --git a/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/index.tsx b/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/index.tsx
index 8305866d..542dea5a 100644
--- a/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/index.tsx
+++ b/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/index.tsx
@@ -1,15 +1,21 @@
-import { FC, memo, useMemo } from 'react';
+import { FC, memo, useCallback, useMemo } from 'react';
import { Icon } from '~/components/common/Icon';
import { ICommentBlockProps } from '~/constants/comment';
+import { useWindowSize } from '~/hooks/dom/useWindowSize';
import { useYoutubeMetadata } from '~/hooks/metadata/useYoutubeMetadata';
import { getYoutubeThumb } from '~/utils/dom';
+import { useVideoPlayer } from '~/utils/providers/VideoPlayerProvider';
+import { CommentVideoFrame } from './components/CommentVideoFrame';
import styles from './styles.module.scss';
type Props = ICommentBlockProps & {};
const CommentEmbedBlock: FC = memo(({ block }) => {
+ const { isTablet } = useWindowSize();
+ const { url, setUrl } = useVideoPlayer();
+
const id = useMemo(() => {
const match = block.content.match(
/https?:\/\/(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch)?(?:\?v=)?([\w\-=]+)/,
@@ -18,7 +24,7 @@ const CommentEmbedBlock: FC = memo(({ block }) => {
return (match && match[1]) || '';
}, [block.content]);
- const url = useMemo(() => `https://youtube.com/watch?v=${id}`, [id]);
+ const address = `https://youtube.com/watch?v=${id}`;
const preview = useMemo(
() => getYoutubeThumb(block.content),
@@ -28,21 +34,46 @@ const CommentEmbedBlock: FC = memo(({ block }) => {
const metadata = useYoutubeMetadata(id);
const title = metadata?.metadata?.title || '';
+ const onClick = useCallback(() => {
+ if (isTablet) {
+ window.open(address, '_blank');
+ return;
+ }
+
+ setUrl(address);
+ }, [isTablet, setUrl, address]);
+
+ const closeVideo = useCallback(() => setUrl(''), [setUrl]);
+
return (
-
-
-
-
-
-
-
-
-
-
{title}
+ {url === address ? (
+
-
+ ) : (
+
+ )}
);
});
diff --git a/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/styles.module.scss b/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/styles.module.scss
index a8e0520b..5c033998 100644
--- a/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/styles.module.scss
+++ b/src/containers/node/NodeComments/components/Comment/components/CommentContent/components/CommentEmbedBlock/styles.module.scss
@@ -1,8 +1,8 @@
@import 'src/styles/variables';
.embed {
- padding: 0 $gap;
- height: $comment_height;
+ padding: 0 0;
+ min-height: $comment_height;
width: 100%;
box-sizing: border-box;
background: 50% 50% no-repeat;
@@ -69,6 +69,7 @@
justify-content: stretch;
box-sizing: border-box;
z-index: 2;
+ cursor: pointer;
& > div {
width: 100%;
@@ -98,3 +99,47 @@
overflow: hidden;
text-overflow: ellipsis;
}
+
+@keyframes appear {
+ 0% {
+ grid-template-columns: 0fr;
+ opacity: 0;
+ }
+
+ 50% {
+ grid-template-columns: 1fr;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
+.video {
+ width: 100%;
+ position: relative;
+ padding: $gap / 2;
+}
+
+.close {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: var(--color_danger);
+ width: 64px;
+ height: 24px;
+ position: absolute;
+ bottom: calc(100% - #{$gap / 2});
+ right: 24px;
+ border-radius: $radius $radius 0 0;
+ z-index: 10;
+ cursor: pointer;
+}
+
+.animation {
+ background-color: var(--content_bg_darker);
+ display: grid;
+ animation: appear 0.5s forwards;
+ width: 100%;
+ border-radius: $radius;
+}
diff --git a/src/containers/node/NodeComments/index.tsx b/src/containers/node/NodeComments/index.tsx
index 816f6d19..fa39d493 100644
--- a/src/containers/node/NodeComments/index.tsx
+++ b/src/containers/node/NodeComments/index.tsx
@@ -15,6 +15,7 @@ import { useCommentContext } from '~/utils/context/CommentContextProvider';
import { useNodeContext } from '~/utils/context/NodeContextProvider';
import { useUserContext } from '~/utils/context/UserContextProvider';
import { canEditComment, canLikeComment } from '~/utils/node';
+import { VideoPlayerProvider } from '~/utils/providers/VideoPlayerProvider';
import styles from './styles.module.scss';
@@ -84,38 +85,40 @@ const NodeComments: FC
= observer(({ order }) => {
}, [isLoading]);
return (
-
- {order === 'DESC' && more}
+
+
+ {order === 'DESC' && more}
- {groupped.map((group, index) => (
- <>
- {isFirstGroupWithNewComment(group, groupped[index - 1]) && (
-
+ )}
+
+
- )}
+ >
+ ))}
-
- >
- ))}
-
- {order === 'ASC' && more}
-
+ {order === 'ASC' && more}
+
+
);
});
diff --git a/src/utils/providers/VideoPlayerProvider.tsx b/src/utils/providers/VideoPlayerProvider.tsx
new file mode 100644
index 00000000..4f12345a
--- /dev/null
+++ b/src/utils/providers/VideoPlayerProvider.tsx
@@ -0,0 +1,17 @@
+import { createContext, ReactNode, useContext, useState } from 'react';
+
+const Context = createContext({
+ url: '',
+ setUrl: (val: string) => {},
+});
+
+/** Provides context for comment video playing */
+export const VideoPlayerProvider = ({ children }: { children: ReactNode }) => {
+ const [url, setUrl] = useState('');
+
+ return (
+ {children}
+ );
+};
+
+export const useVideoPlayer = () => useContext(Context);
diff --git a/yarn.lock b/yarn.lock
index 51753816..30bb1ef1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2626,6 +2626,13 @@ react-popper@^2.2.3:
react-fast-compare "^3.0.1"
warning "^4.0.2"
+react-resize-detector@^12.0.2:
+ version "12.0.2"
+ resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-12.0.2.tgz#5e65f906a85835d246de57dbf608bf22ab333cad"
+ integrity sha512-aAI4WxWAysWLhA8wKDpsS+PnnxQ0lWCkTlk2t+2ijalWvoSa7vPxmcKRLURkH+PU84QE4KP4dO58oVP3ypWkKA==
+ dependencies:
+ lodash "^4.17.21"
+
react-router-dom@^5.1.2:
version "5.3.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363"