fix(player): 修复进度条拖动树稳定性

This commit is contained in:
Zhou Weidong committed 2026-10-22 20:26:58 +08:00
1 parent 5af6caea6e
commit cf6d12b7c8
6 files changed
+216 -23

No files matched your search

+141
View File
@@ -2,6 +2,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fruitshorts/core/data/models/drama.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
import 'package:fruitshorts/pages/player/widgets/home_feed_overlay.dart';
import 'package:fruitshorts/pages/player/widgets/seek_progress_bar.dart';
import 'package:video_player/video_player.dart';
@@ -68,6 +71,86 @@ void main() {
6,
);
});
testWidgets('feed progress tap does not clear overlay content', (
tester,
) async {
await _pumpFeedOverlay(tester);
await tester.tap(find.byKey(const Key('home-feed-progress')));
await tester.pumpAndSettle();
expect(tester.takeException(), isNull);
expect(find.byKey(const Key('home-feed-progress')), findsOneWidget);
expect(
tester
.widget<AnimatedOpacity>(
find.byKey(const Key('home-feed-content-opacity')),
)
.opacity,
1,
);
});
testWidgets('feed progress drag then immediate release restores content', (
tester,
) async {
await _pumpFeedOverlay(tester);
final gesture = await tester.startGesture(
tester.getCenter(find.byKey(const Key('home-feed-progress'))),
);
await gesture.moveBy(const Offset(80, 0));
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(tester.takeException(), isNull);
expect(find.byKey(const Key('home-feed-progress')), findsOneWidget);
expect(
tester
.widget<AnimatedOpacity>(
find.byKey(const Key('home-feed-content-opacity')),
)
.opacity,
1,
);
expect(
tester.getSize(find.byKey(const Key('home-feed-progress-track'))).height,
2,
);
});
testWidgets('feed progress remains mounted and thick while dragging', (
tester,
) async {
await _pumpFeedOverlay(tester);
final progress = find.byKey(const Key('home-feed-progress'));
final gesture = await tester.startGesture(tester.getCenter(progress));
await gesture.moveBy(const Offset(80, 0));
await tester.pump();
await tester.pump(const Duration(milliseconds: 130));
expect(tester.takeException(), isNull);
expect(progress, findsOneWidget);
expect(find.byKey(const Key('scrub-preview-time-bubble')), findsOneWidget);
expect(
tester
.widget<AnimatedOpacity>(
find.byKey(const Key('home-feed-content-opacity')),
)
.opacity,
0,
);
expect(
tester.getSize(find.byKey(const Key('home-feed-progress-track'))).height,
6,
);
await gesture.up();
await tester.pumpAndSettle();
});
}
Future<_HarnessState> _pumpHarness(WidgetTester tester) async {
@@ -104,6 +187,64 @@ SliderThemeData _sliderTheme(WidgetTester tester) {
.data;
}
Future<ValueNotifier<VideoPlayerValue>> _pumpFeedOverlay(
WidgetTester tester,
) async {
final controller = ValueNotifier<VideoPlayerValue>(
const VideoPlayerValue(
duration: Duration(minutes: 2),
position: Duration(seconds: 20),
isInitialized: true,
),
);
addTearDown(controller.dispose);
await tester.pumpWidget(
MaterialApp(
locale: const Locale('en'),
supportedLocales: AppLocalizations.supportedLocales,
localizationsDelegates: AppLocalizations.localizationsDelegates,
home: Builder(
builder: (context) => Scaffold(
body: HomeFeedOverlay(
l10n: AppLocalizations.of(context)!,
drama: const Drama(
id: 'scrub-drama',
title: 'Scrub Drama',
synopsis: 'A short synopsis.',
posterUrl: '',
totalEpisodes: 8,
),
episode: const Episode(
id: 'scrub-episode',
number: 1,
title: 'Scrub Episode',
isFree: true,
),
controller: controller,
locked: false,
liked: false,
saved: false,
visible: true,
boosting: false,
onLike: () {},
onSave: () {},
onComments: () {},
onShare: () {},
onDetail: () {},
onOpenFullPlayer: () {},
onTogglePlay: () {},
onBoostStart: () {},
onBoostEnd: () {},
onMore: () {},
),
),
),
),
);
await tester.pumpAndSettle();
return controller;
}
class _Harness extends StatefulWidget {
const _Harness({super.key, required this.controller});