diff --git a/lib/core/theme/app_colors.dart b/lib/core/theme/app_colors.dart index 26b8f4e..c4e8e60 100644 --- a/lib/core/theme/app_colors.dart +++ b/lib/core/theme/app_colors.dart @@ -91,6 +91,21 @@ abstract final class AppColors { /// 导航未选中。 static const navUnselected = muted; + /// 播放器专用深色页面背景。 + static const playerBackground = Color(0xFF0D0D10); + + /// 播放器底部信息面板,保留轻微视频透出。 + static const playerPanel = Color(0xED0D0D10); + + /// 播放器次要文字。 + static const playerMuted = Color(0xFFBBBBBB); + + /// 播放器底栏胶囊。 + static const playerChip = Color(0xFF1C1C1E); + + /// 播放器面板分割线。 + static const playerDivider = Color(0xFF2A2A2D); + static const outlineDark = border; static const outlineVariantDark = border; static const outlineLight = muted; diff --git a/lib/pages/player/player_view.dart b/lib/pages/player/player_view.dart index f0793d0..428be04 100644 --- a/lib/pages/player/player_view.dart +++ b/lib/pages/player/player_view.dart @@ -217,7 +217,7 @@ class _PlayerPageState extends State with WidgetsBindingObserver { children: [ ColoredBox( key: const Key('player-background'), - color: AppColors.ink, + color: AppColors.playerBackground, child: widget.homeMode ? null : RemoteImage( @@ -227,25 +227,6 @@ class _PlayerPageState extends State with WidgetsBindingObserver { ), ), ?video, - if (!logic.chromeHidden && (!widget.homeMode || _chromeVisible)) - IgnorePointer( - key: widget.homeMode ? const Key('home-feed-scrim') : null, - child: const DecoratedBox( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color(0x66000000), - Color(0x00000000), - Color(0x33000000), - Color(0xE6000000), - ], - stops: [0, 0.16, 0.55, 1], - ), - ), - ), - ), if (widget.homeMode && _chromeVisible && !logic.chromeHidden) Positioned.fill( child: GestureDetector( diff --git a/lib/pages/player/widgets/player_overlay.dart b/lib/pages/player/widgets/player_overlay.dart index ce65340..91b097c 100644 --- a/lib/pages/player/widgets/player_overlay.dart +++ b/lib/pages/player/widgets/player_overlay.dart @@ -167,8 +167,8 @@ class PlayerPlaybackOverlay extends StatelessWidget { key: const Key('player-controls-bottom'), padding: const EdgeInsets.fromLTRB(14, 8, 14, 6), decoration: const BoxDecoration( - color: AppColors.card, - border: Border(top: BorderSide(color: AppColors.border)), + color: AppColors.playerPanel, + border: Border(top: BorderSide(color: AppColors.playerDivider)), borderRadius: BorderRadius.vertical( top: Radius.circular(_panelRadius), ), @@ -194,6 +194,7 @@ class PlayerPlaybackOverlay extends StatelessWidget { semanticsLabel: data.l10n.seekVideo, showTimes: true, compact: true, + inactiveTrackColor: Colors.white24, onScrubStart: actions.onScrubStart, onSeek: actions.onSeek, ), @@ -221,7 +222,7 @@ class PlayerPlaybackOverlay extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( - color: AppColors.onSurface, + color: AppColors.onPrimary, fontFamily: 'Outfit', fontSize: 18 * data.textScale, fontWeight: FontWeight.w800, @@ -231,7 +232,7 @@ class PlayerPlaybackOverlay extends StatelessWidget { const SizedBox(width: 6), const Icon( Icons.chevron_right_rounded, - color: AppColors.muted, + color: AppColors.playerMuted, size: 20, ), ], @@ -246,13 +247,18 @@ class PlayerPlaybackOverlay extends StatelessWidget { children: [ Expanded( child: Material( - color: Colors.transparent, + color: AppColors.playerChip, + borderRadius: BorderRadius.circular(999), + clipBehavior: Clip.antiAlias, child: InkWell( key: const Key('player-episodes'), onTap: actions.onEpisodes, - borderRadius: BorderRadius.circular(8), + borderRadius: BorderRadius.circular(999), child: Padding( - padding: const EdgeInsets.symmetric(vertical: 4), + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 4, + ), child: Row( children: [ Flexible( @@ -263,7 +269,7 @@ class PlayerPlaybackOverlay extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( - color: AppColors.onSurface, + color: AppColors.onPrimary, fontSize: 11, fontWeight: FontWeight.w700, ), @@ -272,7 +278,7 @@ class PlayerPlaybackOverlay extends StatelessWidget { const SizedBox(width: 3), const Icon( Icons.keyboard_arrow_up_rounded, - color: AppColors.onSurface, + color: AppColors.onPrimary, size: 16, ), ], diff --git a/lib/pages/player/widgets/player_overlay_parts.dart b/lib/pages/player/widgets/player_overlay_parts.dart index 8fec70a..d41b36b 100644 --- a/lib/pages/player/widgets/player_overlay_parts.dart +++ b/lib/pages/player/widgets/player_overlay_parts.dart @@ -93,8 +93,8 @@ class _BottomIconButton extends StatelessWidget { tooltip: tooltip, padding: EdgeInsets.zero, style: IconButton.styleFrom( - backgroundColor: AppColors.raised, - foregroundColor: AppColors.onSurface, + backgroundColor: AppColors.playerChip, + foregroundColor: AppColors.onPrimary, ), onPressed: onPressed, icon: Icon(icon, size: 17), @@ -259,7 +259,10 @@ class _EpisodeSynopsisState extends State<_EpisodeSynopsis> { ), const Padding( padding: EdgeInsets.symmetric(horizontal: 6), - child: Text('|', style: TextStyle(color: AppColors.border)), + child: Text( + '|', + style: TextStyle(color: AppColors.playerDivider), + ), ), Expanded( child: Text( @@ -268,7 +271,7 @@ class _EpisodeSynopsisState extends State<_EpisodeSynopsis> { maxLines: _expanded ? 3 : 1, overflow: TextOverflow.ellipsis, style: TextStyle( - color: AppColors.muted, + color: AppColors.playerMuted, fontSize: 11 * widget.textScale, height: 1.35, ), @@ -279,7 +282,7 @@ class _EpisodeSynopsisState extends State<_EpisodeSynopsis> { _expanded ? Icons.keyboard_arrow_up_rounded : Icons.keyboard_arrow_down_rounded, - color: AppColors.subtle, + color: AppColors.playerMuted, size: 16, ), ], @@ -289,7 +292,10 @@ class _EpisodeSynopsisState extends State<_EpisodeSynopsis> { Text( widget.authorNote, key: const Key('player-author-note'), - style: const TextStyle(color: AppColors.muted, fontSize: 10), + style: const TextStyle( + color: AppColors.playerMuted, + fontSize: 10, + ), ), ], ], diff --git a/lib/pages/player/widgets/seek_progress_bar.dart b/lib/pages/player/widgets/seek_progress_bar.dart index 57f7503..45195d5 100644 --- a/lib/pages/player/widgets/seek_progress_bar.dart +++ b/lib/pages/player/widgets/seek_progress_bar.dart @@ -27,6 +27,7 @@ class SeekProgressBar extends StatefulWidget { this.onSeek, this.showTimes = true, this.compact = false, + this.inactiveTrackColor = AppColors.border, }); final ValueListenable? valueListenable; @@ -35,6 +36,7 @@ class SeekProgressBar extends StatefulWidget { final Future Function(Duration)? onSeek; final bool showTimes; final bool compact; + final Color inactiveTrackColor; @override State createState() => _SeekProgressBarState(); @@ -127,7 +129,7 @@ class _SeekProgressBarState extends State { ? (scrubbing ? 3 : 1.5) : (scrubbing ? 4 : 3), activeTrackColor: AppColors.blue, - inactiveTrackColor: AppColors.border, + inactiveTrackColor: widget.inactiveTrackColor, thumbColor: AppColors.onPrimary, thumbShape: RoundSliderThumbShape( enabledThumbRadius: widget.compact diff --git a/test/player/player_fullscreen_test.dart b/test/player/player_fullscreen_test.dart index 45e48d7..f4a78e7 100644 --- a/test/player/player_fullscreen_test.dart +++ b/test/player/player_fullscreen_test.dart @@ -191,12 +191,12 @@ void main() { tester .widget(find.byKey(const Key('player-background'))) .color, - AppColors.ink, + AppColors.playerBackground, ); final panel = tester.widget( find.byKey(const Key('player-controls-bottom')), ); - expect((panel.decoration! as BoxDecoration).color, AppColors.card); + expect((panel.decoration! as BoxDecoration).color, AppColors.playerPanel); expect(bottom.height, lessThanOrEqualTo(200)); expect(bottom.top, greaterThanOrEqualTo(screenHeight * 0.78));