57 lines
1.9 KiB
TypeScript
57 lines
1.9 KiB
TypeScript
|
|
import { useInfiniteQuery, useQuery } from '@tanstack/react-query'
|
|||
|
|
import { Link, useParams } from 'react-router-dom'
|
|||
|
|
import { getChannel, getFeed } from '../api/client'
|
|||
|
|
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 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>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default ChannelVideos
|