Browse Source

Popular videos query (#1057)

* Add orion queries for most viewed videos and channels

* Implement popular section on home view
Rafał Pawłow 3 years ago
parent
commit
4e471f0123

+ 2 - 1
src/api/client/cache.ts

@@ -20,6 +20,7 @@ const getVideoKeyArgs = (args: GetVideosConnectionQueryVariables | null) => {
   const channelId = args?.where?.channelId_eq || ''
   const categoryId = args?.where?.categoryId_eq || ''
   const idEq = args?.where?.id_eq || ''
+  const idIn = args?.where?.id_in || []
   const isPublic = args?.where?.isPublic_eq ?? ''
   const channelIdIn = args?.where?.channelId_in ? JSON.stringify(args.where.channelId_in) : ''
   const createdAtGte = args?.where?.createdAt_gte ? JSON.stringify(args.where.createdAt_gte) : ''
@@ -30,7 +31,7 @@ const getVideoKeyArgs = (args: GetVideosConnectionQueryVariables | null) => {
     return `${createdAtGte}:${channelIdIn}`
   }
 
-  return `${onlyCount}:${channelId}:${categoryId}:${channelIdIn}:${createdAtGte}:${isPublic}:${idEq}:${sorting}`
+  return `${onlyCount}:${channelId}:${categoryId}:${channelIdIn}:${createdAtGte}:${isPublic}:${idEq}:${idIn}:${sorting}`
 }
 
 const createDateHandler = () => ({

+ 44 - 0
src/api/hooks/channel.ts

@@ -1,4 +1,5 @@
 import { MutationHookOptions, QueryHookOptions } from '@apollo/client'
+import { useMemo } from 'react'
 
 import {
   AssetAvailability,
@@ -7,12 +8,15 @@ import {
   GetChannelQuery,
   GetChannelsQuery,
   GetChannelsQueryVariables,
+  GetMostViewedChannelsQuery,
+  GetMostViewedChannelsQueryVariables,
   GetVideoCountQuery,
   UnfollowChannelMutation,
   useFollowChannelMutation,
   useGetBasicChannelQuery,
   useGetChannelQuery,
   useGetChannelsQuery,
+  useGetMostViewedChannelsQuery,
   useGetVideoCountQuery,
   useUnfollowChannelMutation,
 } from '@/api/queries'
@@ -122,3 +126,43 @@ export const useUnfollowChannel = (opts?: UnfollowChannelOpts) => {
     ...rest,
   }
 }
+
+type MostPopularChannelsOpts = QueryHookOptions<GetMostViewedChannelsQuery>
+export const useMostViewedChannelsIds = (
+  variables?: GetMostViewedChannelsQueryVariables,
+  opts?: MostPopularChannelsOpts
+) => {
+  const { data, ...rest } = useGetMostViewedChannelsQuery({ ...opts, variables })
+  return {
+    mostViewedChannels: data?.mostViewedChannels,
+    ...rest,
+  }
+}
+
+export const useMostViewedChannels = (
+  variables?: GetMostViewedChannelsQueryVariables,
+  opts?: MostPopularChannelsOpts
+) => {
+  const { mostViewedChannels } = useMostViewedChannelsIds(variables, opts)
+
+  const mostViewedChannelsIds = useMemo(() => {
+    if (mostViewedChannels) {
+      return mostViewedChannels.map((item) => item.id)
+    }
+    return null
+  }, [mostViewedChannels])
+
+  const { channels, ...rest } = useChannels(
+    {
+      where: {
+        id_in: mostViewedChannelsIds,
+      },
+    },
+    { skip: !mostViewedChannelsIds }
+  )
+
+  return {
+    channels,
+    ...rest,
+  }
+}

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

@@ -1,14 +1,18 @@
 import { MutationHookOptions, QueryHookOptions } from '@apollo/client'
+import { useMemo } from 'react'
 
 import {
   AddVideoViewMutation,
   GetBasicVideosQuery,
   GetBasicVideosQueryVariables,
+  GetMostViewedVideosQuery,
+  GetMostViewedVideosQueryVariables,
   GetVideoQuery,
   GetVideosQuery,
   GetVideosQueryVariables,
   useAddVideoViewMutation,
   useGetBasicVideosQuery,
+  useGetMostViewedVideosQuery,
   useGetVideoQuery,
   useGetVideosQuery,
 } from '@/api/queries'
@@ -64,3 +68,44 @@ export const useBasicVideos = (variables?: GetBasicVideosQueryVariables, opts?:
     ...rest,
   }
 }
+
+type MostViewedVideosOpts = QueryHookOptions<GetMostViewedVideosQuery>
+export const useMostViewedVideosIds = (variables?: GetMostViewedVideosQueryVariables, opts?: MostViewedVideosOpts) => {
+  const { data, ...rest } = useGetMostViewedVideosQuery({ ...opts, variables })
+  return {
+    mostViewedVideos: data?.mostViewedVideos,
+    ...rest,
+  }
+}
+
+export const useMostViewedVideos = (variables?: GetMostViewedVideosQueryVariables, opts?: MostViewedVideosOpts) => {
+  const { mostViewedVideos } = useMostViewedVideosIds(variables, opts)
+
+  const mostViewedVideosIds = useMemo(() => {
+    if (mostViewedVideos) {
+      return mostViewedVideos.map((item) => item.id)
+    }
+    return null
+  }, [mostViewedVideos])
+
+  const { videos, ...rest } = useVideos(
+    {
+      where: {
+        id_in: mostViewedVideosIds,
+      },
+    },
+    { skip: !mostViewedVideosIds }
+  )
+
+  const sortedVideos = useMemo(() => {
+    if (videos) {
+      return [...videos].sort((a, b) => (b.views && a.views ? b.views - a.views : 0))
+    }
+    return null
+  }, [videos])
+
+  return {
+    videos: sortedVideos,
+    ...rest,
+  }
+}

+ 14 - 0
src/api/queries/__generated__/baseTypes.generated.ts

@@ -276,6 +276,10 @@ export type Query = {
   channelsConnection: ChannelConnection
   membershipByUniqueInput?: Maybe<Membership>
   memberships: Array<Membership>
+  /** Get list of channels with most views in given period */
+  mostViewedChannels?: Maybe<Array<EntityViewsInfo>>
+  /** Get list of most viewed videos in given period */
+  mostViewedVideos?: Maybe<Array<EntityViewsInfo>>
   search: Array<SearchFtsOutput>
   videoByUniqueInput?: Maybe<Video>
   videoCategories: Array<VideoCategory>
@@ -332,6 +336,16 @@ export type QueryMembershipsArgs = {
   where: MembershipWhereInput
 }
 
+export type QueryMostViewedChannelsArgs = {
+  period: Scalars['Int']
+  limit?: Maybe<Scalars['Int']>
+}
+
+export type QueryMostViewedVideosArgs = {
+  period: Scalars['Int']
+  limit?: Maybe<Scalars['Int']>
+}
+
 export type QuerySearchArgs = {
   limit?: Maybe<Scalars['Int']>
   text: Scalars['String']

+ 105 - 47
src/api/queries/__generated__/channels.generated.tsx

@@ -87,6 +87,15 @@ export type GetChannelsConnectionQuery = {
   }
 }
 
+export type GetChannelViewsQueryVariables = Types.Exact<{
+  channelId: Types.Scalars['ID']
+}>
+
+export type GetChannelViewsQuery = {
+  __typename?: 'Query'
+  channelViews?: Types.Maybe<{ __typename?: 'EntityViewsInfo'; id: string; views: number }>
+}
+
 export type GetChannelFollowsQueryVariables = Types.Exact<{
   channelId: Types.Scalars['ID']
 }>
@@ -105,15 +114,6 @@ export type GetBatchedChannelFollowsQuery = {
   batchedChannelFollows: Array<Types.Maybe<{ __typename?: 'ChannelFollowsInfo'; id: string; follows: number }>>
 }
 
-export type GetChannelViewsQueryVariables = Types.Exact<{
-  channelId: Types.Scalars['ID']
-}>
-
-export type GetChannelViewsQuery = {
-  __typename?: 'Query'
-  channelViews?: Types.Maybe<{ __typename?: 'EntityViewsInfo'; id: string; views: number }>
-}
-
 export type GetBatchedChannelViewsQueryVariables = Types.Exact<{
   channelIdList: Array<Types.Scalars['ID']> | Types.Scalars['ID']
 }>
@@ -141,6 +141,16 @@ export type UnfollowChannelMutation = {
   unfollowChannel: { __typename?: 'ChannelFollowsInfo'; id: string; follows: number }
 }
 
+export type GetMostViewedChannelsQueryVariables = Types.Exact<{
+  viewedWithinDays: Types.Scalars['Int']
+  limit?: Types.Maybe<Types.Scalars['Int']>
+}>
+
+export type GetMostViewedChannelsQuery = {
+  __typename?: 'Query'
+  mostViewedChannels?: Types.Maybe<Array<{ __typename?: 'EntityViewsInfo'; id: string; views: number }>>
+}
+
 export const BasicChannelFieldsFragmentDoc = gql`
   fragment BasicChannelFields on Channel {
     id
@@ -389,6 +399,44 @@ export type GetChannelsConnectionQueryResult = Apollo.QueryResult<
   GetChannelsConnectionQuery,
   GetChannelsConnectionQueryVariables
 >
+export const GetChannelViewsDocument = gql`
+  query GetChannelViews($channelId: ID!) {
+    channelViews(channelId: $channelId) {
+      id
+      views
+    }
+  }
+`
+
+/**
+ * __useGetChannelViewsQuery__
+ *
+ * To run a query within a React component, call `useGetChannelViewsQuery` and pass it any options that fit your needs.
+ * When your component renders, `useGetChannelViewsQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useGetChannelViewsQuery({
+ *   variables: {
+ *      channelId: // value for 'channelId'
+ *   },
+ * });
+ */
+export function useGetChannelViewsQuery(
+  baseOptions: Apollo.QueryHookOptions<GetChannelViewsQuery, GetChannelViewsQueryVariables>
+) {
+  return Apollo.useQuery<GetChannelViewsQuery, GetChannelViewsQueryVariables>(GetChannelViewsDocument, baseOptions)
+}
+export function useGetChannelViewsLazyQuery(
+  baseOptions?: Apollo.LazyQueryHookOptions<GetChannelViewsQuery, GetChannelViewsQueryVariables>
+) {
+  return Apollo.useLazyQuery<GetChannelViewsQuery, GetChannelViewsQueryVariables>(GetChannelViewsDocument, baseOptions)
+}
+export type GetChannelViewsQueryHookResult = ReturnType<typeof useGetChannelViewsQuery>
+export type GetChannelViewsLazyQueryHookResult = ReturnType<typeof useGetChannelViewsLazyQuery>
+export type GetChannelViewsQueryResult = Apollo.QueryResult<GetChannelViewsQuery, GetChannelViewsQueryVariables>
 export const GetChannelFollowsDocument = gql`
   query GetChannelFollows($channelId: ID!) {
     channelFollows(channelId: $channelId) {
@@ -480,44 +528,6 @@ export type GetBatchedChannelFollowsQueryResult = Apollo.QueryResult<
   GetBatchedChannelFollowsQuery,
   GetBatchedChannelFollowsQueryVariables
 >
-export const GetChannelViewsDocument = gql`
-  query GetChannelViews($channelId: ID!) {
-    channelViews(channelId: $channelId) {
-      id
-      views
-    }
-  }
-`
-
-/**
- * __useGetChannelViewsQuery__
- *
- * To run a query within a React component, call `useGetChannelViewsQuery` and pass it any options that fit your needs.
- * When your component renders, `useGetChannelViewsQuery` returns an object from Apollo Client that contains loading, error, and data properties
- * you can use to render your UI.
- *
- * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
- *
- * @example
- * const { data, loading, error } = useGetChannelViewsQuery({
- *   variables: {
- *      channelId: // value for 'channelId'
- *   },
- * });
- */
-export function useGetChannelViewsQuery(
-  baseOptions: Apollo.QueryHookOptions<GetChannelViewsQuery, GetChannelViewsQueryVariables>
-) {
-  return Apollo.useQuery<GetChannelViewsQuery, GetChannelViewsQueryVariables>(GetChannelViewsDocument, baseOptions)
-}
-export function useGetChannelViewsLazyQuery(
-  baseOptions?: Apollo.LazyQueryHookOptions<GetChannelViewsQuery, GetChannelViewsQueryVariables>
-) {
-  return Apollo.useLazyQuery<GetChannelViewsQuery, GetChannelViewsQueryVariables>(GetChannelViewsDocument, baseOptions)
-}
-export type GetChannelViewsQueryHookResult = ReturnType<typeof useGetChannelViewsQuery>
-export type GetChannelViewsLazyQueryHookResult = ReturnType<typeof useGetChannelViewsLazyQuery>
-export type GetChannelViewsQueryResult = Apollo.QueryResult<GetChannelViewsQuery, GetChannelViewsQueryVariables>
 export const GetBatchedChannelViewsDocument = gql`
   query GetBatchedChannelViews($channelIdList: [ID!]!) {
     batchedChannelsViews(channelIdList: $channelIdList) {
@@ -647,3 +657,51 @@ export type UnfollowChannelMutationOptions = Apollo.BaseMutationOptions<
   UnfollowChannelMutation,
   UnfollowChannelMutationVariables
 >
+export const GetMostViewedChannelsDocument = gql`
+  query GetMostViewedChannels($viewedWithinDays: Int!, $limit: Int) {
+    mostViewedChannels(period: $viewedWithinDays, limit: $limit) {
+      id
+      views
+    }
+  }
+`
+
+/**
+ * __useGetMostViewedChannelsQuery__
+ *
+ * To run a query within a React component, call `useGetMostViewedChannelsQuery` and pass it any options that fit your needs.
+ * When your component renders, `useGetMostViewedChannelsQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useGetMostViewedChannelsQuery({
+ *   variables: {
+ *      viewedWithinDays: // value for 'viewedWithinDays'
+ *      limit: // value for 'limit'
+ *   },
+ * });
+ */
+export function useGetMostViewedChannelsQuery(
+  baseOptions: Apollo.QueryHookOptions<GetMostViewedChannelsQuery, GetMostViewedChannelsQueryVariables>
+) {
+  return Apollo.useQuery<GetMostViewedChannelsQuery, GetMostViewedChannelsQueryVariables>(
+    GetMostViewedChannelsDocument,
+    baseOptions
+  )
+}
+export function useGetMostViewedChannelsLazyQuery(
+  baseOptions?: Apollo.LazyQueryHookOptions<GetMostViewedChannelsQuery, GetMostViewedChannelsQueryVariables>
+) {
+  return Apollo.useLazyQuery<GetMostViewedChannelsQuery, GetMostViewedChannelsQueryVariables>(
+    GetMostViewedChannelsDocument,
+    baseOptions
+  )
+}
+export type GetMostViewedChannelsQueryHookResult = ReturnType<typeof useGetMostViewedChannelsQuery>
+export type GetMostViewedChannelsLazyQueryHookResult = ReturnType<typeof useGetMostViewedChannelsLazyQuery>
+export type GetMostViewedChannelsQueryResult = Apollo.QueryResult<
+  GetMostViewedChannelsQuery,
+  GetMostViewedChannelsQueryVariables
+>

+ 58 - 0
src/api/queries/__generated__/videos.generated.tsx

@@ -123,6 +123,16 @@ export type GetBatchedVideoViewsQuery = {
   batchedVideoViews: Array<Types.Maybe<{ __typename?: 'EntityViewsInfo'; id: string; views: number }>>
 }
 
+export type GetMostViewedVideosQueryVariables = Types.Exact<{
+  viewedWithinDays: Types.Scalars['Int']
+  limit?: Types.Maybe<Types.Scalars['Int']>
+}>
+
+export type GetMostViewedVideosQuery = {
+  __typename?: 'Query'
+  mostViewedVideos?: Types.Maybe<Array<{ __typename?: 'EntityViewsInfo'; id: string; views: number }>>
+}
+
 export type AddVideoViewMutationVariables = Types.Exact<{
   videoId: Types.Scalars['ID']
   channelId: Types.Scalars['ID']
@@ -466,6 +476,54 @@ export type GetBatchedVideoViewsQueryResult = Apollo.QueryResult<
   GetBatchedVideoViewsQuery,
   GetBatchedVideoViewsQueryVariables
 >
+export const GetMostViewedVideosDocument = gql`
+  query GetMostViewedVideos($viewedWithinDays: Int!, $limit: Int) {
+    mostViewedVideos(period: $viewedWithinDays, limit: $limit) {
+      id
+      views
+    }
+  }
+`
+
+/**
+ * __useGetMostViewedVideosQuery__
+ *
+ * To run a query within a React component, call `useGetMostViewedVideosQuery` and pass it any options that fit your needs.
+ * When your component renders, `useGetMostViewedVideosQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useGetMostViewedVideosQuery({
+ *   variables: {
+ *      viewedWithinDays: // value for 'viewedWithinDays'
+ *      limit: // value for 'limit'
+ *   },
+ * });
+ */
+export function useGetMostViewedVideosQuery(
+  baseOptions: Apollo.QueryHookOptions<GetMostViewedVideosQuery, GetMostViewedVideosQueryVariables>
+) {
+  return Apollo.useQuery<GetMostViewedVideosQuery, GetMostViewedVideosQueryVariables>(
+    GetMostViewedVideosDocument,
+    baseOptions
+  )
+}
+export function useGetMostViewedVideosLazyQuery(
+  baseOptions?: Apollo.LazyQueryHookOptions<GetMostViewedVideosQuery, GetMostViewedVideosQueryVariables>
+) {
+  return Apollo.useLazyQuery<GetMostViewedVideosQuery, GetMostViewedVideosQueryVariables>(
+    GetMostViewedVideosDocument,
+    baseOptions
+  )
+}
+export type GetMostViewedVideosQueryHookResult = ReturnType<typeof useGetMostViewedVideosQuery>
+export type GetMostViewedVideosLazyQueryHookResult = ReturnType<typeof useGetMostViewedVideosLazyQuery>
+export type GetMostViewedVideosQueryResult = Apollo.QueryResult<
+  GetMostViewedVideosQuery,
+  GetMostViewedVideosQueryVariables
+>
 export const AddVideoViewDocument = gql`
   mutation AddVideoView($videoId: ID!, $channelId: ID!) {
     addVideoView(videoId: $videoId, channelId: $channelId) {

+ 15 - 7
src/api/queries/channels.graphql

@@ -74,6 +74,14 @@ query GetChannelsConnection($first: Int, $after: String, $where: ChannelWhereInp
 
 ### Orion
 
+# modyfying this query name will need a sync-up in `src/api/client/resolvers.ts`
+query GetChannelViews($channelId: ID!) {
+  channelViews(channelId: $channelId) {
+    id
+    views
+  }
+}
+
 # modyfying this query name will need a sync-up in `src/api/client/resolvers.ts`
 query GetChannelFollows($channelId: ID!) {
   channelFollows(channelId: $channelId) {
@@ -88,13 +96,6 @@ query GetBatchedChannelFollows($channelIdList: [ID!]!) {
     follows
   }
 }
-# modyfying this query name will need a sync-up in `src/api/client/resolvers.ts`
-query GetChannelViews($channelId: ID!) {
-  channelViews(channelId: $channelId) {
-    id
-    views
-  }
-}
 
 query GetBatchedChannelViews($channelIdList: [ID!]!) {
   batchedChannelsViews(channelIdList: $channelIdList) {
@@ -116,3 +117,10 @@ mutation UnfollowChannel($channelId: ID!) {
     follows
   }
 }
+
+query GetMostViewedChannels($viewedWithinDays: Int!, $limit: Int) {
+  mostViewedChannels(period: $viewedWithinDays, limit: $limit) {
+    id
+    views
+  }
+}

+ 7 - 0
src/api/queries/videos.graphql

@@ -118,6 +118,13 @@ query GetBatchedVideoViews($videoIdList: [ID!]!) {
   }
 }
 
+query GetMostViewedVideos($viewedWithinDays: Int!, $limit: Int) {
+  mostViewedVideos(period: $viewedWithinDays, limit: $limit) {
+    id
+    views
+  }
+}
+
 mutation AddVideoView($videoId: ID!, $channelId: ID!) {
   addVideoView(videoId: $videoId, channelId: $channelId) {
     id

+ 10 - 0
src/api/schemas/orion.graphql

@@ -60,4 +60,14 @@ type Query {
   Get views count for a single video
   """
   videoViews(videoId: ID!): EntityViewsInfo
+
+  """
+  Get list of most viewed videos in given period
+  """
+  mostViewedVideos(period: Int!, limit: Int): [EntityViewsInfo!]
+
+  """
+  Get list of channels with most views in given period
+  """
+  mostViewedChannels(period: Int!, limit: Int): [EntityViewsInfo!]
 }

+ 3 - 0
src/components/InfiniteGrids/InfiniteVideoGrid.tsx

@@ -26,6 +26,7 @@ type InfiniteVideoGridProps = {
   isCensored?: boolean
   thumbnailPhotoAvailability?: AssetAvailability
   mediaAvailability?: AssetAvailability
+  idIn?: string[]
   skipCount?: number
   ready?: boolean
   showChannel?: boolean
@@ -51,6 +52,7 @@ export const InfiniteVideoGrid: React.FC<InfiniteVideoGridProps> = ({
   isCensored = false,
   thumbnailPhotoAvailability = AssetAvailability.Accepted,
   mediaAvailability = AssetAvailability.Accepted,
+  idIn,
   skipCount = 0,
   ready = true,
   showChannel = true,
@@ -68,6 +70,7 @@ export const InfiniteVideoGrid: React.FC<InfiniteVideoGridProps> = ({
       ...(categoryId ? { categoryId_eq: categoryId } : {}),
       ...(thumbnailPhotoAvailability ? { thumbnailPhotoAvailability_eq: thumbnailPhotoAvailability } : {}),
       ...(mediaAvailability ? { mediaAvailability_eq: mediaAvailability } : {}),
+      ...(idIn ? { id_in: idIn } : {}),
       isPublic_eq: isPublic,
       isCensored_eq: isCensored,
     },

+ 24 - 5
src/views/viewer/HomeView.tsx

@@ -1,7 +1,7 @@
 import styled from '@emotion/styled'
 import React from 'react'
 
-import useVideosConnection from '@/api/hooks/videosConnection'
+import { useMostViewedVideosIds, useVideosConnection } from '@/api/hooks'
 import {
   InfiniteVideoGrid,
   LimitedWidthContainer,
@@ -19,7 +19,13 @@ export const HomeView: React.FC = () => {
   const channelIdIn = followedChannels.map((channel) => channel.id)
   const anyFollowedChannels = channelIdIn.length > 0
 
-  const { videosConnection, loading, error } = useVideosConnection(
+  const { mostViewedVideos, loading: mostViewedVideosLoading, error: mostViewedVideosError } = useMostViewedVideosIds({
+    limit: 200,
+    viewedWithinDays: 30,
+  })
+  const mostViewedVideosIds = mostViewedVideos?.map((item) => item.id)
+
+  const { videosConnection, loading: followedLoading, error: followedError } = useVideosConnection(
     {
       where: {
         channelId_in: channelIdIn,
@@ -30,7 +36,7 @@ export const HomeView: React.FC = () => {
 
   const followedChannelsVideosCount = videosConnection?.totalCount
 
-  if (error) {
+  if (mostViewedVideosError || followedError) {
     return <ViewErrorFallback />
   }
 
@@ -38,8 +44,21 @@ export const HomeView: React.FC = () => {
     <LimitedWidthContainer big>
       <VideoHero />
       <Container className={transitions.names.slide}>
-        {!loading && followedChannelsVideosCount ? (
-          <StyledInfiniteVideoGrid title="Followed channels" channelIdIn={channelIdIn} ready={!loading} onDemand />
+        {!followedLoading && followedChannelsVideosCount ? (
+          <StyledInfiniteVideoGrid
+            title="Followed channels"
+            channelIdIn={channelIdIn}
+            ready={!followedLoading}
+            onDemand
+          />
+        ) : null}
+        {!mostViewedVideosLoading && mostViewedVideos?.length ? (
+          <StyledInfiniteVideoGrid
+            title="Popular on Joystream"
+            idIn={mostViewedVideosIds}
+            ready={!mostViewedVideosLoading}
+            onDemand
+          />
         ) : null}
         <OfficialJoystreamUpdate />
         <StyledInfiniteVideoGrid title="All content" onDemand />