From 35cbdd2bd3bc9f0b9dc5666639a29064263ecaa5 Mon Sep 17 00:00:00 2001 From: Zhou Weidong <502333560@qq.com> Date: Tue, 3 Nov 2026 18:28:14 +0800 Subject: [PATCH] =?UTF-8?q?perf(player):=20=E4=BC=98=E5=8C=96=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E5=93=8D=E5=BA=94=E4=B8=8E=E4=BA=92=E5=8A=A8=E5=8F=8D?= =?UTF-8?q?=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../player/widgets/interaction_rail.dart | 6 +++--- .../widgets/player_tap_gesture_region.dart | 2 +- test/player/double_tap_like_test.dart | 16 +++++++------- test/player/interaction_rail_motion_test.dart | 21 +++++++++++++++---- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/lib/pages/player/widgets/interaction_rail.dart b/lib/pages/player/widgets/interaction_rail.dart index c3e9fcd..49ca429 100644 --- a/lib/pages/player/widgets/interaction_rail.dart +++ b/lib/pages/player/widgets/interaction_rail.dart @@ -12,9 +12,9 @@ const double _defaultIconSize = 32; const double _defaultCountFont = 12; const double _defaultIconCountGap = 2; const double _defaultItemGap = 24; -const _tapDuration = Duration(milliseconds: 360); -const double _popScale = 1.34; -const double _cancelScale = 0.68; +const _tapDuration = Duration(milliseconds: 220); +const double _popScale = 1.14; +const double _cancelScale = 0.86; const double _popWeight = 40; const double _settleWeight = 60; final _growTween = _tapTween(_popScale); diff --git a/lib/pages/player/widgets/player_tap_gesture_region.dart b/lib/pages/player/widgets/player_tap_gesture_region.dart index 032d159..c76d71a 100644 --- a/lib/pages/player/widgets/player_tap_gesture_region.dart +++ b/lib/pages/player/widgets/player_tap_gesture_region.dart @@ -39,7 +39,7 @@ class PlayerTapGestureRegion extends StatefulWidget { } class _PlayerTapGestureRegionState extends State { - static const Duration _singleTapDelay = Duration(milliseconds: 320); + static const Duration _singleTapDelay = Duration(milliseconds: 240); Timer? _singleTapTimer; DateTime? _lastDownAt; diff --git a/test/player/double_tap_like_test.dart b/test/player/double_tap_like_test.dart index c6a93a9..6560567 100644 --- a/test/player/double_tap_like_test.dart +++ b/test/player/double_tap_like_test.dart @@ -16,8 +16,10 @@ import '../support/fake_haptics.dart'; import '../support/fake_interaction_repositories.dart'; void main() { - testWidgets('double tap within 320ms never pauses', (tester) async { - for (final delay in [120, 250, 300]) { + testWidgets('should_like_without_pausing_when_double_tap_within_240ms', ( + tester, + ) async { + for (final delay in [80, 160, 220]) { final repository = FakeInteractionRepository(); final haptics = FakeHaptics(); final key = GlobalKey<_HarnessState>(); @@ -53,7 +55,7 @@ void main() { } }); - testWidgets('taps 500ms apart toggle playback twice', (tester) async { + testWidgets('should_toggle_twice_when_taps_are_260ms_apart', (tester) async { final key = GlobalKey<_HarnessState>(); final clock = _TestClock(); await _pumpHarness( @@ -67,15 +69,15 @@ void main() { await tester.tapAt( tester.getCenter(find.byKey(const Key('home-feed-gesture'))), ); - clock.advance(const Duration(milliseconds: 500)); - await tester.pump(const Duration(milliseconds: 500)); + clock.advance(const Duration(milliseconds: 260)); + await tester.pump(const Duration(milliseconds: 260)); expect(key.currentState!.pauseToggles, 1); await tester.tapAt( tester.getCenter(find.byKey(const Key('home-feed-gesture'))), ); - clock.advance(const Duration(milliseconds: 500)); - await tester.pump(const Duration(milliseconds: 500)); + clock.advance(const Duration(milliseconds: 260)); + await tester.pump(const Duration(milliseconds: 260)); expect(key.currentState!.pauseToggles, 2); }); diff --git a/test/player/interaction_rail_motion_test.dart b/test/player/interaction_rail_motion_test.dart index dc61ae7..b69a9b3 100644 --- a/test/player/interaction_rail_motion_test.dart +++ b/test/player/interaction_rail_motion_test.dart @@ -14,11 +14,13 @@ const _popFrame = Duration(milliseconds: 100); const _buttonSize = 48.0; const _compactGap = 6.0; const _epsilon = 0.01; -const _cancelledMaximum = 0.8; -const _popMinimum = 1.22; +const _cancelledMinimum = 0.8; +const _popMinimum = 1.03; +const _popMaximum = 1.18; const _burstKey = Key('rail-tap-burst'); const _directionFrame = Duration(milliseconds: 60); -const _directionFrames = 4; +const _directionFrames = 2; +const _motionCompletion = Duration(milliseconds: 230); Future _pumpRail( WidgetTester tester, { @@ -115,7 +117,9 @@ void main() { await tester.pump(_popFrame); expect( _scale(tester, key), - selected ? lessThan(_cancelledMaximum) : greaterThan(_popMinimum), + selected + ? allOf(greaterThan(_cancelledMinimum), lessThan(1)) + : allOf(greaterThan(_popMinimum), lessThan(_popMaximum)), ); _expectBurst(tester, key, selected); expect(tester.getRect(_button(key)), rect); @@ -155,6 +159,15 @@ void main() { }, ); + testWidgets('should_finish_feedback_within_230ms', (tester) async { + await _pumpRail(tester, onTap: () {}); + await tester.tap(_button(_likeKey)); + await tester.pump(); + await tester.pump(_motionCompletion); + expect(find.byKey(_burstKey), findsNothing); + expect(_scale(tester, _likeKey), closeTo(1, _epsilon)); + }); + testWidgets('should_keep_callbacks_without_motion_when_reduced', ( tester, ) async {