ソースを参照

fix broken videos on channel view (#1285)

* fix broken videos on channel view

* remove custom query
Klaudiusz Dembler 3 年 前
コミット
33f9533aa8

+ 28 - 0
src/api/hooks/video.ts

@@ -2,6 +2,7 @@ import { MutationHookOptions, QueryHookOptions } from '@apollo/client'
 
 import {
   AddVideoViewMutation,
+  AssetAvailability,
   GetBasicVideosQuery,
   GetBasicVideosQueryVariables,
   GetMostViewedVideosAllTimeQuery,
@@ -11,6 +12,7 @@ import {
   GetVideoQuery,
   GetVideosQuery,
   GetVideosQueryVariables,
+  VideoOrderByInput,
   useAddVideoViewMutation,
   useGetBasicVideosQuery,
   useGetMostViewedVideosAllTimeQuery,
@@ -40,6 +42,32 @@ export const useVideos = (variables?: GetVideosQueryVariables, opts?: VideosOpts
   }
 }
 
+export const useChannelPreviewVideos = (
+  channelId: string | null | undefined,
+  opts?: QueryHookOptions<GetVideosQuery>
+) => {
+  const { data, ...rest } = useGetVideosQuery({
+    ...opts,
+    variables: {
+      where: {
+        channelId_eq: channelId,
+        isPublic_eq: true,
+        isCensored_eq: false,
+        thumbnailPhotoAvailability_eq: AssetAvailability.Accepted,
+        mediaAvailability_eq: AssetAvailability.Accepted,
+      },
+      orderBy: VideoOrderByInput.CreatedAtDesc,
+      offset: 0,
+      limit: 10,
+    },
+    skip: !channelId || opts?.skip,
+  })
+  return {
+    videos: data?.videos,
+    ...rest,
+  }
+}
+
 type AddVideoViewOpts = Omit<MutationHookOptions<AddVideoViewMutation>, 'variables'>
 export const useAddVideoView = (opts?: AddVideoViewOpts) => {
   const [addVideoView, rest] = useAddVideoViewMutation({

+ 16 - 29
src/components/ChannelWithVideos/ChannelWithVideos.tsx

@@ -1,8 +1,6 @@
 import React, { FC, useState } from 'react'
 
-import { useChannel } from '@/api/hooks'
-import { GetVideosConnectionDocument, GetVideosConnectionQuery, GetVideosConnectionQueryVariables } from '@/api/queries'
-import { useInfiniteGrid } from '@/components/InfiniteGrids/useInfiniteGrid'
+import { useChannel, useChannelPreviewVideos } from '@/api/hooks'
 import { VideoTile } from '@/components/VideoTile'
 import { absoluteRoutes } from '@/config/routes'
 import { useHandleFollowChannel } from '@/hooks'
@@ -26,47 +24,36 @@ type ChannelWithVideosProps = {
 }
 
 const INITIAL_VIDEOS_PER_ROW = 4
-const INITAL_ROWS = 1
+const INITIAL_ROWS = 1
 
 export const ChannelWithVideos: FC<ChannelWithVideosProps> = ({ channelId }) => {
   const [videosPerRow, setVideosPerRow] = useState(INITIAL_VIDEOS_PER_ROW)
-  const { channel, loading } = useChannel(channelId || '')
+  const { channel, loading: channelLoading, error: channelError } = useChannel(channelId || '', {
+    skip: !channelId,
+    onError: (error) => SentryLogger.error('Failed to fetch channel', 'ChannelWithVideos', error),
+  })
+  const { videos, loading: videosLoading, error: videosError } = useChannelPreviewVideos(channelId, {
+    onError: (error) => SentryLogger.error('Failed to fetch videos', 'ChannelWithVideos', error),
+  })
 
   const { url: avatarUrl, isLoadingAsset: isLoadingAvatar } = useAsset({ entity: channel, assetType: AssetType.AVATAR })
   const { toggleFollowing, isFollowing } = useHandleFollowChannel(channelId)
-  const { displayedItems, placeholdersCount, error } = useInfiniteGrid<
-    GetVideosConnectionQuery,
-    GetVideosConnectionQuery['videosConnection'],
-    GetVideosConnectionQueryVariables
-  >({
-    query: GetVideosConnectionDocument,
-    isReady: !!channelId,
-    skipCount: 0,
-    queryVariables: {
-      where: {
-        channelId_eq: channelId,
-        isPublic_eq: true,
-        isCensored_eq: false,
-      },
-    },
-    targetRowsCount: INITAL_ROWS,
-    dataAccessor: (rawData) => rawData?.videosConnection,
-    itemsPerRow: videosPerRow,
-    onError: (error) => SentryLogger.error('Failed to fetch videos', 'ChannelWithVideos', error),
-  })
 
-  const placeholderItems = Array.from({ length: placeholdersCount }, () => ({ id: undefined }))
+  const targetItemsCount = videosPerRow * INITIAL_ROWS
+  const displayedVideos = (videos || []).slice(0, targetItemsCount)
+  const placeholderItems = videosLoading ? Array.from({ length: targetItemsCount }, () => ({ id: undefined })) : []
+
   const gridContent = (
     <>
-      {[...displayedItems, ...placeholderItems]?.map((video, idx) => (
+      {[...displayedVideos, ...placeholderItems].map((video, idx) => (
         <VideoTile id={video.id} key={`channels-with-videos-${idx}`} showChannel />
       ))}
     </>
   )
 
-  const isLoading = !channelId || loading
+  const isLoading = !channelId || channelLoading
 
-  if (error) {
+  if (channelError || videosError) {
     return null
   }
 

+ 8 - 7
src/components/OfficialJoystreamUpdate.tsx

@@ -1,20 +1,21 @@
 import React from 'react'
 
-import { useVideos } from '@/api/hooks'
+import { useChannelPreviewVideos } from '@/api/hooks'
 import { VideoGallery } from '@/components/VideoGallery'
 import { readEnv } from '@/config/envs'
+import { SentryLogger } from '@/utils/logs'
 
 const channelId = readEnv('OFFICIAL_JOYSTREAM_CHANNEL_ID')
-const MAX_VIDEOS = 10
 
 export const OfficialJoystreamUpdate = () => {
-  const { videos, loading } = useVideos({
-    where: {
-      channelId_eq: channelId,
-    },
-    limit: MAX_VIDEOS,
+  const { videos, loading, error } = useChannelPreviewVideos(channelId, {
+    onError: (error) => SentryLogger.error('Failed to fetch videos', 'OfficialJoystreamUpdate', error),
   })
 
+  if (error) {
+    return null
+  }
+
   return (
     <section>
       <VideoGallery title="Official Joystream updates" videos={videos || []} loading={loading} />