fix(home): 修正首页分类与卡片布局
This commit is contained in:
1 parent
10477562d4
commit
aa4870cce6
14 files changed
+573
-459
No files matched your search
@@ -79,14 +79,14 @@ void main() {
|
||||
);
|
||||
expect(views.style?.fontSize, AppDimens.cardViewsFont);
|
||||
expect(views.style?.color, AppColors.textPrimary);
|
||||
final tag = find.byKey(const Key('following-tag-the-signal-demo-0'));
|
||||
expect(tag, findsOneWidget);
|
||||
expect(tester.getSize(tag).height, AppDimens.cardTagHeight);
|
||||
final tagText = tester.widget<Text>(
|
||||
find.descendant(of: tag, matching: find.byType(Text)),
|
||||
final tags = tester.widget<Text>(
|
||||
find.byKey(const Key('following-tags-the-signal-demo')),
|
||||
);
|
||||
expect(tagText.style?.fontSize, AppDimens.cardTagFont);
|
||||
expect(tagText.style?.color, AppColors.textTertiary);
|
||||
expect(tags.data, 'Suspense | Mystery');
|
||||
expect(tags.style?.fontSize, AppDimens.cardTagFont);
|
||||
expect(tags.style?.color, AppColors.textTertiary);
|
||||
expect(tester.getTopLeft(title).dx, tester.getTopLeft(cover).dx);
|
||||
expect(tester.getTopLeft(tags).dx, tester.getTopLeft(cover).dx);
|
||||
|
||||
await tester.tap(find.byKey(const Key('following-edit')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -26,16 +26,17 @@ void main() {
|
||||
);
|
||||
|
||||
final card = find.byKey(const Key('home-feed-card-anime-card'));
|
||||
final container = tester.widget<Container>(card);
|
||||
final decoration = container.decoration! as BoxDecoration;
|
||||
expect(decoration.color, AppColors.contentCard);
|
||||
expect(decoration.boxShadow, isNull);
|
||||
expect(tester.widget<Material>(card).color, AppColors.transparent);
|
||||
expect(
|
||||
decoration.borderRadius,
|
||||
BorderRadius.circular(AppDimens.homeCardRadius),
|
||||
tester
|
||||
.widgetList<Container>(
|
||||
find.descendant(of: card, matching: find.byType(Container)),
|
||||
)
|
||||
.map((container) => container.decoration)
|
||||
.whereType<BoxDecoration>()
|
||||
.every((decoration) => decoration.border == null),
|
||||
isTrue,
|
||||
);
|
||||
expect((decoration.border! as Border).top.width, 1);
|
||||
expect((decoration.border! as Border).top.color, AppColors.contentBorder);
|
||||
|
||||
final cover = find.byKey(const Key('home-feed-cover-anime-card'));
|
||||
final coverSize = tester.getSize(cover);
|
||||
@@ -70,22 +71,14 @@ void main() {
|
||||
expect(title.style?.fontSize, AppDimens.cardTitleFont);
|
||||
expect(title.style?.fontWeight, FontWeight.w500);
|
||||
expect(title.style?.height, AppDimens.cardTitleLineHeight);
|
||||
final firstTag = find.byKey(const Key('home-feed-tag-anime-card-0'));
|
||||
expect(firstTag, findsOneWidget);
|
||||
expect(find.byKey(const Key('home-feed-tag-anime-card-1')), findsOneWidget);
|
||||
expect(find.text('Romance'), findsOneWidget);
|
||||
expect(find.text('Urban'), findsOneWidget);
|
||||
final tagContainer = tester.widget<Container>(firstTag);
|
||||
expect(tester.getSize(firstTag).height, AppDimens.cardTagHeight);
|
||||
expect(
|
||||
(tagContainer.decoration! as BoxDecoration).borderRadius,
|
||||
BorderRadius.circular(AppDimens.cardTagRadius),
|
||||
final tags = tester.widget<Text>(
|
||||
find.byKey(const Key('home-feed-tags-anime-card')),
|
||||
);
|
||||
final tagText = tester.widget<Text>(
|
||||
find.descendant(of: firstTag, matching: find.byType(Text)),
|
||||
);
|
||||
expect(tagText.style?.fontSize, AppDimens.cardTagFont);
|
||||
expect(tagText.style?.color, AppColors.textTertiary);
|
||||
expect(tags.data, 'Romance | Urban');
|
||||
expect(tags.style?.fontSize, AppDimens.cardTagFont);
|
||||
expect(tags.style?.color, AppColors.textTertiary);
|
||||
expect(tester.getTopLeft(title).dx, tester.getTopLeft(cover).dx);
|
||||
expect(tester.getTopLeft(tags).dx, tester.getTopLeft(cover).dx);
|
||||
|
||||
await tester.tap(card);
|
||||
expect(taps, 1);
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:fruitshorts/core/data/repositories/catalog_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/pages/home/widgets/home_feed_card.dart';
|
||||
import 'package:fruitshorts/pages/player/player_view.dart';
|
||||
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
|
||||
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
|
||||
@@ -88,29 +89,82 @@ void main() {
|
||||
expect(find.byKey(const Key('home-tag-uplifting')), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('should_open_existing_pages_from_home_sections', (tester) async {
|
||||
testWidgets('should_switch_home_sections_without_pushing_pages', (
|
||||
tester,
|
||||
) async {
|
||||
final repository = _PagedCatalogRepository();
|
||||
await _pumpApp(tester, repository);
|
||||
|
||||
String firstDramaId() {
|
||||
return tester
|
||||
.widget<HomeFeedCard>(find.byType(HomeFeedCard).first)
|
||||
.drama
|
||||
.id;
|
||||
}
|
||||
|
||||
expect(find.byKey(const Key('home-grid')), findsOneWidget);
|
||||
expect(firstDramaId(), 'page1-0');
|
||||
|
||||
await tester.tap(find.byKey(const Key('home-section-new')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('new-releases-page')), findsOneWidget);
|
||||
await tester.pageBack();
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('new-releases-page')), findsNothing);
|
||||
expect(firstDramaId(), 'page1-9');
|
||||
|
||||
await tester.ensureVisible(find.byKey(const Key('home-section-ranking')));
|
||||
await tester.tap(find.byKey(const Key('home-section-ranking')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('ranking-page')), findsOneWidget);
|
||||
await tester.pageBack();
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('ranking-page')), findsNothing);
|
||||
expect(firstDramaId(), 'page1-0');
|
||||
|
||||
await tester.ensureVisible(
|
||||
find.byKey(const Key('home-section-categories')),
|
||||
);
|
||||
await tester.tap(find.byKey(const Key('home-section-categories')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('filter-page')), findsOneWidget);
|
||||
expect(find.byKey(const Key('filter-page')), findsNothing);
|
||||
expect(find.byKey(const Key('home-grid-cards')), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byKey(const Key('home-section-category-古装')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(firstDramaId(), 'page1-0');
|
||||
|
||||
await tester.tap(find.byKey(const Key('home-section-category-社群')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('home-grid-empty')), findsOneWidget);
|
||||
expect(find.byKey(const Key('filter-page')), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('should_keep_scroll_position_when_switching_sections', (
|
||||
tester,
|
||||
) async {
|
||||
final repository = _PagedCatalogRepository();
|
||||
await _pumpApp(tester, repository);
|
||||
|
||||
await tester.drag(
|
||||
find.byKey(const Key('home-grid-scroll')),
|
||||
const Offset(0, -320),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
final scrollable = find
|
||||
.descendant(
|
||||
of: find.byKey(const Key('home-grid-scroll')),
|
||||
matching: find.byType(Scrollable),
|
||||
)
|
||||
.first;
|
||||
final before = tester.state<ScrollableState>(scrollable).position.pixels;
|
||||
expect(before, greaterThan(0));
|
||||
|
||||
await tester.tap(find.byKey(const Key('home-section-new')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('home-section-featured')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final afterScrollable = find
|
||||
.descendant(
|
||||
of: find.byKey(const Key('home-grid-scroll')),
|
||||
matching: find.byType(Scrollable),
|
||||
)
|
||||
.first;
|
||||
expect(
|
||||
tester.state<ScrollableState>(afterScrollable).position.pixels,
|
||||
closeTo(before, 0.1),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('should_load_next_page_without_expanding_page_size', (
|
||||
@@ -232,14 +286,16 @@ class _PagedCatalogRepository implements CatalogRepository {
|
||||
}
|
||||
|
||||
Drama _drama(String id) {
|
||||
final index = int.tryParse(id.split('-').last) ?? 0;
|
||||
return Drama(
|
||||
id: id,
|
||||
title: 'Grid Drama $id',
|
||||
synopsis: 'synopsis',
|
||||
posterUrl: '',
|
||||
genre: 'Romance',
|
||||
category: 'Urban',
|
||||
viewCount: 200000,
|
||||
category: index.isEven ? '古装' : 'Urban',
|
||||
viewCount: (10 - index) * 10000,
|
||||
createdAt: DateTime(2026, 10, 1).add(Duration(days: index)),
|
||||
detailLoaded: true,
|
||||
episodes: [
|
||||
Episode(
|
||||
|
||||
@@ -109,23 +109,29 @@ void main() {
|
||||
);
|
||||
expect(placeholder.style?.fontSize, AppDimens.searchPlaceholderFont);
|
||||
expect(placeholder.style?.color, AppColors.textSecondary);
|
||||
final selectedPrimary = tester.widget<Text>(
|
||||
final selectedPrimary = tester.widget<AnimatedDefaultTextStyle>(
|
||||
find.byKey(const Key('home-primary-label-featured')),
|
||||
);
|
||||
final unselectedPrimary = tester.widget<AnimatedDefaultTextStyle>(
|
||||
find.byKey(const Key('home-primary-label-newReleases')),
|
||||
);
|
||||
expect(
|
||||
selectedPrimary.style.fontSize,
|
||||
AppDimens.homePrimaryTabSelectedFont,
|
||||
);
|
||||
expect(selectedPrimary.style.fontWeight, FontWeight.w700);
|
||||
expect(selectedPrimary.style.color, AppColors.navSelected);
|
||||
expect(selectedPrimary.duration, AppDimens.homePrimaryTabAnimationDuration);
|
||||
expect(unselectedPrimary.style.fontSize, AppDimens.homePrimaryTabFont);
|
||||
expect(unselectedPrimary.style.fontWeight, FontWeight.w400);
|
||||
expect(unselectedPrimary.style.color, AppColors.textTertiary);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('home-section-featured')),
|
||||
matching: find.text('Featured'),
|
||||
matching: find.byType(Container),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
final unselectedPrimary = tester.widget<Text>(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('home-section-new')),
|
||||
matching: find.text('New'),
|
||||
),
|
||||
);
|
||||
expect(selectedPrimary.style?.fontSize, AppDimens.homePrimaryTabFont);
|
||||
expect(selectedPrimary.style?.fontWeight, FontWeight.w700);
|
||||
expect(selectedPrimary.style?.color, AppColors.navSelected);
|
||||
expect(unselectedPrimary.style?.fontWeight, FontWeight.w400);
|
||||
expect(unselectedPrimary.style?.color, AppColors.textTertiary);
|
||||
final secondaryTag = tester.widget<Text>(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('home-tag-hot')),
|
||||
@@ -135,18 +141,38 @@ void main() {
|
||||
expect(secondaryTag.style?.fontSize, AppDimens.homeSecondaryTagFont);
|
||||
expect(secondaryTag.style?.fontWeight, FontWeight.w400);
|
||||
expect(secondaryTag.style?.color, AppColors.textTertiary);
|
||||
final unselectedTagChip = tester.widget<Container>(
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('home-tag-hot')),
|
||||
matching: find.byType(Container),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
final primaryStart = tester.getTopLeft(find.text('Featured'));
|
||||
final pageStart = tester.getTopLeft(searchBox);
|
||||
expect(primaryStart.dx, pageStart.dx);
|
||||
final primaryGap =
|
||||
tester.getTopLeft(find.text('New')).dx -
|
||||
tester.getBottomRight(find.text('Featured')).dx;
|
||||
expect(primaryGap, closeTo(AppDimens.homePrimaryCategoryGap, 0.1));
|
||||
final tagStart = tester.getTopLeft(find.text('Hot'));
|
||||
expect(tagStart.dx, pageStart.dx);
|
||||
final tagGap =
|
||||
tester.getTopLeft(find.text('Uplifting')).dx -
|
||||
tester.getBottomRight(find.text('Hot')).dx;
|
||||
expect(tagGap, closeTo(AppDimens.homeSecondaryTagGap, 0.1));
|
||||
await tester.tap(find.byKey(const Key('home-tag-hot')));
|
||||
await tester.pump();
|
||||
final selectedTagChip = tester.widget<Container>(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('home-tag-hot')),
|
||||
matching: find.byType(Container),
|
||||
),
|
||||
);
|
||||
expect(
|
||||
(unselectedTagChip.decoration! as BoxDecoration).color,
|
||||
AppColors.transparent,
|
||||
(selectedTagChip.decoration! as BoxDecoration).color,
|
||||
AppColors.contentSurface,
|
||||
);
|
||||
await tester.tap(find.byKey(const Key('home-tag-hot')));
|
||||
await tester.pump();
|
||||
final selectedTag = tester.widget<Text>(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('home-tag-hot')),
|
||||
|
||||
@@ -103,18 +103,14 @@ void main() {
|
||||
);
|
||||
expect(views.style?.fontSize, AppDimens.cardViewsFont);
|
||||
expect(views.style?.color, AppColors.textPrimary);
|
||||
final tag = find.byKey(const Key('recommend-tag-hits-the-signal-demo-0'));
|
||||
expect(tag, findsOneWidget);
|
||||
expect(tester.getSize(tag).height, AppDimens.cardTagHeight);
|
||||
final tagText = tester.widget<Text>(
|
||||
find.descendant(of: tag, matching: find.byType(Text)),
|
||||
);
|
||||
expect(tagText.style?.fontSize, AppDimens.cardTagFont);
|
||||
expect(tagText.style?.color, AppColors.textTertiary);
|
||||
expect(
|
||||
(tester.widget<Container>(tag).decoration! as BoxDecoration).borderRadius,
|
||||
BorderRadius.circular(AppDimens.cardTagRadius),
|
||||
final tags = tester.widget<Text>(
|
||||
find.byKey(const Key('recommend-tags-hits-the-signal-demo')),
|
||||
);
|
||||
expect(tags.data, 'Suspense | Mystery');
|
||||
expect(tags.style?.fontSize, AppDimens.cardTagFont);
|
||||
expect(tags.style?.color, AppColors.textTertiary);
|
||||
expect(tester.getTopLeft(cardTitle).dx, tester.getTopLeft(cover).dx);
|
||||
expect(tester.getTopLeft(tags).dx, tester.getTopLeft(cover).dx);
|
||||
});
|
||||
|
||||
testWidgets('should_switch_inner_tabs_without_losing_grid_filter_state', (
|
||||
@@ -132,8 +128,13 @@ void main() {
|
||||
for (var row = 0; row < 4; row++) {
|
||||
expect(find.byKey(Key('all-filter-row-$row')), findsOneWidget);
|
||||
}
|
||||
expect(find.byKey(const Key('all-filter-local')), findsNothing);
|
||||
expect(find.byKey(const Key('all-filter-subtitles')), findsNothing);
|
||||
expect(find.byKey(const Key('all-filter-local')), findsOneWidget);
|
||||
expect(find.byKey(const Key('all-filter-subtitles')), findsOneWidget);
|
||||
await tester.tap(find.byKey(const Key('all-filter-local')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('all-dramas-empty')), findsOneWidget);
|
||||
await tester.tap(find.byKey(const Key('all-filter-all')).first);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('all-sort-new')));
|
||||
await tester.pump();
|
||||
expect(_textStyle(tester, 'New').fontWeight, FontWeight.w700);
|
||||
|
||||
Reference in new issue
Block a user