From 3068eb99da3a18af4b17d2132920ddcb962fbd23 Mon Sep 17 00:00:00 2001 From: Zhou Weidong <502333560@qq.com> Date: Tue, 20 Oct 2026 11:33:23 +0800 Subject: [PATCH] =?UTF-8?q?fix(flutter):=20=E6=94=B6=E7=AA=84=E6=B8=85?= =?UTF-8?q?=E5=B1=8F=E8=8C=83=E5=9B=B4=E5=B9=B6=E4=BF=9D=E7=95=99=E5=BA=95?= =?UTF-8?q?=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/player/widgets/player_overlay.dart | 195 ++++++++++--------- test/player/player_fullscreen_test.dart | 75 +++---- 2 files changed, 136 insertions(+), 134 deletions(-) diff --git a/lib/pages/player/widgets/player_overlay.dart b/lib/pages/player/widgets/player_overlay.dart index 4e3128a..ae72e42 100644 --- a/lib/pages/player/widgets/player_overlay.dart +++ b/lib/pages/player/widgets/player_overlay.dart @@ -5,7 +5,6 @@ import '../../../core/formatting/localized_content.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_dimens.dart'; import '../../../l10n/app_localizations.dart'; -import 'exit_clear_screen_button.dart'; import 'player_center_toggle.dart'; import 'player_overlay_models.dart'; import 'seek_progress_bar.dart'; @@ -51,21 +50,9 @@ class PlayerPlaybackOverlay extends StatelessWidget { onTap: actions.onTogglePlay, ), ), - if (controlsVisible) ...[ - _top(context), - _bottom(context), - _rail(context), - ], - if (!controlsVisible) - Positioned( - top: AppDimens.spaceSm, - right: AppDimens.spaceMd, - child: ExitClearScreenButton( - key: const Key('player-exit-clear-screen'), - tooltip: data.l10n.exitClearScreen, - onPressed: actions.onExitClear, - ), - ), + _top(context), + _bottom(context), + if (controlsVisible) _rail(context), if (!data.playing) Center( child: PlayerCenterToggle( @@ -153,43 +140,49 @@ class PlayerPlaybackOverlay extends StatelessWidget { } Widget _bottom(BuildContext context) { - final series = localizedDramaTitle(data.l10n, data.drama); - final synopsis = localizedDramaSynopsis(data.l10n, data.drama); return Positioned( left: 0, right: 0, bottom: 0, - child: Padding( - key: const Key('player-controls-bottom'), - padding: const EdgeInsets.fromLTRB(14, 8, 14, 6), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _detailRow(series), - const SizedBox(height: 4), - _EpisodeSynopsis( - key: const Key('player-episode-synopsis'), - l10n: data.l10n, - episodeNumber: data.episode.number, - synopsis: synopsis, - authorNote: data.authorNote, - textScale: data.textScale, - ), - const SizedBox(height: 2), - SeekProgressBar( - key: const Key('player-progress'), - valueListenable: data.controller, - semanticsLabel: data.l10n.seekVideo, - showTimes: true, - compact: true, - inactiveTrackColor: Colors.white24, - onScrubStart: actions.onScrubStart, - onSeek: actions.onSeek, - ), - _bottomActions(), - ], - ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [if (controlsVisible) _bottomInfo(context), _bottomActions()], + ), + ); + } + + Widget _bottomInfo(BuildContext context) { + final series = localizedDramaTitle(data.l10n, data.drama); + final synopsis = localizedDramaSynopsis(data.l10n, data.drama); + return Padding( + key: const Key('player-controls-bottom'), + padding: const EdgeInsets.fromLTRB(14, 8, 14, 0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _detailRow(series), + const SizedBox(height: 4), + _EpisodeSynopsis( + key: const Key('player-episode-synopsis'), + l10n: data.l10n, + episodeNumber: data.episode.number, + synopsis: synopsis, + authorNote: data.authorNote, + textScale: data.textScale, + ), + const SizedBox(height: 2), + SeekProgressBar( + key: const Key('player-progress'), + valueListenable: data.controller, + semanticsLabel: data.l10n.seekVideo, + showTimes: true, + compact: true, + inactiveTrackColor: Colors.white24, + onScrubStart: actions.onScrubStart, + onSeek: actions.onSeek, + ), + ], ), ); } @@ -234,61 +227,69 @@ class PlayerPlaybackOverlay extends StatelessWidget { } Widget _bottomActions() { - return Row( - children: [ - Expanded( - child: Material( - key: const Key('player-episodes-pill'), - color: AppColors.playerOverlayPill, - borderRadius: BorderRadius.circular(999), - clipBehavior: Clip.antiAlias, - child: InkWell( - key: const Key('player-episodes'), - onTap: actions.onEpisodes, + return Padding( + key: const Key('player-bottom-actions'), + padding: const EdgeInsets.fromLTRB(14, 6, 14, 6), + child: Row( + children: [ + Expanded( + child: Material( + key: const Key('player-episodes-pill'), + color: AppColors.playerOverlayPill, borderRadius: BorderRadius.circular(999), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 4, - ), - child: Row( - children: [ - Flexible( - child: Text( - '${data.l10n.episodes} · ' - '${data.l10n.allEpisodesBadge(data.totalEpisodes)} · ' - '${data.l10n.freeWatch}', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - color: AppColors.onPrimary, - fontSize: 11, - fontWeight: FontWeight.w700, - shadows: _playerTextShadows, + clipBehavior: Clip.antiAlias, + child: InkWell( + key: const Key('player-episodes'), + onTap: actions.onEpisodes, + borderRadius: BorderRadius.circular(999), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 4, + ), + child: Row( + children: [ + Flexible( + child: Text( + '${data.l10n.episodes} · ' + '${data.l10n.allEpisodesBadge(data.totalEpisodes)} · ' + '${data.l10n.freeWatch}', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + color: AppColors.onPrimary, + fontSize: 11, + fontWeight: FontWeight.w700, + shadows: _playerTextShadows, + ), ), ), - ), - const SizedBox(width: 3), - const Icon( - Icons.keyboard_arrow_up_rounded, - color: AppColors.onPrimary, - size: 16, - shadows: _playerTextShadows, - ), - ], + const SizedBox(width: 3), + const Icon( + Icons.keyboard_arrow_up_rounded, + color: AppColors.onPrimary, + size: 16, + shadows: _playerTextShadows, + ), + ], + ), ), ), ), ), - ), - const SizedBox(width: 8), - _BottomIconButton( - key: const Key('player-bottom-clear-screen'), - tooltip: data.l10n.clearScreen, - icon: Icons.fullscreen_rounded, - onPressed: actions.onClear, - ), - ], + const SizedBox(width: 8), + _BottomIconButton( + key: const Key('player-bottom-clear-screen'), + tooltip: controlsVisible + ? data.l10n.clearScreen + : data.l10n.exitClearScreen, + icon: controlsVisible + ? Icons.fullscreen_rounded + : Icons.fullscreen_exit_rounded, + onPressed: controlsVisible ? actions.onClear : actions.onExitClear, + ), + ], + ), ); } } diff --git a/test/player/player_fullscreen_test.dart b/test/player/player_fullscreen_test.dart index 47eb77e..6f24abd 100644 --- a/test/player/player_fullscreen_test.dart +++ b/test/player/player_fullscreen_test.dart @@ -110,8 +110,10 @@ void main() { await _clearFromMore(tester); await tester.pump(); - expect(find.byKey(const Key('player-controls-top')), findsNothing); + expect(find.byKey(const Key('player-controls-top')), findsOneWidget); expect(find.byKey(const Key('player-controls-bottom')), findsNothing); + expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget); + expect(find.byKey(const Key('player-interaction-rail')), findsNothing); expect(find.byType(PlayerCenterToggle), findsOneWidget); expect( tester @@ -122,45 +124,30 @@ void main() { isFalse, ); expect(find.byKey(const Key('player-video-tap')), findsOneWidget); - expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); + expect(find.byKey(const Key('player-bottom-clear-screen')), findsOneWidget); + expect(find.byTooltip('Exit clear screen'), findsOneWidget); expect( - tester.getSize(find.byKey(const Key('player-exit-clear-screen'))), - const Size(36, 36), + tester.getSize(find.byKey(const Key('player-bottom-clear-screen'))), + const Size(30, 30), ); await tester.tapAt(const Offset(80, 300)); await tester.pump(); - expect(find.byKey(const Key('player-controls-top')), findsNothing); - expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); + expect(find.byKey(const Key('player-controls-top')), findsOneWidget); + expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget); expect(find.byType(PlayerCenterToggle), findsNothing); await tester.tapAt(const Offset(80, 300)); await tester.pump(); - expect(find.byKey(const Key('player-controls-top')), findsNothing); - expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); - expect( - tester - .widget( - find.byKey(const Key('player-play-toggle')), - ) - .playing, - isFalse, - ); + expect(find.byType(PlayerCenterToggle), findsOneWidget); - await tester.tap(find.byKey(const Key('player-exit-clear-screen'))); + await tester.tap(find.byKey(const Key('player-bottom-clear-screen'))); await tester.pump(); expect(find.byKey(const Key('player-controls-top')), findsOneWidget); expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget); + expect(find.byKey(const Key('player-interaction-rail')), findsOneWidget); expect(find.byType(PlayerCenterToggle), findsOneWidget); - expect( - tester - .widget( - find.byKey(const Key('player-play-toggle')), - ) - .playing, - isFalse, - ); - expect(find.byKey(const Key('player-exit-clear-screen')), findsNothing); + expect(find.byTooltip('Clear screen'), findsOneWidget); }); testWidgets('should_fit_player_header_on_320_width', (tester) async { @@ -251,20 +238,22 @@ void main() { await _clearFromMore(tester); await tester.pump(); - expect(find.byKey(const Key('player-controls-top')), findsNothing); + expect(find.byKey(const Key('player-controls-top')), findsOneWidget); await tester.drag(find.byType(PageView), const Offset(0, -550)); await tester.pumpAndSettle(); - expect(find.byKey(const Key('player-controls-top')), findsNothing); + expect(find.byKey(const Key('player-controls-top')), findsOneWidget); expect(find.byKey(const Key('player-controls-bottom')), findsNothing); - expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); + expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget); + expect(find.byKey(const Key('player-interaction-rail')), findsNothing); + expect(find.byKey(const Key('player-bottom-clear-screen')), findsOneWidget); - await tester.tap(find.byKey(const Key('player-exit-clear-screen'))); + await tester.tap(find.byKey(const Key('player-bottom-clear-screen'))); await tester.pump(); expect(find.byKey(const Key('player-controls-top')), findsOneWidget); expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget); - expect(find.byKey(const Key('player-exit-clear-screen')), findsNothing); + expect(find.byKey(const Key('player-interaction-rail')), findsOneWidget); }); testWidgets('should_open_speed_sheet_and_apply_selected_speed', ( @@ -309,9 +298,9 @@ void main() { await _clearFromMore(tester); await tester.pump(); - expect(find.byKey(const Key('player-more')), findsNothing); + expect(find.byKey(const Key('player-more')), findsOneWidget); - await tester.tap(find.byKey(const Key('player-exit-clear-screen'))); + await tester.tap(find.byKey(const Key('player-bottom-clear-screen'))); await tester.pump(); await tester.drag(find.byType(PageView), const Offset(0, -550)); await tester.pumpAndSettle(); @@ -448,9 +437,11 @@ void main() { await tester.tap(find.byKey(const Key('player-more-clear'))); await tester.pumpAndSettle(); - expect(find.byKey(const Key('player-controls-top')), findsNothing); + expect(find.byKey(const Key('player-controls-top')), findsOneWidget); expect(find.byKey(const Key('player-controls-bottom')), findsNothing); - expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); + expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget); + expect(find.byKey(const Key('player-interaction-rail')), findsNothing); + expect(find.byTooltip('Exit clear screen'), findsOneWidget); }); testWidgets('should_enter_clear_screen_from_bottom_button', (tester) async { @@ -462,9 +453,19 @@ void main() { await tester.tap(find.byKey(const Key('player-bottom-clear-screen'))); await tester.pumpAndSettle(); - expect(find.byKey(const Key('player-controls-top')), findsNothing); + expect(find.byKey(const Key('player-controls-top')), findsOneWidget); expect(find.byKey(const Key('player-controls-bottom')), findsNothing); - expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); + expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget); + expect(find.byKey(const Key('player-interaction-rail')), findsNothing); + expect(find.byType(PlayerCenterToggle), findsNothing); + expect(find.byTooltip('Exit clear screen'), findsOneWidget); + + await tester.tap(find.byKey(const Key('player-bottom-clear-screen'))); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget); + expect(find.byKey(const Key('player-interaction-rail')), findsOneWidget); + expect(find.byType(PlayerCenterToggle), findsNothing); + expect(find.byTooltip('Clear screen'), findsOneWidget); }); testWidgets('should_open_unlock_panel_with_honest_method_states', (