mirror of
https://github.com/MoonTechLab/LunaTV.git
synced 2026-05-19 04:17:29 +08:00
feat: show episode titles
This commit is contained in:
@@ -1706,25 +1706,25 @@ function PlayPageClient() {
|
|||||||
<div className='flex justify-center space-x-2 mb-4'>
|
<div className='flex justify-center space-x-2 mb-4'>
|
||||||
<div
|
<div
|
||||||
className={`w-3 h-3 rounded-full transition-all duration-500 ${loadingStage === 'searching' || loadingStage === 'fetching'
|
className={`w-3 h-3 rounded-full transition-all duration-500 ${loadingStage === 'searching' || loadingStage === 'fetching'
|
||||||
? 'bg-green-500 scale-125'
|
? 'bg-green-500 scale-125'
|
||||||
: loadingStage === 'preferring' ||
|
: loadingStage === 'preferring' ||
|
||||||
loadingStage === 'ready'
|
loadingStage === 'ready'
|
||||||
? 'bg-green-500'
|
? 'bg-green-500'
|
||||||
: 'bg-gray-300'
|
: 'bg-gray-300'
|
||||||
}`}
|
}`}
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div
|
||||||
className={`w-3 h-3 rounded-full transition-all duration-500 ${loadingStage === 'preferring'
|
className={`w-3 h-3 rounded-full transition-all duration-500 ${loadingStage === 'preferring'
|
||||||
? 'bg-green-500 scale-125'
|
? 'bg-green-500 scale-125'
|
||||||
: loadingStage === 'ready'
|
: loadingStage === 'ready'
|
||||||
? 'bg-green-500'
|
? 'bg-green-500'
|
||||||
: 'bg-gray-300'
|
: 'bg-gray-300'
|
||||||
}`}
|
}`}
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div
|
||||||
className={`w-3 h-3 rounded-full transition-all duration-500 ${loadingStage === 'ready'
|
className={`w-3 h-3 rounded-full transition-all duration-500 ${loadingStage === 'ready'
|
||||||
? 'bg-green-500 scale-125'
|
? 'bg-green-500 scale-125'
|
||||||
: 'bg-gray-300'
|
: 'bg-gray-300'
|
||||||
}`}
|
}`}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1835,7 +1835,7 @@ function PlayPageClient() {
|
|||||||
{videoTitle || '影片标题'}
|
{videoTitle || '影片标题'}
|
||||||
{totalEpisodes > 1 && (
|
{totalEpisodes > 1 && (
|
||||||
<span className='text-gray-500 dark:text-gray-400'>
|
<span className='text-gray-500 dark:text-gray-400'>
|
||||||
{` > 第 ${currentEpisodeIndex + 1} 集`}
|
{` > ${detail?.episodes_titles?.[currentEpisodeIndex] || `第 ${currentEpisodeIndex + 1} 集`}`}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</h1>
|
</h1>
|
||||||
@@ -1874,8 +1874,8 @@ function PlayPageClient() {
|
|||||||
{/* 精致的状态指示点 */}
|
{/* 精致的状态指示点 */}
|
||||||
<div
|
<div
|
||||||
className={`absolute -top-0.5 -right-0.5 w-2 h-2 rounded-full transition-all duration-200 ${isEpisodeSelectorCollapsed
|
className={`absolute -top-0.5 -right-0.5 w-2 h-2 rounded-full transition-all duration-200 ${isEpisodeSelectorCollapsed
|
||||||
? 'bg-orange-400 animate-pulse'
|
? 'bg-orange-400 animate-pulse'
|
||||||
: 'bg-green-400'
|
: 'bg-green-400'
|
||||||
}`}
|
}`}
|
||||||
></div>
|
></div>
|
||||||
</button>
|
</button>
|
||||||
@@ -1883,8 +1883,8 @@ function PlayPageClient() {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
className={`grid gap-4 lg:h-[500px] xl:h-[650px] 2xl:h-[750px] transition-all duration-300 ease-in-out ${isEpisodeSelectorCollapsed
|
className={`grid gap-4 lg:h-[500px] xl:h-[650px] 2xl:h-[750px] transition-all duration-300 ease-in-out ${isEpisodeSelectorCollapsed
|
||||||
? 'grid-cols-1'
|
? 'grid-cols-1'
|
||||||
: 'grid-cols-1 md:grid-cols-4'
|
: 'grid-cols-1 md:grid-cols-4'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{/* 播放器 */}
|
{/* 播放器 */}
|
||||||
@@ -1941,8 +1941,8 @@ function PlayPageClient() {
|
|||||||
{/* 选集和换源 - 在移动端始终显示,在 lg 及以上可折叠 */}
|
{/* 选集和换源 - 在移动端始终显示,在 lg 及以上可折叠 */}
|
||||||
<div
|
<div
|
||||||
className={`h-[300px] lg:h-full md:overflow-hidden transition-all duration-300 ease-in-out ${isEpisodeSelectorCollapsed
|
className={`h-[300px] lg:h-full md:overflow-hidden transition-all duration-300 ease-in-out ${isEpisodeSelectorCollapsed
|
||||||
? 'md:col-span-1 lg:hidden lg:opacity-0 lg:scale-95'
|
? 'md:col-span-1 lg:hidden lg:opacity-0 lg:scale-95'
|
||||||
: 'md:col-span-1 lg:opacity-100 lg:scale-100'
|
: 'md:col-span-1 lg:opacity-100 lg:scale-100'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<EpisodeSelector
|
<EpisodeSelector
|
||||||
|
|||||||
@@ -312,10 +312,9 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
|
|||||||
<div
|
<div
|
||||||
onClick={() => setActiveTab('episodes')}
|
onClick={() => setActiveTab('episodes')}
|
||||||
className={`flex-1 py-3 px-6 text-center cursor-pointer transition-all duration-200 font-medium
|
className={`flex-1 py-3 px-6 text-center cursor-pointer transition-all duration-200 font-medium
|
||||||
${
|
${activeTab === 'episodes'
|
||||||
activeTab === 'episodes'
|
? 'text-green-600 dark:text-green-400'
|
||||||
? 'text-green-600 dark:text-green-400'
|
: 'text-gray-700 hover:text-green-600 bg-black/5 dark:bg-white/5 dark:text-gray-300 dark:hover:text-green-400 hover:bg-black/3 dark:hover:bg-white/3'
|
||||||
: 'text-gray-700 hover:text-green-600 bg-black/5 dark:bg-white/5 dark:text-gray-300 dark:hover:text-green-400 hover:bg-black/3 dark:hover:bg-white/3'
|
|
||||||
}
|
}
|
||||||
`.trim()}
|
`.trim()}
|
||||||
>
|
>
|
||||||
@@ -325,10 +324,9 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
|
|||||||
<div
|
<div
|
||||||
onClick={handleSourceTabClick}
|
onClick={handleSourceTabClick}
|
||||||
className={`flex-1 py-3 px-6 text-center cursor-pointer transition-all duration-200 font-medium
|
className={`flex-1 py-3 px-6 text-center cursor-pointer transition-all duration-200 font-medium
|
||||||
${
|
${activeTab === 'sources'
|
||||||
activeTab === 'sources'
|
? 'text-green-600 dark:text-green-400'
|
||||||
? 'text-green-600 dark:text-green-400'
|
: 'text-gray-700 hover:text-green-600 bg-black/5 dark:bg-white/5 dark:text-gray-300 dark:hover:text-green-400 hover:bg-black/3 dark:hover:bg-white/3'
|
||||||
: 'text-gray-700 hover:text-green-600 bg-black/5 dark:bg-white/5 dark:text-gray-300 dark:hover:text-green-400 hover:bg-black/3 dark:hover:bg-white/3'
|
|
||||||
}
|
}
|
||||||
`.trim()}
|
`.trim()}
|
||||||
>
|
>
|
||||||
@@ -353,10 +351,9 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
|
|||||||
}}
|
}}
|
||||||
onClick={() => handleCategoryClick(idx)}
|
onClick={() => handleCategoryClick(idx)}
|
||||||
className={`w-20 relative py-2 text-sm font-medium transition-colors whitespace-nowrap flex-shrink-0 text-center
|
className={`w-20 relative py-2 text-sm font-medium transition-colors whitespace-nowrap flex-shrink-0 text-center
|
||||||
${
|
${isActive
|
||||||
isActive
|
? 'text-green-500 dark:text-green-400'
|
||||||
? 'text-green-500 dark:text-green-400'
|
: 'text-gray-700 hover:text-green-600 dark:text-gray-300 dark:hover:text-green-400'
|
||||||
: 'text-gray-700 hover:text-green-600 dark:text-gray-300 dark:hover:text-green-400'
|
|
||||||
}
|
}
|
||||||
`.trim()}
|
`.trim()}
|
||||||
>
|
>
|
||||||
@@ -408,10 +405,9 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
|
|||||||
key={episodeNumber}
|
key={episodeNumber}
|
||||||
onClick={() => handleEpisodeClick(episodeNumber - 1)}
|
onClick={() => handleEpisodeClick(episodeNumber - 1)}
|
||||||
className={`h-10 min-w-10 px-3 py-2 flex items-center justify-center text-sm font-medium rounded-md transition-all duration-200 whitespace-nowrap font-mono
|
className={`h-10 min-w-10 px-3 py-2 flex items-center justify-center text-sm font-medium rounded-md transition-all duration-200 whitespace-nowrap font-mono
|
||||||
${
|
${isActive
|
||||||
isActive
|
? 'bg-green-500 text-white shadow-lg shadow-green-500/25 dark:bg-green-600'
|
||||||
? 'bg-green-500 text-white shadow-lg shadow-green-500/25 dark:bg-green-600'
|
: 'bg-gray-200 text-gray-700 hover:bg-gray-300 hover:scale-105 dark:bg-white/10 dark:text-gray-300 dark:hover:bg-white/20'
|
||||||
: 'bg-gray-200 text-gray-700 hover:bg-gray-300 hover:scale-105 dark:bg-white/10 dark:text-gray-300 dark:hover:bg-white/20'
|
|
||||||
}`.trim()}
|
}`.trim()}
|
||||||
>
|
>
|
||||||
{(() => {
|
{(() => {
|
||||||
@@ -419,8 +415,8 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
|
|||||||
if (!title) {
|
if (!title) {
|
||||||
return episodeNumber;
|
return episodeNumber;
|
||||||
}
|
}
|
||||||
// 如果匹配"第X集"格式,提取中间的数字
|
// 如果匹配"第X集"、"第X话"、"X集"、"X话"格式,提取中间的数字
|
||||||
const match = title.match(/第(\d+)集/);
|
const match = title.match(/(?:第)?(\d+)(?:集|话)/);
|
||||||
if (match) {
|
if (match) {
|
||||||
return match[1];
|
return match[1];
|
||||||
}
|
}
|
||||||
@@ -496,11 +492,10 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
|
|||||||
!isCurrentSource && handleSourceClick(source)
|
!isCurrentSource && handleSourceClick(source)
|
||||||
}
|
}
|
||||||
className={`flex items-start gap-3 px-2 py-3 rounded-lg transition-all select-none duration-200 relative
|
className={`flex items-start gap-3 px-2 py-3 rounded-lg transition-all select-none duration-200 relative
|
||||||
${
|
${isCurrentSource
|
||||||
isCurrentSource
|
? 'bg-green-500/10 dark:bg-green-500/20 border-green-500/30 border'
|
||||||
? 'bg-green-500/10 dark:bg-green-500/20 border-green-500/30 border'
|
: 'hover:bg-gray-200/50 dark:hover:bg-white/10 hover:scale-[1.02] cursor-pointer'
|
||||||
: 'hover:bg-gray-200/50 dark:hover:bg-white/10 hover:scale-[1.02] cursor-pointer'
|
}`.trim()}
|
||||||
}`.trim()}
|
|
||||||
>
|
>
|
||||||
{/* 封面 */}
|
{/* 封面 */}
|
||||||
<div className='flex-shrink-0 w-12 h-20 bg-gray-300 dark:bg-gray-600 rounded overflow-hidden'>
|
<div className='flex-shrink-0 w-12 h-20 bg-gray-300 dark:bg-gray-600 rounded overflow-hidden'>
|
||||||
@@ -555,8 +550,8 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
|
|||||||
const textColorClasses = isUltraHigh
|
const textColorClasses = isUltraHigh
|
||||||
? 'text-purple-600 dark:text-purple-400'
|
? 'text-purple-600 dark:text-purple-400'
|
||||||
: isHigh
|
: isHigh
|
||||||
? 'text-green-600 dark:text-green-400'
|
? 'text-green-600 dark:text-green-400'
|
||||||
: 'text-yellow-600 dark:text-yellow-400';
|
: 'text-yellow-600 dark:text-yellow-400';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user