fix(player): 复用播放会话进入全屏
This commit is contained in:
1 parent
ab4c246675
commit
23e80dd637
4 files changed
+303
-77
No files matched your search
@@ -17,12 +17,14 @@ 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/core/data/services/playback_session.dart';
|
||||
import 'package:fruitshorts/core/data/services/video_player_port.dart';
|
||||
import 'package:fruitshorts/core/theme/app_colors.dart';
|
||||
import 'package:fruitshorts/pages/auth/auth_view.dart';
|
||||
import 'package:fruitshorts/pages/player/player_view.dart';
|
||||
import 'package:fruitshorts/pages/player/widgets/player_center_toggle.dart';
|
||||
import 'package:fruitshorts/pages/player/widgets/player_render_stack.dart';
|
||||
import 'package:fruitshorts/pages/player/widgets/seek_progress_bar.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
import '../support/fake_catalog.dart';
|
||||
import '../support/fake_category.dart';
|
||||
@@ -86,7 +88,9 @@ void main() {
|
||||
testWidgets('should_preserve_recommend_feed_when_full_player_pops', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpApp(tester);
|
||||
final factory = _RouteVideoFactory();
|
||||
final playback = FakePlaybackRepository();
|
||||
await _pumpApp(tester, playerFactory: factory.create, playback: playback);
|
||||
await tester.tap(find.byKey(const Key('tab-recommend')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -101,27 +105,80 @@ void main() {
|
||||
expect(renderStack, findsOneWidget);
|
||||
final playerState = tester.state(recommendPlayer);
|
||||
final renderState = tester.state(renderStack);
|
||||
final currentSurface = find.descendant(
|
||||
of: recommendPlayer,
|
||||
matching: find.byKey(
|
||||
const ValueKey('player-render-slot-current'),
|
||||
),
|
||||
);
|
||||
final controller = factory.created.first.controller;
|
||||
final createdBefore = factory.created.length;
|
||||
final requestsBefore = playback.requests.length;
|
||||
expect(controller.value.position, const Duration(seconds: 5));
|
||||
expect(
|
||||
find.descendant(
|
||||
of: currentSurface,
|
||||
matching: find.byKey(const Key('player-single-placeholder')),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(const Key('home-feed-full-series')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(PlayerPage), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-back')), findsOneWidget);
|
||||
expect(factory.created.length, createdBefore);
|
||||
expect(playback.requests.length, requestsBefore);
|
||||
expect(controller.value.position, const Duration(seconds: 5));
|
||||
expect(
|
||||
tester.widget<PlayerPage>(find.byType(PlayerPage).last).homeMode,
|
||||
isFalse,
|
||||
find.descendant(
|
||||
of: currentSurface,
|
||||
matching: find.byKey(const Key('player-single-placeholder')),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
|
||||
tester.state<NavigatorState>(find.byType(Navigator).first).pop();
|
||||
await tester.pump();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('recommend-page')), findsOneWidget);
|
||||
expect(recommendPlayer, findsOneWidget);
|
||||
expect(renderStack, findsOneWidget);
|
||||
expect(factory.created.length, createdBefore);
|
||||
expect(playback.requests.length, requestsBefore);
|
||||
expect(controller.value.position, const Duration(seconds: 5));
|
||||
expect(tester.state(recommendPlayer), same(playerState));
|
||||
expect(tester.state(renderStack), same(renderState));
|
||||
expect(find.byKey(const Key('recommend-feed-skeleton')), findsNothing);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: currentSurface,
|
||||
matching: find.byKey(const Key('player-single-placeholder')),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('should_swipe_full_player_without_creating_another_session', (
|
||||
tester,
|
||||
) async {
|
||||
final factory = _RouteVideoFactory();
|
||||
await _pumpApp(tester, playerFactory: factory.create);
|
||||
await tester.tap(find.byKey(const Key('tab-recommend')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(tester.state(recommendPlayer), same(playerState));
|
||||
expect(tester.state(renderStack), same(renderState));
|
||||
await tester.tap(find.byKey(const Key('home-feed-full-series')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final createdBefore = factory.created.length;
|
||||
await tester.drag(
|
||||
find.byKey(const Key('player-video-tap')),
|
||||
const Offset(0, -560),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(PlayerPage), findsOneWidget);
|
||||
expect(factory.created.length, lessThanOrEqualTo(createdBefore + 1));
|
||||
expect(find.byKey(const Key('player-render-stack')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_render_player_loading_indicators_at_compact_size', (
|
||||
@@ -1482,6 +1539,55 @@ Future<void> _pumpApp(
|
||||
if (settle) await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
class _RouteVideoFactory {
|
||||
final List<_RouteVideoPlayer> created = [];
|
||||
|
||||
PlayerPort create(Episode episode) {
|
||||
final player = _RouteVideoPlayer(episode);
|
||||
created.add(player);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
||||
class _RouteVideoPlayer extends VideoPlayerPort {
|
||||
_RouteVideoPlayer(super.episode);
|
||||
|
||||
@override
|
||||
Future<void> initialize() async {
|
||||
controller.value = const VideoPlayerValue(
|
||||
duration: Duration(minutes: 1),
|
||||
size: Size(1280, 720),
|
||||
position: Duration(seconds: 5),
|
||||
isInitialized: true,
|
||||
isPlaying: true,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> play() async {
|
||||
final value = controller.value;
|
||||
controller.value = VideoPlayerValue(
|
||||
duration: value.duration,
|
||||
size: value.size,
|
||||
position: value.position,
|
||||
isInitialized: value.isInitialized,
|
||||
isPlaying: true,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> pause() async {
|
||||
final value = controller.value;
|
||||
controller.value = VideoPlayerValue(
|
||||
duration: value.duration,
|
||||
size: value.size,
|
||||
position: value.position,
|
||||
isInitialized: value.isInitialized,
|
||||
isPlaying: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _RecordingPlayer implements PlayerPort {
|
||||
bool playing = false;
|
||||
|
||||
|
||||
@@ -464,28 +464,28 @@ void main() {
|
||||
expect(find.byKey(const Key('recommend-tab-recommend')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_open_standalone_player_from_title_and_watch_all', (
|
||||
testWidgets('should_open_full_player_presentation_from_title_and_watch_all', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpRecommend(tester);
|
||||
|
||||
await tester.tap(find.byKey(const Key('home-feed-series-name')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(PlayerPage), findsOneWidget);
|
||||
expect(
|
||||
tester.widget<PlayerPage>(find.byType(PlayerPage).last).homeMode,
|
||||
isFalse,
|
||||
tester.widget<PlayerPage>(find.byType(PlayerPage)).homeMode,
|
||||
isTrue,
|
||||
);
|
||||
await tester.binding.handlePopRoute();
|
||||
expect(find.byKey(const Key('player-back')), findsOneWidget);
|
||||
tester.state<NavigatorState>(find.byType(Navigator).first).pop();
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('recommend-page')), findsOneWidget);
|
||||
expect(find.byKey(const Key('recommend-tab-recommend')), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byKey(const Key('home-feed-full-series')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
tester.widget<PlayerPage>(find.byType(PlayerPage).last).homeMode,
|
||||
isFalse,
|
||||
);
|
||||
expect(find.byType(PlayerPage), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-back')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_pull_refresh_recommend_feed_from_the_first_video', (
|
||||
|
||||
Reference in new issue
Block a user