detailpanel选集自动跟随

Šī revīzija ir iekļauta:
mtvpls
2026-02-26 12:24:02 +08:00
vecāks 34698e943c
revīzija 0beffc2fbd
3 mainīti faili ar 36 papildinājumiem un 2 dzēšanām
+1
Parādīt failu
@@ -8409,6 +8409,7 @@ function PlayPageClient() {
: undefined : undefined
} }
type={detail.type_name === '电影' ? 'movie' : 'tv'} type={detail.type_name === '电影' ? 'movie' : 'tv'}
currentEpisode={currentEpisodeIndex + 1}
cmsData={ cmsData={
// 非特殊源使用 cms 数据 // 非特殊源使用 cms 数据
// 但如果有豆瓣ID且不为0,则不传入cmsData,优先使用豆瓣数据 // 但如果有豆瓣ID且不为0,则不传入cmsData,优先使用豆瓣数据
+34 -2
Parādīt failu
@@ -21,6 +21,7 @@ interface DetailPanelProps {
tmdbId?: number; tmdbId?: number;
type?: 'movie' | 'tv'; type?: 'movie' | 'tv';
seasonNumber?: number; seasonNumber?: number;
currentEpisode?: number; // 当前集数(从1开始)
cmsData?: { cmsData?: {
desc?: string; desc?: string;
episodes?: string[]; episodes?: string[];
@@ -78,6 +79,7 @@ const DetailPanel: React.FC<DetailPanelProps> = ({
tmdbId, tmdbId,
type = 'movie', type = 'movie',
seasonNumber, seasonNumber,
currentEpisode,
cmsData, cmsData,
sourceId, sourceId,
source, source,
@@ -651,6 +653,30 @@ const DetailPanel: React.FC<DetailPanelProps> = ({
fetchSeasonData(); fetchSeasonData();
}, [detailData?.tmdbId, detailData?.mediaType, detailData?.seasonNumber, seasonsLoaded]); }, [detailData?.tmdbId, detailData?.mediaType, detailData?.seasonNumber, seasonsLoaded]);
// 自动滚动到当前集数
useEffect(() => {
if (!currentEpisode || !seasonData?.episodes || !episodesScrollRef.current || currentSource !== 'tmdb') {
return;
}
// 等待 DOM 更新后再滚动
const timer = setTimeout(() => {
const episodeElement = document.getElementById(`episode-${currentEpisode}`);
if (episodeElement && episodesScrollRef.current) {
// 计算滚动位置,使当前集数居中显示
const container = episodesScrollRef.current;
const elementLeft = episodeElement.offsetLeft;
const elementWidth = episodeElement.offsetWidth;
const containerWidth = container.offsetWidth;
const scrollLeft = elementLeft - (containerWidth / 2) + (elementWidth / 2);
container.scrollLeft = scrollLeft;
}
}, 100);
return () => clearTimeout(timer);
}, [currentEpisode, seasonData?.episodes, currentSource]);
// 异步获取演职人员信息(仅TMDB) // 异步获取演职人员信息(仅TMDB)
useEffect(() => { useEffect(() => {
if (!detailData?.tmdbId || !detailData?.mediaType || currentSource !== 'tmdb') { if (!detailData?.tmdbId || !detailData?.mediaType || currentSource !== 'tmdb') {
@@ -1212,13 +1238,19 @@ const DetailPanel: React.FC<DetailPanelProps> = ({
scrollBehavior: isDragging ? 'auto' : 'smooth' scrollBehavior: isDragging ? 'auto' : 'smooth'
}} }}
> >
<div className="flex gap-3 pb-2"> <div className="flex gap-3 py-2">
{seasonData.episodes.map((episode: Episode) => { {seasonData.episodes.map((episode: Episode) => {
const isExpanded = expandedEpisodes.has(episode.id); const isExpanded = expandedEpisodes.has(episode.id);
const isCurrentEpisode = currentEpisode === episode.episode_number;
return ( return (
<div <div
key={episode.id} key={episode.id}
className="flex-shrink-0 w-64 p-3 rounded bg-gray-50 dark:bg-gray-800" id={`episode-${episode.episode_number}`}
className={`flex-shrink-0 w-64 p-3 rounded ${
isCurrentEpisode
? 'bg-green-100 dark:bg-green-900/30 ring-2 ring-green-500'
: 'bg-gray-50 dark:bg-gray-800'
}`}
style={{ pointerEvents: isDragging ? 'none' : 'auto' }} style={{ pointerEvents: isDragging ? 'none' : 'auto' }}
> >
{episode.still_path && ( {episode.still_path && (
+1
Parādīt failu
@@ -1522,6 +1522,7 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(function VideoCard
tmdbId={tmdb_id} tmdbId={tmdb_id}
type={actualSearchType as 'movie' | 'tv'} type={actualSearchType as 'movie' | 'tv'}
seasonNumber={seasonNumber} seasonNumber={seasonNumber}
currentEpisode={currentEpisode}
cmsData={cmsData} cmsData={cmsData}
sourceId={id} sourceId={id}
source={source} source={source}