123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import styled from '@emotion/styled'
- import React, { useMemo } from 'react'
- import { VideoFieldsFragment } from '@/api/queries'
- import { Gallery, RankingNumberTile } from '@/shared/components'
- import { breakpointsOfGrid } from '@/shared/components/Grid'
- import { AvatarContainer } from '@/shared/components/VideoTileBase/VideoTileBase.styles'
- import { media } from '@/shared/theme'
- import { VideoTile } from './VideoTile'
- interface VideoFieldsWithProgress extends VideoFieldsFragment {
- progress?: number
- }
- type VideoWithIdAndProgress = {
- id: string
- progress?: number
- }
- type CustomVideosType = VideoFieldsWithProgress[] | VideoWithIdAndProgress[]
- type VideoGalleryProps = {
- title?: string
- videos?: CustomVideosType | null
- loading?: boolean
- removeButton?: boolean
- onRemoveButtonClick?: (id: string) => void
- onVideoNotFound?: (id: string) => void
- onVideoClick?: (id: string) => void
- hasRanking?: boolean
- seeAllUrl?: string
- className?: string
- }
- const PLACEHOLDERS_COUNT = 12
- const MIN_VIDEO_PREVIEW_WIDTH = 281
- const CAROUSEL_SMALL_BREAKPOINT = 688
- const FRACTIONAL_LEVEL = 1.3
- const FRACTIONAL_LEVEL_RANKING = 1.4
- export const VideoGallery: React.FC<VideoGalleryProps> = ({
- title,
- videos = [],
- loading,
- onVideoClick,
- removeButton,
- onRemoveButtonClick,
- onVideoNotFound,
- seeAllUrl,
- hasRanking = false,
- className,
- }) => {
- 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 + FRACTIONAL_LEVEL,
- slidesToScroll: idx + 1,
- },
- }
- }
- return {
- breakpoint,
- settings: {
- slidesToShow: idx + (breakpoint <= CAROUSEL_SMALL_BREAKPOINT ? FRACTIONAL_LEVEL_RANKING : 1),
- slidesToScroll: idx + 1,
- },
- }
- })
- }, [hasRanking])
- if (loading === false && videos?.length === 0) {
- return null
- }
- const placeholderItems = Array.from({ length: loading || !videos?.length ? PLACEHOLDERS_COUNT : 0 }, () => ({
- id: undefined,
- progress: undefined,
- }))
- const createClickHandler = (id?: string) => () => id && onVideoClick && onVideoClick(id)
- const createRemoveButtonClickHandler = (id?: string) => () => id && onRemoveButtonClick && onRemoveButtonClick(id)
- const createNotFoundHandler = (id?: string) => () => id && onVideoNotFound && onVideoNotFound(id)
- return (
- <Gallery
- title={title}
- responsive={breakpoints}
- itemWidth={MIN_VIDEO_PREVIEW_WIDTH}
- dotsVisible
- seeAllUrl={seeAllUrl}
- className={className}
- >
- {[...(videos ? videos : []), ...placeholderItems]?.map((video, idx) =>
- hasRanking ? (
- <RankingNumberTile variant="video" rankingNumber={idx + 1} key={`${idx}-${video.id}`}>
- <StyledVideoTile
- id={video.id}
- progress={video?.progress}
- removeButton={video ? removeButton : false}
- onClick={createClickHandler(video.id)}
- onNotFound={createNotFoundHandler(video.id)}
- onRemoveButtonClick={createRemoveButtonClickHandler(video.id)}
- />
- </RankingNumberTile>
- ) : (
- <StyledVideoTile
- key={`${idx}-${video.id}`}
- id={video.id}
- progress={video?.progress}
- removeButton={video ? removeButton : false}
- onClick={createClickHandler(video.id)}
- onNotFound={createNotFoundHandler(video.id)}
- onRemoveButtonClick={createRemoveButtonClickHandler(video.id)}
- />
- )
- )}
- </Gallery>
- )
- }
- const StyledVideoTile = styled(VideoTile)`
- flex-shrink: 0;
- ${AvatarContainer} {
- display: none;
- ${media.medium} {
- display: block;
- }
- }
- `
|