import React, { useCallback, useMemo, useState } from 'react' import { css, SerializedStyles } from '@emotion/core' import styled from '@emotion/styled' import { navigate } from '@reach/router' import { Gallery, MAX_VIDEO_PREVIEW_WIDTH, VideoPreview, VideoPreviewBase } from '@/shared/components' import { VideoFields } from '@/api/queries/__generated__/VideoFields' import { CAROUSEL_CONTROL_SIZE } from '@/shared/components/Carousel' import routes from '@/config/routes' type VideoGalleryProps = { title: string action?: string videos?: VideoFields[] loading?: boolean } const PLACEHOLDERS_COUNT = 12 const VideoGallery: React.FC = ({ title, action, videos, loading }) => { const [posterSize, setPosterSize] = useState(0) const [galleryControlCss, setGalleryControlCss] = useState(css``) useMemo(() => { if (!posterSize) { return } const topPx = posterSize / 2 - CAROUSEL_CONTROL_SIZE / 2 setGalleryControlCss(css` top: ${topPx}px; `) }, [posterSize]) const displayPlaceholders = loading || !videos const imgRef = useCallback((node: HTMLImageElement) => { if (node != null) { setPosterSize(node.clientHeight) } }, []) const handleVideoClick = (id: string) => { navigate(routes.video(id)) } const handleChannelClick = (id: string) => { navigate(routes.channel(id)) } return ( {displayPlaceholders ? Array.from({ length: PLACEHOLDERS_COUNT }).map((_, idx) => ( )) : videos!.map((video, idx) => ( handleVideoClick(video.id)} onChannelClick={() => handleChannelClick(video.channel.id)} imgRef={idx === 0 ? imgRef : null} key={video.id} /> ))} ) } const StyledVideoPreviewBase = styled(VideoPreviewBase)` & + & { margin-left: 1.25rem; } width: ${MAX_VIDEO_PREVIEW_WIDTH}; ` const StyledVideoPreview = styled(VideoPreview)` & + & { margin-left: 1.25rem; } width: ${MAX_VIDEO_PREVIEW_WIDTH}; ` export default VideoGallery