From 4d7173d035ab51416ab5e2cab7e2bd7f8ee20761 Mon Sep 17 00:00:00 2001 From: Zhou Weidong <502333560@qq.com> Date: Mon, 19 Oct 2026 17:44:06 +0800 Subject: [PATCH] =?UTF-8?q?fix(player):=20=E8=B0=83=E6=95=B4=20rail=20?= =?UTF-8?q?=E5=80=8D=E9=80=9F=E5=BC=B9=E7=AA=97=E4=B8=8E=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/player/player_view.dart | 56 +++++++--------- .../player/widgets/home_feed_overlay.dart | 2 +- test/home/home_preview_layout_test.dart | 4 ++ test/playback/seek_progress_bar_test.dart | 2 + test/player/player_fullscreen_test.dart | 66 ++++++++++++++++--- 5 files changed, 88 insertions(+), 42 deletions(-) diff --git a/lib/pages/player/player_view.dart b/lib/pages/player/player_view.dart index a333628..20ac336 100644 --- a/lib/pages/player/player_view.dart +++ b/lib/pages/player/player_view.dart @@ -683,37 +683,7 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> { key: const Key('player-controls-visible'), children: [ _topBar(context), - Expanded( - child: Stack( - children: [ - Positioned( - right: 10, - bottom: 14, - child: Material( - color: Colors.transparent, - child: InkWell( - key: const Key('player-speed'), - onTap: widget.onSpeedTap, - borderRadius: BorderRadius.circular(6), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 4, - vertical: 2, - ), - child: Text( - _speedLabel(widget.playbackSpeed), - style: const TextStyle( - color: Color(0xFFDDDDDD), - fontSize: 9, - ), - ), - ), - ), - ), - ), - ], - ), - ), + const Spacer(), Padding( key: const Key('player-controls-bottom'), padding: const EdgeInsets.fromLTRB(14, 8, 14, 12), @@ -723,7 +693,7 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> { key: const Key('player-progress'), valueListenable: widget.controller, semanticsLabel: widget.l10n.seekVideo, - showTimes: false, + showTimes: true, onScrubStart: widget.onScrubStart, onSeek: widget.onSeek, ), @@ -886,6 +856,28 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> { child: Column( mainAxisSize: MainAxisSize.min, children: [ + ListTile( + key: const Key('player-more-speed'), + leading: const Icon( + Icons.speed_rounded, + color: AppColors.secondary, + ), + title: Text(widget.l10n.playbackSpeed), + trailing: Text( + _speedLabel(widget.playbackSpeed), + style: const TextStyle( + color: AppColors.blue, + fontSize: 12, + fontWeight: FontWeight.w600, + ), + ), + onTap: () { + Navigator.pop(sheetContext); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) widget.onSpeedTap(); + }); + }, + ), ListTile( key: const Key('player-more-download'), leading: const Icon( diff --git a/lib/pages/player/widgets/home_feed_overlay.dart b/lib/pages/player/widgets/home_feed_overlay.dart index 77b35da..3fc5c00 100644 --- a/lib/pages/player/widgets/home_feed_overlay.dart +++ b/lib/pages/player/widgets/home_feed_overlay.dart @@ -55,7 +55,7 @@ class HomeFeedOverlay extends StatelessWidget { _header(context), Expanded( child: Align( - alignment: Alignment.centerRight, + alignment: const Alignment(1.0, 0.45), child: Padding( padding: const EdgeInsets.fromLTRB(0, 0, 12, 16), child: _rail(), diff --git a/test/home/home_preview_layout_test.dart b/test/home/home_preview_layout_test.dart index 6d267ae..753de68 100644 --- a/test/home/home_preview_layout_test.dart +++ b/test/home/home_preview_layout_test.dart @@ -61,6 +61,10 @@ void main() { find.byKey(const Key('home-feed-episode')), ); expect(episodeRect.left, lessThan(cardRect.center.dx)); + final railCenter = tester.getCenter(find.byKey(const Key('rail-like'))); + final railBottom = tester.getBottomLeft(find.byKey(const Key('rail-save'))); + expect(railCenter.dy, greaterThan(844 * 0.4)); + expect(railBottom.dy, lessThan(cardRect.top)); expect(find.byKey(const Key('home-feed-follow-series')), findsOneWidget); expect(find.byKey(const Key('home-feed-episodes')), findsOneWidget); for (final key in const [Key('home-feed-search'), Key('home-feed-more')]) { diff --git a/test/playback/seek_progress_bar_test.dart b/test/playback/seek_progress_bar_test.dart index 67d3012..53ad74b 100644 --- a/test/playback/seek_progress_bar_test.dart +++ b/test/playback/seek_progress_bar_test.dart @@ -56,11 +56,13 @@ void main() { await tester.pump(); expect(started, 1); expect(target, isNull); + expect(find.textContaining('/ 00:12'), findsOneWidget); await gesture.up(); await tester.pumpAndSettle(); expect(target, isNotNull); expect(target!, greaterThan(const Duration(seconds: 3))); expect(target!, lessThan(const Duration(seconds: 12))); + expect(find.textContaining('/ 00:12'), findsNothing); }); testWidgets('should_show_time_only_while_dragging_when_seek_bar_is_compact', ( diff --git a/test/player/player_fullscreen_test.dart b/test/player/player_fullscreen_test.dart index 69c5a66..45fc167 100644 --- a/test/player/player_fullscreen_test.dart +++ b/test/player/player_fullscreen_test.dart @@ -10,6 +10,7 @@ import 'package:fruitshorts/core/data/repositories/favorite_repository.dart'; import 'package:fruitshorts/core/data/repositories/playback_repository.dart'; import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart'; import 'package:fruitshorts/pages/player/widgets/player_center_toggle.dart'; +import 'package:fruitshorts/pages/player/widgets/seek_progress_bar.dart'; import '../support/fake_catalog.dart'; import '../support/fake_category.dart'; @@ -260,8 +261,10 @@ void main() { await tester.tap(find.byKey(const Key('detail-cta'))); await tester.pumpAndSettle(); - expect(find.text('1.0x'), findsOneWidget); - await tester.tap(find.byKey(const Key('player-speed'))); + await tester.tap(find.byKey(const Key('player-more'))); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('player-more-speed')), findsOneWidget); + await tester.tap(find.byKey(const Key('player-more-speed'))); await tester.pumpAndSettle(); expect(find.byKey(const Key('player-speed-sheet')), findsOneWidget); @@ -273,7 +276,15 @@ void main() { await tester.pumpAndSettle(); expect(find.byKey(const Key('player-speed-sheet')), findsNothing); - expect(find.text('1.5x'), findsOneWidget); + await tester.tap(find.byKey(const Key('player-more'))); + await tester.pumpAndSettle(); + expect( + find.descendant( + of: find.byKey(const Key('player-more-speed')), + matching: find.text('1.5x'), + ), + findsOneWidget, + ); }); testWidgets('should_hide_speed_entry_in_clear_screen_and_keep_speed', ( @@ -289,24 +300,61 @@ void main() { await tester.tap(find.byKey(const Key('detail-cta'))); await tester.pumpAndSettle(); - await tester.tap(find.byKey(const Key('player-speed'))); + await tester.tap(find.byKey(const Key('player-more'))); + await tester.pumpAndSettle(); + await tester.tap(find.byKey(const Key('player-more-speed'))); await tester.pumpAndSettle(); await tester.tap(find.byKey(const Key('player-speed-1.5'))); await tester.pumpAndSettle(); - expect(find.text('1.5x'), findsOneWidget); await tester.tap(find.byKey(const Key('player-clear-screen'))); await tester.pump(); - expect(find.byKey(const Key('player-speed')), findsNothing); + expect(find.byKey(const Key('player-more')), findsNothing); await tester.tap(find.byKey(const Key('player-exit-clear-screen'))); await tester.pump(); - expect(find.byKey(const Key('player-speed')), findsOneWidget); - expect(find.text('1.5x'), findsOneWidget); + await tester.tap(find.byKey(const Key('player-more'))); + await tester.pumpAndSettle(); + expect( + find.descendant( + of: find.byKey(const Key('player-more-speed')), + matching: find.text('1.5x'), + ), + findsOneWidget, + ); + await tester.binding.handlePopRoute(); + await tester.pumpAndSettle(); await tester.drag(find.byType(PageView), const Offset(0, -550)); await tester.pumpAndSettle(); - expect(find.text('1.5x'), findsOneWidget); + await tester.tap(find.byKey(const Key('player-more'))); + await tester.pumpAndSettle(); + expect( + find.descendant( + of: find.byKey(const Key('player-more-speed')), + matching: find.text('1.5x'), + ), + findsOneWidget, + ); + }); + + testWidgets('should_enable_drag_time_preview_on_player_progress', ( + tester, + ) async { + await _pumpApp(tester); + await tester.binding.handlePopRoute(); + await tester.pumpAndSettle(); + await tester.binding.handlePopRoute(); + await tester.pumpAndSettle(); + await tester.tap(find.byKey(const Key('drawer-open-series'))); + await tester.pumpAndSettle(); + await tester.tap(find.byKey(const Key('detail-cta'))); + await tester.pumpAndSettle(); + + final bar = tester.widget( + find.byKey(const Key('player-progress')), + ); + expect(bar.showTimes, isTrue); }); testWidgets('should_clear_and_restore_home_feed_chrome', (tester) async {