Redesign responsive MyTube interface
This commit is contained in:
parent
90eb012e0d
commit
c4a772b1e3
23 changed files with 787 additions and 1119 deletions
|
|
@ -1,56 +1,24 @@
|
|||
import { useInfiniteQuery, useQuery } from '@tanstack/react-query'
|
||||
import { Link, useParams } from 'react-router-dom'
|
||||
import { getChannel, getFeed } from '../api/client'
|
||||
import Icon from '../components/Icon'
|
||||
import VideoCard from '../components/VideoCard'
|
||||
|
||||
function ChannelVideos() {
|
||||
const { channelId } = useParams<{ channelId: string }>()
|
||||
const id = Number(channelId)
|
||||
|
||||
const channelQuery = useQuery({ queryKey: ['channel', id], queryFn: () => getChannel(id) })
|
||||
|
||||
const feedQuery = useInfiniteQuery({
|
||||
queryKey: ['feed', 'channel', id],
|
||||
queryFn: ({ pageParam }) => getFeed({ channelId: id, cursor: pageParam }),
|
||||
initialPageParam: undefined as string | undefined,
|
||||
getNextPageParam: (lastPage) => lastPage.next_cursor ?? undefined,
|
||||
})
|
||||
|
||||
const valid = Number.isInteger(id) && id > 0
|
||||
const channelQuery = useQuery({ queryKey: ['channel', id], queryFn: () => getChannel(id), enabled: valid })
|
||||
const feedQuery = useInfiniteQuery({ queryKey: ['feed', 'channel', id], queryFn: ({ pageParam }) => getFeed({ channelId: id, cursor: pageParam }), initialPageParam: undefined as string | undefined, getNextPageParam: (lastPage) => lastPage.next_cursor ?? undefined, enabled: valid })
|
||||
const items = feedQuery.data?.pages.flatMap((page) => page.items) ?? []
|
||||
|
||||
return (
|
||||
<div className="feed-screen">
|
||||
<header>
|
||||
<div>
|
||||
<Link to="/channels" className="back-link">
|
||||
← Каналы
|
||||
</Link>
|
||||
<h1>{channelQuery.data?.title ?? 'Канал'}</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{feedQuery.isLoading && <p>Загрузка...</p>}
|
||||
{feedQuery.isError && <p className="error">Не удалось загрузить видео</p>}
|
||||
|
||||
<ul className="video-grid">
|
||||
{items.map((video) => (
|
||||
<VideoCard key={video.youtube_video_id} video={video} />
|
||||
))}
|
||||
</ul>
|
||||
|
||||
{!feedQuery.isLoading && items.length === 0 && <p>У этого канала пока нет синхронизированных видео.</p>}
|
||||
|
||||
{feedQuery.hasNextPage && (
|
||||
<button
|
||||
className="load-more"
|
||||
onClick={() => feedQuery.fetchNextPage()}
|
||||
disabled={feedQuery.isFetchingNextPage}
|
||||
>
|
||||
{feedQuery.isFetchingNextPage ? 'Загрузка...' : 'Показать ещё'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
return <section className="page feed-screen">
|
||||
<Link to="/channels" className="back-link"><Icon name="arrow" size={17} /> Каналы</Link>
|
||||
<div className="page-heading"><div><p className="eyebrow">Видео канала</p><h1>{channelQuery.data?.title ?? 'Канал'}</h1><p className="page-subtitle">Последние ролики из твоих подписок.</p></div></div>
|
||||
{(channelQuery.isError || feedQuery.isError || !valid) && <div className="empty-state" role="alert"><h2>Не удалось открыть канал</h2><Link to="/channels" className="button-primary">К списку каналов</Link></div>}
|
||||
{feedQuery.isLoading && <div className="video-grid">{Array.from({ length: 6 }, (_, index) => <div className="video-card skeleton-card" key={index}><div className="skeleton-thumbnail" /><div className="video-info"><div className="skeleton-line wide" /><div className="skeleton-line" /></div></div>)}</div>}
|
||||
{!feedQuery.isLoading && !feedQuery.isError && items.length > 0 && <ul className="video-grid">{items.map((video) => <VideoCard key={video.youtube_video_id} video={video} />)}</ul>}
|
||||
{!feedQuery.isLoading && !feedQuery.isError && items.length === 0 && <div className="empty-state"><h2>Пока нет видео</h2><p>Обнови ленту, чтобы получить новые ролики канала.</p></div>}
|
||||
{feedQuery.hasNextPage && <button className="button-secondary load-more" onClick={() => feedQuery.fetchNextPage()} disabled={feedQuery.isFetchingNextPage}>{feedQuery.isFetchingNextPage ? 'Загрузка…' : 'Показать ещё'}</button>}
|
||||
</section>
|
||||
}
|
||||
|
||||
export default ChannelVideos
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue