From 0397ac3e66b4b90c7061b712a51548a4f4cd3b2a Mon Sep 17 00:00:00 2001 From: Roy Schut Date: Sun, 30 May 2021 20:37:25 +0200 Subject: [PATCH] feat(videodetail): add cinema and jwplayer --- src/components/Button/Button.module.scss | 18 +- .../DynamicBlur/DynamicBlur.module.scss | 5 +- src/components/Video/Video.module.scss | 136 ++++++++---- src/components/Video/Video.tsx | 93 +++++---- .../Video/__snapshots__/Video.test.tsx.snap | 193 ++++++++++++------ src/containers/Cinema/Cinema.module.scss | 7 + src/containers/Cinema/Cinema.test.tsx | 12 ++ src/containers/Cinema/Cinema.tsx | 33 +++ .../Cinema/__snapshots__/Cinema.test.tsx.snap | 10 + src/containers/Shelf/Shelf.tsx | 5 +- src/containers/Video/Video.tsx | 57 ++++-- src/hooks/usePlaylist.ts | 12 +- src/icons/Play.tsx | 10 + src/utils/dom.ts | 10 + types/global.d.ts | 1 + types/jwplayer.d.ts | 3 + 16 files changed, 443 insertions(+), 162 deletions(-) create mode 100644 src/containers/Cinema/Cinema.module.scss create mode 100644 src/containers/Cinema/Cinema.test.tsx create mode 100644 src/containers/Cinema/Cinema.tsx create mode 100644 src/containers/Cinema/__snapshots__/Cinema.test.tsx.snap create mode 100644 src/icons/Play.tsx create mode 100644 types/jwplayer.d.ts diff --git a/src/components/Button/Button.module.scss b/src/components/Button/Button.module.scss index 051447b39..63a438254 100644 --- a/src/components/Button/Button.module.scss +++ b/src/components/Button/Button.module.scss @@ -12,6 +12,8 @@ color: var(--highlight-color, white); font-family: theme.$body-alt-font-family; + font-size: 16px; + line-height: 18px; text-align: center; text-decoration: none; @@ -20,7 +22,12 @@ border-radius: 4px; cursor: pointer; - transition: background 0.1s ease, transform 0.1s ease; + transition: background-color 0.1s ease, transform 0.1s ease; + + > svg { + height: 18px; + width: 18px; + } &.fullWidth { width: 100%; @@ -61,5 +68,12 @@ } } .startIcon { - margin-right: 13px; + margin-right: 11px; + height: 100%; + display: flex; + align-items: center; + > svg { + height: 20px; + width: 20px; + } } diff --git a/src/components/DynamicBlur/DynamicBlur.module.scss b/src/components/DynamicBlur/DynamicBlur.module.scss index d1cbef02e..56ac1b2de 100644 --- a/src/components/DynamicBlur/DynamicBlur.module.scss +++ b/src/components/DynamicBlur/DynamicBlur.module.scss @@ -5,10 +5,11 @@ position: fixed; height: 100vh; width: 100vw; - background-position: center; + background-position: center center; background-size: cover; + background-repeat: no-repeat; box-sizing: border-box; filter: blur(30px); - z-index: -1; + z-index: -2; opacity: 0; } diff --git a/src/components/Video/Video.module.scss b/src/components/Video/Video.module.scss index c7169e385..049f908e2 100644 --- a/src/components/Video/Video.module.scss +++ b/src/components/Video/Video.module.scss @@ -1,52 +1,112 @@ @use '../../styles/variables'; @use '../../styles/theme'; +@use '../../styles/mixins/responsive'; .video { - padding: 50px; - color: white; + padding: 56px 56px; + color: var(--primary-color); + font-family: var(--body-font-family); + font-weight: 400; + text-shadow: 0px 2px 4px rgba(0, 0, 0, 0.14), 0px 3px 4px rgba(0, 0, 0, 0.12), 0px 1px 5px rgba(0, 0, 0, 0.2); + + @include responsive.tablet-only() { + padding: 24px; + } + @include responsive.mobile-only() { + padding: 16px; + } } .main { display: flex; + position: relative; } .info { - width: 50%; + max-width: 450px; + @include responsive.tablet-only() { + max-width: 350px; + } + @include responsive.mobile-only() { + width: 100%; + padding-top: 225px; + } } .title { - font-weight: 900; - font-size: larger; - margin: 20px 0px; + font-size: 34px; + font-weight: 700; + line-height: 36px; + letter-spacing: 0.25px; + margin: 8px 0px; } .meta { - margin: 20px 0px; - > ul { - padding-inline-start: 0px; - display: flex; - > li { - margin-right: 30px; + line-height: 18px; + font-size: 16px; + letter-spacing: 0.15px; + margin-bottom: 8px; +} +.description { + font-size: 18px; + line-height: 20px; + letter-spacing: 0.5px; + margin-bottom: 24px; +} +.playButton { + justify-content: center; + margin-bottom: 8px; +} +.otherButtons { + display: flex; + justify-content: center; + > button { + margin-right: 8px; + width: 33%; + } + > button:last-child { + margin-right: 0px; + } + @include responsive.mobile-only() { + flex-wrap: wrap; + > button:first-child { + margin-bottom: 8px; + margin-right: 0px; + width: 100%; } - > li:first-child { - list-style-type: none; + > button:not(:first-child) { + flex: 1; } } } -.buttons { - margin: 20px 0px; - > button { - margin-right: 20px; - } +.poster { + position: absolute; + background-size: cover; + background-repeat: no-repeat; + background-position: center center; + top: 0; + right: 0; + z-index: -1; } -.banner { - width: 50%; - position: relative; - opacity: 0.7; - > img { - width: 100%; +.posterNormal { + width: 720px; + height: 405px; + border-radius: 4px; + mask-image: linear-gradient(-90deg, rgba(0, 0, 0, 1) 90%, rgba(0, 0, 0, 0) 100%); + -webkit-mask-image: linear-gradient(-90deg, rgba(0, 0, 0, 1) 90%, rgba(0, 0, 0, 0) 100%); + + @include responsive.tablet-only() { + width: 600px; + height: 338px; } - &:hover { - cursor: pointer; - opacity: 1; + @include responsive.mobile-only() { + width: 100vw; + mask-image: radial-gradient(farthest-corner at 80% 20%, rgba(0, 0, 0, 1) 40%, rgba(0, 0, 0, 0) 60%); + -webkit-mask-image: radial-gradient(farthest-corner at 80% 20%, rgba(0, 0, 0, 1) 40%, rgba(0, 0, 0, 0) 60%); } } +.posterFading { + width: 1280px; + height: 640px; + mask-image: radial-gradient(farthest-corner at 80% 20%, rgba(0, 0, 0, 1) 40%, rgba(0, 0, 0, 0) 60%); + -webkit-mask-image: radial-gradient(farthest-corner at 80% 20%, rgba(0, 0, 0, 1) 40%, rgba(0, 0, 0, 0) 60%); +} .playIcon { position: absolute; left: calc(50% - 35px); @@ -74,18 +134,20 @@ background-position: center; opacity: 0.7; } -.playerInfo { +.player { position: absolute; + left: 0; top: 0; - margin: 50px; + width: 100vw; + height: 100vh; +} +.playerContent { + position: absolute; + top: 0; + margin: 30px 62px; max-width: 50%; display: flex; - - > h2 { - font-size: x-large; - } } -.backButton { - padding: 10px; - font-size: x-large; +.playerInfo { + margin: 0px 30px; } diff --git a/src/components/Video/Video.tsx b/src/components/Video/Video.tsx index 5a2ad5985..d37509597 100644 --- a/src/components/Video/Video.tsx +++ b/src/components/Video/Video.tsx @@ -1,6 +1,14 @@ import React from 'react'; import type { PlaylistItem } from 'types/playlist'; +import classNames from 'classnames'; +import Cinema from '../../containers/Cinema/Cinema'; +import useBreakpoint, { Breakpoint } from '../../hooks/useBreakpoint'; +import Favorite from '../../icons/Favorite'; +import PlayTrailer from '../../icons/PlayTrailer'; +import Share from '../../icons/Share'; +import ArrowLeft from '../../icons/ArrowLeft'; +import Play from '../../icons/Play'; import Button from '../Button/Button'; import IconButton from '../IconButton/IconButton'; @@ -11,59 +19,68 @@ type Props = { play: boolean; startPlay: () => void; goBack: () => void; + posterFading: boolean; + relatedShelf?: JSX.Element; }; -const Video: React.FC = ({ item, play, startPlay, goBack }: Props) => { - const fullYear: number = new Date(item.pubdate).getFullYear(); - const duration: string = `${Math.floor(item.duration / 60)}h ${item.duration % 60}m`; +const Video: React.FC = ({ item, play, startPlay, goBack, posterFading, relatedShelf }: Props) => { + const posterImage = item.image.replace('720', '1280'); // Todo: 1280 should be sent from API + const breakpoint = useBreakpoint(); + const isMobile = breakpoint === Breakpoint.xs; + + const metaData = []; + if (item.pubdate) metaData.push(new Date(item.pubdate).getFullYear()); + if (item.duration) metaData.push(`${Math.floor(item.duration / 60)}h ${item.duration % 60}m`); + if (item.genre) metaData.push(item.genre); + if (item.rating) metaData.push(item.rating); + const metaString = metaData.join(' • '); + + //todo: image based on screen res, etc (like Home) + //todo: breakpoints not same as css (so info padding-top acts too soon) + //todo: description enlarger + return (

{item.title}

-
-
    -
  • {fullYear}
  • -
  • {duration}
  • -
  • {item.genre}
  • -
  • {item.rating}
  • -
+
{metaString}
+ {!isMobile &&
{item.description}
} +
+
-
{item.description}
-
-
-
- -
-
-
-
-

Resting shelf

+
+ {!!relatedShelf &&
{relatedShelf}
} {play && (
-
-
-
- -

-
-
-
+
+ +
+
+ + + +

{item.title}

-
-
    -
  • {fullYear}
  • -
  • {duration}
  • -
  • {item.genre}
  • -
  • {item.rating}
  • -
-
+
{metaString}
{item.description}
diff --git a/src/components/Video/__snapshots__/Video.test.tsx.snap b/src/components/Video/__snapshots__/Video.test.tsx.snap index d572f7bb4..0eb654f3e 100644 --- a/src/components/Video/__snapshots__/Video.test.tsx.snap +++ b/src/components/Video/__snapshots__/Video.test.tsx.snap @@ -19,44 +19,116 @@ exports[`
-
-

- Resting shelf -

+ class="poster posterNormal" + style="background-image: url(http://test/img.jpg);" + />
renders and matches snapshot 1`] = ` class="background" style="background-image: url(http://test/img.jpg);" /> -
+
+
+
- + + + +
-
+

@@ -116,22 +190,11 @@ exports[`