|
@@ -1,10 +1,11 @@
|
|
import styled from '@emotion/styled'
|
|
import styled from '@emotion/styled'
|
|
-import React from 'react'
|
|
|
|
|
|
+import React, { useMemo } from 'react'
|
|
|
|
|
|
import { VideoFieldsFragment } from '@/api/queries'
|
|
import { VideoFieldsFragment } from '@/api/queries'
|
|
import { Gallery } from '@/shared/components'
|
|
import { Gallery } from '@/shared/components'
|
|
import { breakpointsOfGrid } from '@/shared/components/Grid'
|
|
import { breakpointsOfGrid } from '@/shared/components/Grid'
|
|
-import { sizes } from '@/shared/theme'
|
|
|
|
|
|
+import { AvatarContainer } from '@/shared/components/VideoTileBase/VideoTileBase.styles'
|
|
|
|
+import { media, sizes } from '@/shared/theme'
|
|
|
|
|
|
import { VideoTile } from './VideoTile'
|
|
import { VideoTile } from './VideoTile'
|
|
|
|
|
|
@@ -27,26 +28,13 @@ type VideoGalleryProps = {
|
|
onRemoveButtonClick?: (id: string) => void
|
|
onRemoveButtonClick?: (id: string) => void
|
|
onVideoNotFound?: (id: string) => void
|
|
onVideoNotFound?: (id: string) => void
|
|
onVideoClick?: (id: string) => void
|
|
onVideoClick?: (id: string) => void
|
|
|
|
+ hasRanking?: boolean
|
|
seeAllUrl?: string
|
|
seeAllUrl?: string
|
|
}
|
|
}
|
|
|
|
|
|
const PLACEHOLDERS_COUNT = 12
|
|
const PLACEHOLDERS_COUNT = 12
|
|
-
|
|
|
|
-// This is needed since Gliderjs and the Grid have different resizing policies
|
|
|
|
-const breakpoints = breakpointsOfGrid({
|
|
|
|
- breakpoints: 6,
|
|
|
|
- minItemWidth: 300,
|
|
|
|
- gridColumnGap: 24,
|
|
|
|
- viewportContainerDifference: 64,
|
|
|
|
-}).map((breakpoint, idx) => ({
|
|
|
|
- breakpoint,
|
|
|
|
- settings: {
|
|
|
|
- slidesToShow: idx + 1,
|
|
|
|
- slidesToScroll: idx + 1,
|
|
|
|
- },
|
|
|
|
-}))
|
|
|
|
-
|
|
|
|
const MIN_VIDEO_PREVIEW_WIDTH = 281
|
|
const MIN_VIDEO_PREVIEW_WIDTH = 281
|
|
|
|
+const CAROUSEL_SMALL_BREAKPOINT = 688
|
|
|
|
|
|
export const VideoGallery: React.FC<VideoGalleryProps> = ({
|
|
export const VideoGallery: React.FC<VideoGalleryProps> = ({
|
|
title,
|
|
title,
|
|
@@ -57,7 +45,33 @@ export const VideoGallery: React.FC<VideoGalleryProps> = ({
|
|
onRemoveButtonClick,
|
|
onRemoveButtonClick,
|
|
onVideoNotFound,
|
|
onVideoNotFound,
|
|
seeAllUrl,
|
|
seeAllUrl,
|
|
|
|
+ hasRanking = true,
|
|
}) => {
|
|
}) => {
|
|
|
|
+ const breakpoints = useMemo(() => {
|
|
|
|
+ return breakpointsOfGrid({
|
|
|
|
+ breakpoints: 6,
|
|
|
|
+ minItemWidth: 300,
|
|
|
|
+ gridColumnGap: 24,
|
|
|
|
+ viewportContainerDifference: 64,
|
|
|
|
+ }).map((breakpoint, idx) => {
|
|
|
|
+ if (breakpoint <= CAROUSEL_SMALL_BREAKPOINT && hasRanking) {
|
|
|
|
+ return {
|
|
|
|
+ breakpoint,
|
|
|
|
+ settings: {
|
|
|
|
+ slidesToShow: idx + 1.5,
|
|
|
|
+ slidesToScroll: idx + 1,
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return {
|
|
|
|
+ breakpoint,
|
|
|
|
+ settings: {
|
|
|
|
+ slidesToShow: idx + 1,
|
|
|
|
+ slidesToScroll: idx + 1,
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }, [hasRanking])
|
|
if (!loading && videos?.length === 0) {
|
|
if (!loading && videos?.length === 0) {
|
|
return null
|
|
return null
|
|
}
|
|
}
|
|
@@ -79,25 +93,46 @@ export const VideoGallery: React.FC<VideoGalleryProps> = ({
|
|
seeAllUrl={seeAllUrl}
|
|
seeAllUrl={seeAllUrl}
|
|
>
|
|
>
|
|
{[...videos, ...placeholderItems]?.map((video, idx) => (
|
|
{[...videos, ...placeholderItems]?.map((video, idx) => (
|
|
- <StyledVideoTile
|
|
|
|
- id={video.id}
|
|
|
|
- progress={video?.progress}
|
|
|
|
- key={idx}
|
|
|
|
- removeButton={video ? removeButton : false}
|
|
|
|
- onClick={createClickHandler(video.id)}
|
|
|
|
- onNotFound={createNotFoundHandler(video.id)}
|
|
|
|
- onRemoveButtonClick={createRemoveButtonClickHandler(video.id)}
|
|
|
|
- />
|
|
|
|
|
|
+ <GalleryWrapper key={`${idx}-${video.id}`} hasRanking={hasRanking}>
|
|
|
|
+ <StyledVideoTile
|
|
|
|
+ id={video.id}
|
|
|
|
+ progress={video?.progress}
|
|
|
|
+ removeButton={video ? removeButton : false}
|
|
|
|
+ onClick={createClickHandler(video.id)}
|
|
|
|
+ onNotFound={createNotFoundHandler(video.id)}
|
|
|
|
+ onRemoveButtonClick={createRemoveButtonClickHandler(video.id)}
|
|
|
|
+ rankingNumber={hasRanking ? idx + 1 : undefined}
|
|
|
|
+ />
|
|
|
|
+ </GalleryWrapper>
|
|
))}
|
|
))}
|
|
</Gallery>
|
|
</Gallery>
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
const StyledVideoTile = styled(VideoTile)`
|
|
const StyledVideoTile = styled(VideoTile)`
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
+
|
|
|
|
+ ${AvatarContainer} {
|
|
|
|
+ display: none;
|
|
|
|
+
|
|
|
|
+ ${media.medium} {
|
|
|
|
+ display: block;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+`
|
|
|
|
+
|
|
|
|
+const GalleryWrapper = styled.div<{ hasRanking?: boolean }>`
|
|
|
|
+ position: relative;
|
|
|
|
+ ${({ hasRanking }) => `
|
|
|
|
+ display: ${hasRanking ? 'flex' : 'block'};
|
|
|
|
+ justify-content: ${hasRanking ? 'flex-end' : 'unset'};
|
|
|
|
+ `}
|
|
|
|
+
|
|
|
|
+ ${StyledVideoTile} {
|
|
|
|
+ width: ${({ hasRanking }) => (hasRanking ? '78%' : '100%')};
|
|
|
|
+ }
|
|
|
|
+
|
|
& + & {
|
|
& + & {
|
|
margin-left: ${sizes(6)};
|
|
margin-left: ${sizes(6)};
|
|
}
|
|
}
|
|
-
|
|
|
|
- /* MIN_VIDEO_TILE_WIDTH */
|
|
|
|
- min-width: 300px;
|
|
|
|
`
|
|
`
|