feat(discover): 增加瀑布流与下拉刷新

This commit is contained in:
Zhou Weidong committed 2026-10-19 18:10:30 +08:00
1 parent cabc0e72f5
commit d271c43feb
3 files changed
+256 -151

No files matched your search

+79 -22
View File
@@ -12,7 +12,6 @@ import 'package:fruitshorts/core/data/repositories/category_repository.dart';
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/widgets/remote_image.dart';
import '../support/fake_catalog.dart';
import '../support/fake_interaction_repositories.dart';
@@ -26,7 +25,7 @@ void main() {
});
testWidgets(
'should_show_all_dramas_in_two_column_sliver_grid_without_continue_watching',
'should_show_all_dramas_in_two_column_masonry_without_continue_watching',
(tester) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
@@ -57,41 +56,48 @@ void main() {
);
}
expect(find.text('For You'), findsNothing);
final grid = tester.widget<SliverGrid>(
final masonry = tester.widget<Row>(
find.byKey(const Key('home-all-dramas-grid')),
);
final delegate =
grid.gridDelegate as SliverGridDelegateWithFixedCrossAxisCount;
expect(delegate.crossAxisCount, 2);
expect(delegate.crossAxisSpacing, 10);
expect(delegate.mainAxisSpacing, 10);
expect(delegate.mainAxisExtent, 164);
expect(masonry.children, hasLength(3));
expect((masonry.children[1] as SizedBox).width, 10);
expect(
tester
.widget<SliverPadding>(
find.byKey(const Key('home-all-dramas-section')),
)
.widget<Padding>(find.byKey(const Key('home-all-dramas-section')))
.padding,
const EdgeInsets.symmetric(horizontal: 14),
);
expect(find.byType(GridView), findsNothing);
expect(find.byType(CustomScrollView), findsOneWidget);
expect(find.byType(RemoteImage), findsWidgets);
expect(
tester
.getSize(find.byKey(const Key('home-drama-cover-city-lights-demo')))
.height,
120,
final signalCard = find.byKey(
const Key('home-drama-card-the-signal-demo'),
);
final cityCard = find.byKey(
const Key('home-drama-card-city-lights-demo'),
);
final vengeanceCard = find.byKey(
const Key('home-drama-card-vengeance-demo'),
);
expect(tester.getTopLeft(signalCard).dy, tester.getTopLeft(cityCard).dy);
expect(
tester.getTopLeft(vengeanceCard).dx,
tester.getTopLeft(signalCard).dx,
);
expect(
tester.getTopLeft(vengeanceCard).dy -
tester.getBottomLeft(signalCard).dy,
closeTo(10, 1),
);
final cover = find.byKey(const Key('home-drama-cover-city-lights-demo'));
expect(tester.getSize(cover).height, greaterThan(120));
expect(
tester
.widget<RemoteImage>(
find.descendant(of: cover, matching: find.byType(RemoteImage)),
.widget<Image>(
find.descendant(of: cover, matching: find.byType(Image)),
)
.fit,
BoxFit.contain,
BoxFit.fitWidth,
);
expect(
find.descendant(
@@ -104,6 +110,14 @@ void main() {
find.byKey(const Key('home-drama-title-city-lights-demo')),
findsOneWidget,
);
expect(
tester
.getTopLeft(
find.byKey(const Key('home-drama-title-city-lights-demo')),
)
.dy,
greaterThan(tester.getBottomLeft(cover).dy),
);
expect(
tester
.widget<Text>(
@@ -346,6 +360,29 @@ void main() {
);
});
testWidgets('should_refresh_feed_when_pulled_down', (tester) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
final counter = _CountingCategoryRepository(
_GridCategoryRepository(discoverFeed: _tallDiscoverFeed),
);
await _pumpApp(tester, categoryRepository: counter);
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
final before = counter.categoryLoads + counter.feedLoads;
await tester.drag(find.byType(CustomScrollView), const Offset(0, 320));
await tester.pump();
await tester.pump(const Duration(seconds: 1));
await tester.pumpAndSettle();
expect(counter.categoryLoads + counter.feedLoads, greaterThan(before));
expect(find.byType(RefreshProgressIndicator), findsNothing);
});
testWidgets('should_show_continue_watching_only_when_a_record_exists', (
tester,
) async {
@@ -469,3 +506,23 @@ final _tallDiscoverFeed = HomeFeed(
),
],
);
class _CountingCategoryRepository implements CategoryRepository {
_CountingCategoryRepository(this.delegate);
final CategoryRepository delegate;
int categoryLoads = 0;
int feedLoads = 0;
@override
Future<List<ContentCategory>> fetchCategories() {
categoryLoads++;
return delegate.fetchCategories();
}
@override
Future<HomeFeed> fetchDiscoverFeed() {
feedLoads++;
return delegate.fetchDiscoverFeed();
}
}