提升播放页带背景图下选集面板的对比度

This commit is contained in:
mtvpls
2026-06-10 09:49:29 +08:00
parent 65d89be93a
commit f515f8ee46
2 changed files with 49 additions and 18 deletions
+3 -2
View File
@@ -9666,6 +9666,7 @@ function PlayPageClient() {
sourceSearchError={sourceSearchError}
backgroundSourcesLoading={backgroundSourcesLoading}
precomputedVideoInfo={precomputedVideoInfo}
useLightTextOnBackdrop={!!tmdbBackdrop}
onDanmakuSelect={(selection) => handleDanmakuSelect(selection, true)}
currentDanmakuSelection={currentDanmakuSelection}
onUploadDanmaku={handleUploadDanmaku}
@@ -9821,11 +9822,11 @@ function PlayPageClient() {
})}
</div>
{/* 评分数值 */}
<span className='text-gray-700 dark:text-gray-300 font-semibold'>
<span className={`font-semibold ${tmdbBackdrop ? 'text-white' : 'text-gray-700 dark:text-gray-300'}`}>
{doubanRating.value.toFixed(1)}
</span>
{/* 评分人数 */}
<span className='text-gray-500 dark:text-gray-400 text-sm'>
<span className={`text-sm ${tmdbBackdrop ? 'text-white/80' : 'text-gray-500 dark:text-gray-400'}`}>
({doubanRating.count.toLocaleString()})
</span>
</div>
+46 -16
View File
@@ -62,6 +62,8 @@ interface EpisodeSelectorProps {
onUploadDanmaku?: (comments: DanmakuComment[]) => void;
/** 观影室房员状态 - 禁用选集和换源,但保留弹幕 */
isRoomMember?: boolean;
/** 外层使用 TMDB 背景图时,提升深色文字对比度 */
useLightTextOnBackdrop?: boolean;
/** 集数过滤配置 */
episodeFilterConfig?: EpisodeFilterConfig | null;
onFilterConfigUpdate?: (config: EpisodeFilterConfig) => void;
@@ -91,11 +93,39 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
currentDanmakuSelection,
onUploadDanmaku,
isRoomMember = false,
useLightTextOnBackdrop = false,
episodeFilterConfig = null,
onFilterConfigUpdate,
onShowToast,
}) => {
const router = useRouter();
const mutedTextClass = useLightTextOnBackdrop
? 'text-white/80'
: 'text-gray-600 dark:text-gray-300';
const faintTextClass = useLightTextOnBackdrop
? 'text-white/65'
: 'text-gray-500 dark:text-gray-400';
const inactiveTabClass = useLightTextOnBackdrop
? 'text-white/85 hover:text-white bg-white/10 dark:bg-white/5 hover:bg-white/15 dark:hover:bg-white/10'
: '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';
const inactiveActionTextClass = useLightTextOnBackdrop
? 'text-white/85 hover:text-white'
: 'text-gray-700 hover:text-green-600 dark:text-gray-300 dark:hover:text-green-400';
const iconButtonClass = useLightTextOnBackdrop
? 'text-white/85 hover:text-white hover:bg-white/15'
: 'text-gray-700 hover:text-green-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:text-green-400 dark:hover:bg-white/20';
const inactiveEpisodeClass = useLightTextOnBackdrop
? 'bg-white/15 text-white border-white/10 hover:bg-white/25 hover:scale-105'
: 'bg-gray-200 text-gray-700 border-transparent hover:bg-gray-300 hover:scale-105 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600';
const sourceTitleClass = useLightTextOnBackdrop
? 'text-white'
: 'text-gray-900 dark:text-gray-100';
const sourcePillTextClass = useLightTextOnBackdrop
? 'text-white/85'
: 'text-gray-700 dark:text-gray-300';
const disabledTextClass = useLightTextOnBackdrop
? 'text-white/45 cursor-not-allowed'
: 'text-gray-400 dark:text-gray-500 cursor-not-allowed';
const parseSxxExxTitle = useCallback((title?: string) => {
const match = title?.match(/[Ss](\d+)[Ee](\d{1,4}(?:\.\d+)?)/);
@@ -683,7 +713,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
${isRoomMember ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'}
${activeTab === 'episodes'
? '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'
: inactiveTabClass
}
`.trim()}
>
@@ -699,7 +729,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
${isRoomMember ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'}
${activeTab === 'sources'
? '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'
: inactiveTabClass
}
`.trim()}
>
@@ -713,7 +743,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
className={`flex-1 py-3 px-6 text-center cursor-pointer transition-all duration-200 font-medium
${activeTab === 'danmaku'
? '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'
: inactiveTabClass
}
`.trim()}
>
@@ -758,7 +788,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
className={`w-20 relative py-2 text-sm font-medium transition-colors whitespace-nowrap flex-shrink-0 text-center
${isActive
? 'text-green-500 dark:text-green-400'
: 'text-gray-700 hover:text-green-600 dark:text-gray-300 dark:hover:text-green-400'
: inactiveActionTextClass
}
`.trim()}
>
@@ -773,7 +803,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
</div>
{/* 向上/向下按钮 */}
<button
className='flex-shrink-0 w-8 h-8 rounded-md flex items-center justify-center text-gray-700 hover:text-green-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:text-green-400 dark:hover:bg-white/20 transition-colors transform translate-y-[-4px]'
className={`flex-shrink-0 w-8 h-8 rounded-md flex items-center justify-center ${iconButtonClass} transition-colors transform translate-y-[-4px]`}
onClick={() => {
// 切换集数排序(正序/倒序)
setDescending((prev) => !prev);
@@ -795,7 +825,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
</button>
{/* 集数屏蔽配置按钮 */}
<button
className='flex-shrink-0 w-8 h-8 rounded-md flex items-center justify-center text-gray-700 hover:text-green-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:text-green-400 dark:hover:bg-white/20 transition-colors transform translate-y-[-4px]'
className={`flex-shrink-0 w-8 h-8 rounded-md flex items-center justify-center ${iconButtonClass} transition-colors transform translate-y-[-4px]`}
onClick={() => setShowFilterSettings(true)}
title='集数屏蔽设置'
>
@@ -825,7 +855,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
? 'bg-green-500 text-white border-green-400 shadow-lg shadow-green-500/25 dark:bg-green-600'
: isWatched
? 'bg-emerald-50 text-emerald-700 border-emerald-200 hover:bg-emerald-100 hover:scale-105 dark:bg-emerald-900/20 dark:text-emerald-300 dark:border-emerald-700/60 dark:hover:bg-emerald-900/30'
: 'bg-gray-200 text-gray-700 border-transparent hover:bg-gray-300 hover:scale-105 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600'
: inactiveEpisodeClass
} ${isActive ? 'cursor-default' : ''}`.trim()}
title={isWatched && !isActive ? '已观看过' : undefined}
aria-current={isActive ? 'true' : undefined}
@@ -873,7 +903,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
disabled={isRetestingAll || retestingSources.size > 0 || isInitialTesting}
className={`text-xs font-medium transition-colors ${
isRetestingAll || retestingSources.size > 0 || isInitialTesting
? 'text-gray-400 dark:text-gray-500 cursor-not-allowed'
? disabledTextClass
: 'text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 cursor-pointer'
}`}
>
@@ -885,7 +915,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
{sourceSearchLoading && (
<div className='flex items-center justify-center py-8'>
<div className='animate-spin rounded-full h-8 w-8 border-b-2 border-green-500'></div>
<span className='ml-2 text-sm text-gray-600 dark:text-gray-300'>
<span className={`ml-2 text-sm ${mutedTextClass}`}>
...
</span>
</div>
@@ -908,7 +938,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
<div className='flex items-center justify-center py-8'>
<div className='text-center'>
<div className='text-gray-400 text-2xl mb-2'>📺</div>
<p className='text-sm text-gray-600 dark:text-gray-300'>
<p className={`text-sm ${mutedTextClass}`}>
</p>
</div>
@@ -987,7 +1017,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
{/* 标题和分辨率 - 顶部 */}
<div className='flex items-start justify-between gap-3 h-6'>
<div className='flex-1 min-w-0 relative group/title'>
<h3 className='font-medium text-base truncate text-gray-900 dark:text-gray-100 leading-none'>
<h3 className={`font-medium text-base truncate ${sourceTitleClass} leading-none`}>
{source.title}
</h3>
{/* 标题级别的 tooltip - 第一个元素不显示 */}
@@ -1039,7 +1069,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
{/* 源名称和集数信息 - 垂直居中 */}
<div className='flex items-center justify-between'>
<span className={`text-xs px-2 py-1 border rounded text-gray-700 dark:text-gray-300 ${
<span className={`text-xs px-2 py-1 border rounded ${sourcePillTextClass} ${
source.source === 'xiaoya' ? 'border-blue-500' : isNetdiskSource(source.source) ? 'border-purple-500' : source.source === 'openlist' || source.source === 'emby' || source.source?.startsWith('emby_')
? 'border-yellow-500'
: 'border-gray-500/60'
@@ -1047,7 +1077,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
{source.source_name}
</span>
{source.episodes.length > 1 && (
<span className='text-xs text-gray-500 dark:text-gray-400 font-medium'>
<span className={`text-xs ${faintTextClass} font-medium`}>
{source.episodes.length}
</span>
)}
@@ -1106,7 +1136,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
disabled={isTesting}
className={`text-xs font-medium transition-colors ${
isTesting
? 'text-gray-400 dark:text-gray-500 cursor-not-allowed'
? disabledTextClass
: 'text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 cursor-pointer'
}`}
>
@@ -1125,7 +1155,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
{backgroundSourcesLoading && (
<div className='flex items-center justify-center py-6 border-t border-gray-300 dark:border-gray-700'>
<div className='animate-spin rounded-full h-6 w-6 border-b-2 border-green-500'></div>
<span className='ml-2 text-sm text-gray-600 dark:text-gray-300'>
<span className={`ml-2 text-sm ${mutedTextClass}`}>
...
</span>
</div>
@@ -1139,7 +1169,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
);
}
}}
className='w-full text-center text-xs text-gray-500 dark:text-gray-400 hover:text-green-500 dark:hover:text-green-400 transition-colors py-2'
className={`w-full text-center text-xs ${faintTextClass} hover:text-green-500 dark:hover:text-green-400 transition-colors py-2`}
>
</button>