fix(detail): 选集改为等宽懒加载网格

This commit is contained in:
Zhou Weidong committed 2026-10-19 16:32:09 +08:00
1 parent cbbd4c80e4
commit fbfb9769a0
2 files changed
+135 -20

No files matched your search

+95 -4
View File
@@ -5,20 +5,25 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:fruitshorts/core/data/models/drama.dart';
import 'package:fruitshorts/core/data/repositories/comment_repository.dart';
import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
import 'package:fruitshorts/core/data/repositories/interaction_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/catalog_controller.dart';
import 'package:fruitshorts/core/data/services/favorite_controller.dart';
import 'package:fruitshorts/core/data/services/interaction_controller.dart';
import 'package:fruitshorts/core/data/services/playback_session.dart';
import 'package:fruitshorts/core/platform/haptics.dart';
import 'package:fruitshorts/core/theme/app_theme.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
import 'package:fruitshorts/pages/drama_detail/drama_detail_view.dart';
import 'package:fruitshorts/pages/player/player_view.dart';
import '../support/fake_catalog.dart';
import '../support/fake_haptics.dart';
import '../support/fake_interaction_repositories.dart';
import '../support/widget_player.dart';
void main() {
testWidgets('should_render_preview_hero_cta_synopsis_and_episode_chips', (
@@ -78,6 +83,14 @@ void main() {
await tester.pumpWidget(_host(_detailDrama()));
await tester.pumpAndSettle();
final grid = tester.widget<GridView>(
find.byKey(const Key('detail-episode-chips')),
);
expect(
(grid.gridDelegate as SliverGridDelegateWithFixedCrossAxisCount)
.crossAxisCount,
6,
);
await tester.drag(
find.byKey(const Key('detail-scroll')),
const Offset(0, -520),
@@ -87,22 +100,96 @@ void main() {
expect(find.byKey(const Key('detail-episode-chip-8')), findsOneWidget);
expect(tester.takeException(), isNull);
});
testWidgets('should_render_sorted_six_column_grid_and_open_original_index', (
tester,
) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await tester.pumpWidget(_host(_detailDrama(count: 80)));
await tester.pumpAndSettle();
final grid = tester.widget<GridView>(
find.byKey(const Key('detail-episode-chips')),
);
final delegate =
grid.gridDelegate as SliverGridDelegateWithFixedCrossAxisCount;
expect(delegate.crossAxisCount, 6);
expect(delegate.mainAxisSpacing, 8);
expect(delegate.crossAxisSpacing, 8);
expect(delegate.childAspectRatio, closeTo(1.35, 0.001));
final chip1 = find.byKey(const Key('detail-episode-chip-1'));
final chip2 = find.byKey(const Key('detail-episode-chip-2'));
final chip6 = find.byKey(const Key('detail-episode-chip-6'));
final chip7 = find.byKey(const Key('detail-episode-chip-7'));
expect(tester.getTopLeft(chip1).dy, tester.getTopLeft(chip6).dy);
expect(
tester.getTopLeft(chip7).dy,
greaterThan(tester.getTopLeft(chip1).dy),
);
expect(tester.getTopLeft(chip1).dx, lessThan(tester.getTopLeft(chip2).dx));
expect(tester.getSize(chip1), tester.getSize(chip2));
await tester.drag(
find.byKey(const Key('detail-scroll')),
const Offset(0, -420),
);
await tester.pumpAndSettle();
final chip12 = find.byKey(const Key('detail-episode-chip-12'));
expect(chip12, findsOneWidget);
await tester.tap(chip12);
await tester.pumpAndSettle();
final player = tester.widget<PlayerPage>(find.byType(PlayerPage));
expect(player.initialIndex, 11);
});
testWidgets('should_sort_episode_chips_ascending_by_number', (tester) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await tester.pumpWidget(_host(_detailDrama(count: 80, descending: true)));
await tester.pumpAndSettle();
final chip1 = find.byKey(const Key('detail-episode-chip-1'));
final chip2 = find.byKey(const Key('detail-episode-chip-2'));
final chip6 = find.byKey(const Key('detail-episode-chip-6'));
final chip7 = find.byKey(const Key('detail-episode-chip-7'));
expect(tester.getTopLeft(chip1).dy, tester.getTopLeft(chip6).dy);
expect(tester.getTopLeft(chip1).dx, lessThan(tester.getTopLeft(chip2).dx));
expect(
tester.getTopLeft(chip7).dy,
greaterThan(tester.getTopLeft(chip1).dy),
);
expect(tester.getSize(chip1), tester.getSize(chip2));
});
}
Widget _host(Drama drama) {
final catalog = FakeCatalogRepository(dramas: [drama]);
final interactions = FakeInteractionRepository();
return MultiProvider(
providers: [
Provider<WatchHistoryRepository>.value(
value: InMemoryWatchHistoryRepository(),
),
Provider<PlaybackRepository>.value(value: FakePlaybackRepository()),
Provider<PlayerFactory>.value(value: createWidgetPlayer),
Provider(create: (_) => PlaybackCoordinator()),
Provider<InteractionRepository>.value(value: interactions),
Provider<CommentRepository>.value(value: FakeCommentRepository()),
Provider<Haptics>.value(value: FakeHaptics()),
ChangeNotifierProvider(
create: (_) => FavoriteController(InMemoryFavoriteRepository()),
),
ChangeNotifierProvider(
create: (_) => InteractionController(FakeInteractionRepository()),
create: (_) => InteractionController(interactions),
),
ChangeNotifierProvider(create: (_) => CatalogController(catalog)..load()),
],
@@ -116,7 +203,11 @@ Widget _host(Drama drama) {
);
}
Drama _detailDrama() {
Drama _detailDrama({int count = 8, bool descending = false}) {
final numbers = List<int>.generate(
count,
(index) => descending ? count - index : index + 1,
);
return Drama(
id: 'detail-k25',
title: 'Detail K25',
@@ -126,11 +217,11 @@ Drama _detailDrama() {
posterUrl: '/files/detail-k25.png',
genre: 'Urban Romance',
category: 'Romance',
totalEpisodes: 8,
totalEpisodes: count,
viewCount: 4800000,
detailLoaded: true,
episodes: [
for (var number = 1; number <= 8; number++)
for (final number in numbers)
Episode(
id: 'detail-k25-$number',
number: number,