Ver código fonte

connect video view to the data store

Klaudiusz Dembler 4 anos atrás
pai
commit
495ea08a48

+ 6 - 0
.eslintrc.js

@@ -7,6 +7,12 @@ module.exports = {
   },
   extends: ['plugin:react-hooks/recommended', '@joystream/eslint-config'],
   rules: {
+    camelcase: [
+      'warn',
+      {
+        ignoreImports: true,
+      },
+    ],
     'react/prop-types': 'off',
     '@typescript-eslint/explicit-module-boundary-types': 'off',
     '@typescript-eslint/no-empty-function': 'warn',

+ 12 - 1
packages/app/src/api/queries/__generated__/GetFeaturedVideos.ts

@@ -7,14 +7,25 @@
 // GraphQL query operation: GetFeaturedVideos
 // ====================================================
 
-export interface GetFeaturedVideos_featured_videos_media_location {
+export interface GetFeaturedVideos_featured_videos_media_location_HTTPVideoMediaLocation {
   __typename: 'HTTPVideoMediaLocation'
   host: string
   port: number | null
 }
 
+export interface GetFeaturedVideos_featured_videos_media_location_JoystreamVideoMediaLocation {
+  __typename: 'JoystreamVideoMediaLocation'
+  dataObjectID: string
+}
+
+export type GetFeaturedVideos_featured_videos_media_location =
+  | GetFeaturedVideos_featured_videos_media_location_HTTPVideoMediaLocation
+  | GetFeaturedVideos_featured_videos_media_location_JoystreamVideoMediaLocation
+
 export interface GetFeaturedVideos_featured_videos_media {
   __typename: 'VideoMedia'
+  pixelHeight: number
+  pixelWidth: number
   location: GetFeaturedVideos_featured_videos_media_location
 }
 

+ 12 - 1
packages/app/src/api/queries/__generated__/GetNewestVideos.ts

@@ -7,14 +7,25 @@
 // GraphQL query operation: GetNewestVideos
 // ====================================================
 
-export interface GetNewestVideos_videos_media_location {
+export interface GetNewestVideos_videos_media_location_HTTPVideoMediaLocation {
   __typename: 'HTTPVideoMediaLocation'
   host: string
   port: number | null
 }
 
+export interface GetNewestVideos_videos_media_location_JoystreamVideoMediaLocation {
+  __typename: 'JoystreamVideoMediaLocation'
+  dataObjectID: string
+}
+
+export type GetNewestVideos_videos_media_location =
+  | GetNewestVideos_videos_media_location_HTTPVideoMediaLocation
+  | GetNewestVideos_videos_media_location_JoystreamVideoMediaLocation
+
 export interface GetNewestVideos_videos_media {
   __typename: 'VideoMedia'
+  pixelHeight: number
+  pixelWidth: number
   location: GetNewestVideos_videos_media_location
 }
 

+ 58 - 0
packages/app/src/api/queries/__generated__/GetVideo.ts

@@ -0,0 +1,58 @@
+/* tslint:disable */
+/* eslint-disable */
+// @generated
+// This file was automatically generated and should not be edited.
+
+// ====================================================
+// GraphQL query operation: GetVideo
+// ====================================================
+
+export interface GetVideo_video_media_location_HTTPVideoMediaLocation {
+  __typename: 'HTTPVideoMediaLocation'
+  host: string
+  port: number | null
+}
+
+export interface GetVideo_video_media_location_JoystreamVideoMediaLocation {
+  __typename: 'JoystreamVideoMediaLocation'
+  dataObjectID: string
+}
+
+export type GetVideo_video_media_location =
+  | GetVideo_video_media_location_HTTPVideoMediaLocation
+  | GetVideo_video_media_location_JoystreamVideoMediaLocation
+
+export interface GetVideo_video_media {
+  __typename: 'VideoMedia'
+  pixelHeight: number
+  pixelWidth: number
+  location: GetVideo_video_media_location
+}
+
+export interface GetVideo_video_channel {
+  __typename: 'Channel'
+  id: string
+  avatarPhotoURL: string
+  handle: string
+}
+
+export interface GetVideo_video {
+  __typename: 'Video'
+  id: string
+  title: string
+  description: string
+  views: number
+  duration: number
+  thumbnailURL: string
+  publishedOnJoystreamAt: GQLDate
+  media: GetVideo_video_media
+  channel: GetVideo_video_channel
+}
+
+export interface GetVideo {
+  video: GetVideo_video | null
+}
+
+export interface GetVideoVariables {
+  id: string
+}

+ 12 - 1
packages/app/src/api/queries/__generated__/VideoFields.ts

@@ -7,14 +7,25 @@
 // GraphQL fragment: VideoFields
 // ====================================================
 
-export interface VideoFields_media_location {
+export interface VideoFields_media_location_HTTPVideoMediaLocation {
   __typename: 'HTTPVideoMediaLocation'
   host: string
   port: number | null
 }
 
+export interface VideoFields_media_location_JoystreamVideoMediaLocation {
+  __typename: 'JoystreamVideoMediaLocation'
+  dataObjectID: string
+}
+
+export type VideoFields_media_location =
+  | VideoFields_media_location_HTTPVideoMediaLocation
+  | VideoFields_media_location_JoystreamVideoMediaLocation
+
 export interface VideoFields_media {
   __typename: 'VideoMedia'
+  pixelHeight: number
+  pixelWidth: number
   location: VideoFields_media_location
 }
 

+ 14 - 0
packages/app/src/api/queries/videos.ts

@@ -10,11 +10,16 @@ const videoFieldsFragment = gql`
     thumbnailURL
     publishedOnJoystreamAt
     media {
+      pixelHeight
+      pixelWidth
       location {
         ... on HTTPVideoMediaLocation {
           host
           port
         }
+        ... on JoystreamVideoMediaLocation {
+          dataObjectID
+        }
       }
     }
     channel {
@@ -43,3 +48,12 @@ export const GET_FEATURED_VIDEOS = gql`
   }
   ${videoFieldsFragment}
 `
+
+export const GET_VIDEO = gql`
+  query GetVideo($id: ID!) {
+    video(id: $id) {
+      ...VideoFields
+    }
+  }
+  ${videoFieldsFragment}
+`

+ 1 - 1
packages/app/src/components/LayoutWithRouting.tsx

@@ -9,7 +9,7 @@ const LayoutWithRouting: React.FC = () => (
     <GlobalStyle />
     <Router primary={false}>
       <HomeView default />
-      <VideoView path={routes.video} />
+      <VideoView path={routes.video()} />
     </Router>
   </main>
 )

+ 4 - 3
packages/app/src/components/VideoGallery.tsx

@@ -6,6 +6,7 @@ import { navigate } from '@reach/router'
 import { Gallery, 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
@@ -39,8 +40,8 @@ const VideoGallery: React.FC<VideoGalleryProps> = ({ title, action, videos, load
     }
   }, [])
 
-  const handleVideoClick = () => {
-    navigate('/video/fake')
+  const handleVideoClick = (id: string) => {
+    navigate(routes.video(id))
   }
 
   return (
@@ -64,7 +65,7 @@ const VideoGallery: React.FC<VideoGalleryProps> = ({ title, action, videos, load
               createdAt={video.publishedOnJoystreamAt}
               duration={video.duration}
               posterURL={video.thumbnailURL}
-              onClick={handleVideoClick}
+              onClick={() => handleVideoClick(video.id)}
               imgRef={idx === 0 ? imgRef : null}
               key={video.id}
             />

+ 1 - 1
packages/app/src/config/routes.ts

@@ -1,3 +1,3 @@
 export default {
-  video: 'video/:id',
+  video: (id = ':id') => `video/${id}`,
 }

+ 8 - 3
packages/app/src/shared/components/VideoPlayer/videoJsPlayer.ts

@@ -1,9 +1,12 @@
-import videojs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js'
 import { RefObject, useEffect, useRef, useState } from 'react'
+import videojs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js'
 import 'video.js/dist/video-js.css'
 
+import { VideoFields_media_location } from '@/api/queries/__generated__/VideoFields'
+
 export type VideoJsConfig = {
-  src: string
+  // eslint-disable-next-line camelcase
+  src: VideoFields_media_location
   width?: number
   height?: number
   fluid?: boolean
@@ -15,6 +18,8 @@ export const useVideoJsPlayer: VideoJsPlayerHook = ({ fill, fluid, height, src,
   const playerRef = useRef<HTMLVideoElement>(null)
   const [player, setPlayer] = useState<VideoJsPlayer | null>(null)
 
+  const parsedSource = src.__typename === 'HTTPVideoMediaLocation' ? src.host : 'TODO'
+
   useEffect(() => {
     const videoJsOptions: VideoJsPlayerOptions = {
       controls: true,
@@ -34,7 +39,7 @@ export const useVideoJsPlayer: VideoJsPlayerHook = ({ fill, fluid, height, src,
     }
 
     player.src({
-      src,
+      src: parsedSource,
       type: 'video/mp4',
     })
   }, [player, src])

+ 3 - 1
packages/app/src/views/VideoView/VideoView.style.tsx

@@ -5,6 +5,8 @@ import theme from '@/shared/theme'
 export const Container = styled.div`
   display: flex;
   flex-direction: column;
+  // TODO: remove once we have the navbar
+  padding-top: 72px;
 `
 
 export const PlayerContainer = styled.div`
@@ -45,7 +47,7 @@ export const DescriptionContainer = styled.div`
   p {
     color: ${theme.colors.gray[300]};
     line-height: 175%;
-    margin-top: ${theme.spacing.m};
+    margin: ${theme.spacing.m} 0 0;
   }
 `
 

+ 12 - 7
packages/app/src/views/VideoView/VideoView.tsx

@@ -1,5 +1,5 @@
 import React from 'react'
-import { RouteComponentProps } from '@reach/router'
+import { RouteComponentProps, useParams } from '@reach/router'
 import {
   ActionsContainer,
   Container,
@@ -19,26 +19,31 @@ import { Button, VideoPlayer } from '@/shared/components'
 import { formatDateAgo } from '@/utils/time'
 import { formatNumber } from '@/utils/number'
 import { useQuery } from '@apollo/client'
-import { GET_NEWEST_VIDEOS } from '@/api/queries'
-import { GetNewestVideos } from '@/api/queries/__generated__/GetNewestVideos'
+import { GET_VIDEO } from '@/api/queries'
+import { GetVideo, GetVideoVariables } from '@/api/queries/__generated__/GetVideo'
 
 const VideoView: React.FC<RouteComponentProps> = () => {
-  const { loading, data } = useQuery<GetNewestVideos>(GET_NEWEST_VIDEOS)
+  const { id } = useParams()
+  const { loading, data } = useQuery<GetVideo, GetVideoVariables>(GET_VIDEO, { variables: { id } })
 
   if (loading || !data) {
     return <p>Loading</p>
   }
 
-  const { title, views, publishedOnJoystreamAt, channel, description } = data.videos[0]
+  if (!data.video) {
+    return <p>Video not found</p>
+  }
+
+  const { title, views, publishedOnJoystreamAt, channel, description } = data.video
 
   const descriptionLines = description.split('\n')
 
-  const moreVideos = Array.from({ length: 10 }, () => data.videos[0])
+  const moreVideos = Array.from({ length: 10 }, () => data.video as NonNullable<typeof data.video>)
 
   return (
     <Container>
       <PlayerContainer>
-        <VideoPlayer src="https://js-video-example.s3.eu-central-1.amazonaws.com/waves.mp4" height={700} autoplay />
+        <VideoPlayer src={data.video.media.location} height={700} autoplay />
       </PlayerContainer>
       <InfoContainer>
         <TitleActionsContainer>