소스 검색

Not found video and channel fallbacks (#1191)

* Not found video and channel fallbacks

Fixes: #1180

* Flex container

* remove unused export
Diego Cardenas 3 년 전
부모
커밋
ef0c5ad995

+ 3 - 2
src/shared/components/EmptyFallback/EmptyFallback.tsx

@@ -11,6 +11,7 @@ export type EmptyFallbackProps = {
   subtitle?: string | null
   variant?: EmptyFallbackSizes
   button?: ReactNode
+  className?: string
 }
 
 const ILLUSTRATION_SIZES = {
@@ -24,8 +25,8 @@ const ILLUSTRATION_SIZES = {
   },
 }
 
-export const EmptyFallback: FC<EmptyFallbackProps> = ({ title, subtitle, variant = 'large', button }) => (
-  <Container variant={variant}>
+export const EmptyFallback: FC<EmptyFallbackProps> = ({ title, subtitle, variant = 'large', button, className }) => (
+  <Container className={className} variant={variant}>
     <SvgEmptyStateIllustration width={ILLUSTRATION_SIZES[variant].width} height={ILLUSTRATION_SIZES[variant].height} />
     <Message>
       {title && <Title variant={variant === 'large' ? 'h4' : 'body1'}>{title}</Title>}

+ 8 - 1
src/views/viewer/ChannelView/ChannelView.style.tsx

@@ -1,7 +1,7 @@
 import styled from '@emotion/styled'
 import { fluidRange } from 'polished'
 
-import { ChannelLink } from '@/components'
+import { ChannelLink, TOP_NAVBAR_HEIGHT } from '@/components'
 import { Button, IconButton, SkeletonLoader, Tabs, Text, TextField } from '@/shared/components'
 import { colors, media, sizes, transitions, typography } from '@/shared/theme'
 
@@ -227,3 +227,10 @@ export const UnfollowDescriptionAccentText = styled.span`
   font-weight: ${typography.weights.regular};
   color: ${colors.gray[50]};
 `
+
+export const NotFoundChannelContainer = styled.div`
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: calc(100vh - ${TOP_NAVBAR_HEIGHT}px);
+`

+ 15 - 2
src/views/viewer/ChannelView/ChannelView.tsx

@@ -17,9 +17,10 @@ import {
   useSearchLazyQuery,
 } from '@/api/queries'
 import { LimitedWidthContainer, VideoTile, ViewWrapper } from '@/components'
+import { absoluteRoutes } from '@/config/routes'
 import { SORT_OPTIONS } from '@/config/sorting'
 import { AssetType, useAsset, useDialog, usePersonalDataStore } from '@/providers'
-import { ChannelCover, EmptyFallback, Grid, Pagination, Select, Text } from '@/shared/components'
+import { Button, ChannelCover, EmptyFallback, Grid, Pagination, Select, Text } from '@/shared/components'
 import { SvgGlyphCheck, SvgGlyphPlus, SvgGlyphSearch } from '@/shared/icons'
 import { transitions } from '@/shared/theme'
 import { Logger } from '@/utils/logger'
@@ -27,6 +28,7 @@ import { formatNumberShort } from '@/utils/number'
 
 import { ChannelAbout } from './ChannelAbout'
 import {
+  NotFoundChannelContainer,
   PaginationContainer,
   SearchButton,
   SearchContainer,
@@ -258,7 +260,18 @@ export const ChannelView: React.FC = () => {
   }, [])
 
   if (!loading && !channel) {
-    return <span>Channel not found</span>
+    return (
+      <NotFoundChannelContainer>
+        <EmptyFallback
+          title="Channel not found"
+          button={
+            <Button variant="secondary" size="large" to={absoluteRoutes.viewer.index()}>
+              Go back to home page
+            </Button>
+          }
+        />
+      </NotFoundChannelContainer>
+    )
   }
   return (
     <ViewWrapper>

+ 8 - 1
src/views/viewer/VideoView/VideoView.style.tsx

@@ -1,7 +1,7 @@
 import styled from '@emotion/styled'
 import { fluidRange } from 'polished'
 
-import { ViewWrapper } from '@/components'
+import { TOP_NAVBAR_HEIGHT, ViewWrapper } from '@/components'
 import { SkeletonLoader, Text } from '@/shared/components'
 import { breakpoints, colors, media, sizes, typography } from '@/shared/theme'
 
@@ -97,3 +97,10 @@ export const LicenseContainer = styled.div`
     color: ${colors.gray[500]};
   }
 `
+
+export const NotFoundVideoContainer = styled.div`
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: calc(100vh - ${TOP_NAVBAR_HEIGHT}px);
+`

+ 15 - 2
src/views/viewer/VideoView/VideoView.tsx

@@ -4,10 +4,11 @@ import { useParams } from 'react-router-dom'
 
 import { useAddVideoView, useVideo } from '@/api/hooks'
 import { ChannelLink, InfiniteVideoGrid } from '@/components'
+import { absoluteRoutes } from '@/config/routes'
 import knownLicenses from '@/data/knownLicenses.json'
 import { useRouterQuery } from '@/hooks'
 import { AssetType, useAsset, usePersonalDataStore } from '@/providers'
-import { SkeletonLoader, VideoPlayer } from '@/shared/components'
+import { Button, EmptyFallback, SkeletonLoader, VideoPlayer } from '@/shared/components'
 import { transitions } from '@/shared/theme'
 import { Logger } from '@/utils/logger'
 import { formatVideoViewsAndDate } from '@/utils/video'
@@ -21,6 +22,7 @@ import {
   Meta,
   MoreVideosContainer,
   MoreVideosHeader,
+  NotFoundVideoContainer,
   PlayerContainer,
   PlayerSkeletonLoader,
   PlayerWrapper,
@@ -102,7 +104,18 @@ export const VideoView: React.FC = () => {
   }
 
   if (!loading && !video) {
-    return <p>Video not found</p>
+    return (
+      <NotFoundVideoContainer>
+        <EmptyFallback
+          title="Video not found"
+          button={
+            <Button variant="secondary" size="large" to={absoluteRoutes.viewer.index()}>
+              Go back to home page
+            </Button>
+          }
+        />
+      </NotFoundVideoContainer>
+    )
   }
 
   const foundLicense = knownLicenses.find((license) => license.code === video?.license?.code)