/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import {DemoVideoGalleryQuery} from '@/common/components/gallery/__generated__/DemoVideoGalleryQuery.graphql'; import VideoGalleryUploadVideo from '@/common/components/gallery/VideoGalleryUploadPhoto'; import VideoPhoto from '@/common/components/gallery/VideoPhoto'; import useScreenSize from '@/common/screen/useScreenSize'; import {VideoData} from '@/demo/atoms'; import {DEMO_SHORT_NAME} from '@/demo/DemoConfig'; import {fontSize, fontWeight, spacing} from '@/theme/tokens.stylex'; import stylex from '@stylexjs/stylex'; import {useMemo} from 'react'; import PhotoAlbum, {Photo, RenderPhotoProps} from 'react-photo-album'; import {graphql, useLazyLoadQuery} from 'react-relay'; import {useLocation, useNavigate} from 'react-router-dom'; const styles = stylex.create({ container: { display: 'flex', flexDirection: 'column', marginHorizontal: spacing[1], height: '100%', lineHeight: 1.2, paddingTop: spacing[8], }, headerContainer: { marginBottom: spacing[8], fontWeight: fontWeight['medium'], fontSize: fontSize['2xl'], '@media screen and (max-width: 768px)': { marginTop: spacing[0], marginBottom: spacing[8], marginHorizontal: spacing[4], fontSize: fontSize['xl'], }, }, albumContainer: { flex: '1 1 0%', width: '100%', overflowY: 'auto', }, }); type Props = { showUploadInGallery?: boolean; onSelect?: (video: VideoPhotoData) => void; onUpload: (video: VideoData) => void; onUploadStart?: () => void; onUploadError?: (error: Error) => void; }; type VideoPhotoData = Photo & VideoData & { poster: string; isUploadOption: boolean; }; export default function DemoVideoGallery({ showUploadInGallery = false, onSelect, onUpload, onUploadStart, onUploadError, }: Props) { const navigate = useNavigate(); const location = useLocation(); const {isMobile: isMobileScreenSize} = useScreenSize(); const data = useLazyLoadQuery( graphql` query DemoVideoGalleryQuery { videos { edges { node { id path posterPath url posterUrl height width posterUrl } } } } `, {}, ); const allVideos: VideoPhotoData[] = useMemo(() => { return data.videos.edges.map(video => { return { src: video.node.url, path: video.node.path, poster: video.node.posterPath, posterPath: video.node.posterPath, url: video.node.url, posterUrl: video.node.posterUrl, width: video.node.width, height: video.node.height, isUploadOption: false, } as VideoPhotoData; }); }, [data.videos.edges]); const shareableVideos: VideoPhotoData[] = useMemo(() => { const filteredVideos = [...allVideos]; if (showUploadInGallery) { const uploadOption = { src: '', width: 1280, height: 720, poster: '', isUploadOption: true, } as VideoPhotoData; filteredVideos.unshift(uploadOption); } return filteredVideos; }, [allVideos, showUploadInGallery]); const renderPhoto = ({ photo: video, imageProps, }: RenderPhotoProps) => { const {style} = imageProps; const {url, posterUrl} = video; return video.isUploadOption ? ( ) : ( { navigate(location.pathname, { state: { video, }, }); onSelect?.(video); }} /> ); }; function handleUploadVideo(video: VideoData) { navigate(location.pathname, { state: { video, }, }); onUpload?.(video); } const descriptionStyle = 'text-sm md:text-base text-gray-400 leading-snug'; return (

Select a video to try{' '} with the {DEMO_SHORT_NAME}

You’ll be able to download what you make.

layout="rows" photos={shareableVideos} targetRowHeight={isMobileScreenSize ? 120 : 200} rowConstraints={{ singleRowMaxHeight: isMobileScreenSize ? 120 : 240, maxPhotos: 3, }} renderPhoto={renderPhoto} spacing={4} />
); }