feat(app): 客户端展示多语言并支持筛选分页

This commit is contained in:
Zhou Weidong committed 2026-10-24 17:20:24 +08:00
1 parent 8481611372
commit 8b50b5bd06
68 files changed
+2742 -1120

No files matched your search

+18 -24
View File
@@ -21,6 +21,8 @@ void main() {
title: 'A very long home grid drama title that must wrap',
dramaType: 'ANIME',
viewCount: 444500,
tag: '漫剧',
tagLocales: const {'zh': '漫剧', 'en': 'Anime', 'id': 'Anime'},
),
onTap: () => taps++,
);
@@ -52,7 +54,7 @@ void main() {
BorderRadius.circular(AppDimens.cardCoverRadius),
);
final badge = find.byKey(
const Key('drama-cover-badge-ribbon-anime-card-anime'),
const Key('drama-cover-badge-ribbon-anime-card-tag'),
);
expect(badge, findsOneWidget);
expect(
@@ -120,10 +122,7 @@ void main() {
expect(taps, 1);
});
testWidgets('should_choose_anime_new_and_hot_badges_from_real_data', (
tester,
) async {
final now = DateTime(2026, 10, 22, 12);
testWidgets('should_show_cover_badge_from_tag_locale', (tester) async {
await tester.pumpWidget(
MaterialApp(
theme: AppTheme.dark(),
@@ -134,18 +133,18 @@ void main() {
body: Row(
children: [
for (final drama in [
_drama(id: 'anime', title: 'Anime', dramaType: 'ANIME'),
_drama(
id: 'new',
title: 'New',
createdAt: now.subtract(const Duration(days: 2)),
id: 'tagged',
title: 'Tagged',
tag: '新剧',
tagLocales: const {'zh': '新剧', 'en': 'New', 'id': 'Baru'},
),
_drama(id: 'hot', title: 'Hot', isHot: true),
_drama(id: 'plain', title: 'Plain'),
])
SizedBox(
width: 130,
height: 240,
child: HomeFeedCard(drama: drama, onTap: () {}, now: now),
child: HomeFeedCard(drama: drama, onTap: () {}),
),
],
),
@@ -154,18 +153,10 @@ void main() {
);
await tester.pumpAndSettle();
expect(
find.byKey(const Key('drama-cover-badge-ribbon-anime-anime')),
findsOneWidget,
);
expect(
find.byKey(const Key('drama-cover-badge-ribbon-new-newRelease')),
findsOneWidget,
);
expect(
find.byKey(const Key('drama-cover-badge-ribbon-hot-hot')),
findsOneWidget,
);
final badge = find.byKey(const Key('drama-cover-badge-ribbon-tagged-tag'));
expect(badge, findsOneWidget);
expect(find.text('New'), findsOneWidget);
expect(find.byKey(const Key('drama-cover-badge-ribbon-plain-tag')), findsNothing);
});
}
@@ -176,6 +167,8 @@ Drama _drama({
int viewCount = 0,
bool isHot = false,
DateTime? createdAt,
String tag = '',
Map<String, String> tagLocales = const {},
}) {
return Drama(
id: id,
@@ -188,6 +181,8 @@ Drama _drama({
isHot: isHot,
dramaType: dramaType,
createdAt: createdAt,
tag: tag,
tagLocales: tagLocales,
);
}
@@ -210,7 +205,6 @@ Future<void> _pumpCard(
child: HomeFeedCard(
drama: drama,
onTap: onTap,
now: DateTime(2026, 10, 22, 12),
),
),
),
+14 -36
View File
@@ -45,24 +45,24 @@ void main() {
await _pumpApp(tester, repository);
final sectionKeys = [
const Key('home-section-featured'),
const Key('home-section-new'),
const Key('home-section-categories'),
const Key('home-section-ranking'),
const Key('home-section-category-古装'),
const Key('home-section-category-社群'),
const Key('home-section-category-爽剧'),
const Key('home-section-category-甜宠'),
const Key('home-section-category-打脸虐渣'),
const Key('home-section-category-虐恋'),
];
final sectionCenters = sectionKeys
.map((key) => tester.getCenter(find.byKey(key)).dx)
.toList();
expect(sectionCenters, orderedEquals(sectionCenters.toList()..sort()));
expect(find.byKey(const Key('home-secondary-tags')), findsNothing);
expect(find.text('Featured'), findsOneWidget);
expect(find.text('New'), findsOneWidget);
expect(find.text('Categories'), findsOneWidget);
expect(find.text('Charts'), findsOneWidget);
expect(find.text('Costume'), findsOneWidget);
expect(find.text('Community'), findsOneWidget);
expect(find.text('Featured'), findsNothing);
expect(find.text('New'), findsNothing);
expect(find.text('Categories'), findsNothing);
expect(find.text('Charts'), findsNothing);
expect(find.text('古装'), findsOneWidget);
expect(find.text('社群'), findsOneWidget);
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
expect(find.byType(FloatingActionButton), findsNothing);
});
@@ -94,31 +94,9 @@ void main() {
}
expect(find.byKey(const Key('home-grid')), findsOneWidget);
expect(find.byKey(const Key('home-section-featured')), findsNothing);
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')), findsNothing);
expect(find.byKey(const Key('home-secondary-tags')), findsNothing);
expect(firstDramaId(), 'page1-9');
await tester.tap(find.byKey(const Key('home-section-ranking')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('ranking-page')), findsOneWidget);
expect(find.byKey(const Key('ranking-hero')), findsOneWidget);
expect(find.byKey(const Key('home-grid-cards')), findsNothing);
final home = tester.widget<DecoratedBox>(find.byKey(const Key('home-grid')));
expect(
(home.decoration as BoxDecoration).gradient,
AppTheme.pageGradient,
);
await tester.tap(find.byKey(const Key('home-section-categories')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('filter-page')), findsNothing);
expect(find.byKey(const Key('home-secondary-tags')), 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');
@@ -149,9 +127,9 @@ void main() {
final before = tester.state<ScrollableState>(scrollable).position.pixels;
expect(before, greaterThan(0));
await tester.tap(find.byKey(const Key('home-section-new')));
await tester.tap(find.byKey(const Key('home-section-category-社群')));
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('home-section-featured')));
await tester.tap(find.byKey(const Key('home-section-category-古装')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('home-secondary-tags')), findsNothing);
@@ -180,7 +158,7 @@ void main() {
expect(find.byKey(const Key('home-secondary-tags')), findsNothing);
final selected = tester.widget<AnimatedDefaultTextStyle>(
find.byKey(const Key('home-primary-label-newReleases')),
find.byKey(const Key('home-primary-label-community')),
);
expect(selected.style.fontSize, AppDimens.homePrimaryTabSelectedFont);
expect(selected.style.fontWeight, FontWeight.w700);
+8 -11
View File
@@ -87,10 +87,7 @@ void main() {
expect(delegate.crossAxisCount, 3);
expect(delegate.crossAxisSpacing, AppDimens.homeGridGap);
expect(delegate.mainAxisSpacing, AppDimens.homeGridRowGap);
expect(find.byKey(const Key('home-section-featured')), findsOneWidget);
expect(find.byKey(const Key('home-section-new')), findsOneWidget);
expect(find.byKey(const Key('home-section-categories')), findsOneWidget);
expect(find.byKey(const Key('home-section-ranking')), findsOneWidget);
expect(find.byKey(const Key('home-section-featured')), findsNothing);
expect(find.byKey(const Key('home-section-category-古装')), findsOneWidget);
expect(find.byKey(const Key('home-section-category-社群')), findsOneWidget);
expect(find.byKey(const Key('home-secondary-tags')), findsNothing);
@@ -111,10 +108,10 @@ void main() {
expect(placeholder.style?.fontSize, AppDimens.searchPlaceholderFont);
expect(placeholder.style?.color, AppColors.textSecondary);
final selectedPrimary = tester.widget<AnimatedDefaultTextStyle>(
find.byKey(const Key('home-primary-label-featured')),
find.byKey(const Key('home-primary-label-costume')),
);
final unselectedPrimary = tester.widget<AnimatedDefaultTextStyle>(
find.byKey(const Key('home-primary-label-newReleases')),
find.byKey(const Key('home-primary-label-community')),
);
expect(
selectedPrimary.style.fontSize,
@@ -128,19 +125,19 @@ void main() {
expect(unselectedPrimary.style.color, AppColors.textTabInactive);
expect(
find.descendant(
of: find.byKey(const Key('home-section-featured')),
of: find.byKey(const Key('home-section-category-古装')),
matching: find.byType(Container),
),
findsNothing,
);
final primaryStart = tester.getTopLeft(find.text('Featured'));
final primaryStart = tester.getTopLeft(find.text('古装'));
final pageStart = tester.getTopLeft(searchBox);
expect(primaryStart.dx, pageStart.dx);
final primaryGap =
tester.getTopLeft(find.text('New')).dx -
tester.getBottomRight(find.text('Featured')).dx;
tester.getTopLeft(find.text('社群')).dx -
tester.getBottomRight(find.text('古装')).dx;
expect(primaryGap, closeTo(AppDimens.homePrimaryCategoryGap, 0.1));
expect(find.byType(PageView), findsNothing);
expect(find.byKey(const Key('home-primary-page-view')), findsOneWidget);
expect(tester.takeException(), isNull);
});
+1 -1
View File
@@ -108,7 +108,7 @@ void main() {
await tester.tap(find.byKey(const Key('recommend-tab-all')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('all-dramas-grid')), findsOneWidget);
for (var row = 0; row < 4; row++) {
for (var row = 0; row < 3; row++) {
expect(find.byKey(Key('all-filter-row-$row')), findsOneWidget);
}
_expectNoFloatingOverlays();