feat(flutter): 按参考图重做首页 feed 浮层

This commit is contained in:
Zhou Weidong committed 2026-10-20 13:46:20 +08:00
1 parent d6b055dc62
commit ee6f0d7e72
14 files changed
+1062 -398

No files matched your search

+46 -76
View File
@@ -60,75 +60,29 @@ void main() {
await tester.pumpAndSettle();
expect(find.byKey(const Key('home-feed-title')), findsOneWidget);
expect(find.byKey(const Key('home-feed-info-card')), findsOneWidget);
expect(find.byKey(const Key('home-feed-full-series')), findsOneWidget);
expect(find.byType(PageView), findsOneWidget);
expect(find.byKey(const Key('home-browse-page')), findsNothing);
expect(tester.takeException(), isNull);
});
testWidgets('should_use_episode_title_then_drama_title_as_fallback', (
testWidgets('should_render_new_feed_structure_with_formatted_counts', (
tester,
) async {
Future<void> pumpEpisode(Episode episode) async {
await tester.pumpWidget(
MaterialApp(
theme: AppTheme.light(),
locale: const Locale('en'),
supportedLocales: AppLocalizations.supportedLocales,
localizationsDelegates: AppLocalizations.localizationsDelegates,
home: Builder(
builder: (context) => Scaffold(
body: HomeFeedOverlay(
l10n: AppLocalizations.of(context)!,
drama: _drama,
episode: episode,
liked: false,
saved: false,
onLike: () {},
onSave: () {},
onComments: () {},
onShare: () {},
onEpisodes: () {},
onDownload: () {},
onClear: () {},
onSearch: () {},
),
),
),
),
);
await tester.pumpAndSettle();
}
await pumpEpisode(
const Episode(
id: 'featured',
number: 2,
title: 'Midnight Contract',
isFree: true,
),
const drama = Drama(
id: 'feed-drama',
title: 'Feed Drama',
synopsis: 'synopsis',
posterUrl: '',
genre: 'Romance',
category: 'Urban',
totalEpisodes: 8,
freeEpisodes: 8,
viewCount: 419000,
likeCount: 1006,
favoriteCount: 32000,
commentCount: 12,
);
expect(
tester
.widget<Text>(find.byKey(const Key('home-feed-episode-title')))
.data,
'Midnight Contract',
);
await pumpEpisode(
const Episode(id: 'fallback', number: 2, title: '', isFree: true),
);
expect(
tester
.widget<Text>(find.byKey(const Key('home-feed-episode-title')))
.data,
'Fallback Drama',
);
});
testWidgets('should_show_server_like_count_when_count_is_available', (
tester,
) async {
await tester.pumpWidget(
MaterialApp(
theme: AppTheme.light(),
@@ -139,21 +93,26 @@ void main() {
builder: (context) => Scaffold(
body: HomeFeedOverlay(
l10n: AppLocalizations.of(context)!,
drama: _drama,
drama: drama,
episode: const Episode(
id: 'count-episode',
number: 1,
title: 'Count Episode',
id: 'feed-episode',
number: 2,
title: 'Ignored Episode Title',
isFree: true,
),
controller: null,
liked: true,
likeCount: 128,
saved: false,
likeCount: 1006,
favoriteCount: 32000,
commentCount: 12,
onLike: () {},
onSave: () {},
onComments: () {},
onShare: () {},
onEpisodes: () {},
onDetail: () {},
onFullscreen: () {},
onDownload: () {},
onClear: () {},
onSearch: () {},
@@ -164,15 +123,26 @@ void main() {
);
await tester.pumpAndSettle();
expect(find.byKey(const Key('rail-like-count')), findsOneWidget);
expect(find.text('128'), findsOneWidget);
expect(
tester.widget<Text>(find.byKey(const Key('home-feed-title'))).data,
'Feed Drama',
);
expect(find.byKey(const Key('home-feed-info-card')), findsNothing);
expect(find.byKey(const Key('home-feed-full-series')), findsOneWidget);
expect(find.byKey(const Key('home-feed-tags')), findsOneWidget);
expect(find.text('Episode 2'), findsOneWidget);
expect(find.textContaining('41.9万'), findsOneWidget);
expect(
tester.widget<Text>(find.byKey(const Key('rail-like-count'))).data,
'1006',
);
expect(
tester.widget<Text>(find.byKey(const Key('rail-save-count'))).data,
'3.2万',
);
expect(
tester.widget<Text>(find.byKey(const Key('rail-comments-count'))).data,
'12',
);
});
}
const _drama = Drama(
id: 'featured-drama',
title: 'Fallback Drama',
synopsis: 'synopsis',
posterUrl: '',
totalEpisodes: 8,
);
+36 -1
View File
@@ -50,12 +50,47 @@ void main() {
await _pumpApp(tester);
expect(find.byKey(const Key('home-feed-title')), findsOneWidget);
expect(find.byKey(const Key('home-feed-info-card')), findsOneWidget);
expect(find.byKey(const Key('home-feed-full-series')), findsOneWidget);
expect(find.byType(PageView), findsOneWidget);
expect(find.byKey(const Key('home-browse-page')), findsNothing);
expect(
tester.widget<Text>(find.byKey(const Key('rail-like-count'))).data,
'41.9万',
);
expect(
tester.widget<Text>(find.byKey(const Key('rail-save-count'))).data,
'1006',
);
expect(
tester.widget<Text>(find.byKey(const Key('rail-comments-count'))).data,
'3.2万',
);
expect(tester.widget<PlayerPage>(find.byType(PlayerPage)).homeMode, isTrue);
});
testWidgets('should_open_episode_sheet_from_full_series_bar', (tester) async {
await _pumpApp(tester);
await tester.tap(find.byKey(const Key('home-feed-full-series')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('player-episodes-sheet')), findsOneWidget);
});
testWidgets('should_show_coming_soon_for_danmaku_and_following_tab', (
tester,
) async {
await _pumpApp(tester);
await tester.tap(find.byKey(const Key('home-feed-danmaku')));
await tester.pump();
expect(find.text('Coming soon'), findsOneWidget);
await tester.tap(find.byKey(const Key('home-feed-tab-follow')));
await tester.pump();
expect(find.text('Coming soon'), findsOneWidget);
});
testWidgets('should_switch_feed_drama_when_swiped_up', (tester) async {
await _pumpApp(tester);
final before = tester
+12 -1
View File
@@ -44,7 +44,16 @@ class FakeCatalogRepository implements CatalogRepository, SearchRepository {
}
final List<Drama> demoDramas = [
_drama('the-signal-demo', 'The Signal', 'Suspense · Mystery', format: 1),
_drama(
'the-signal-demo',
'The Signal',
'Suspense · Mystery',
format: 1,
viewCount: 419000,
likeCount: 419000,
favoriteCount: 1006,
commentCount: 32000,
),
_drama(
'city-lights-demo',
'City Lights & Velvet Nights',
@@ -65,6 +74,7 @@ Drama _drama(
int? likeCount,
int? favoriteCount,
int? commentCount,
int viewCount = 0,
}) => Drama(
id: id,
title: title,
@@ -73,6 +83,7 @@ Drama _drama(
genre: genre,
language: 'id',
detailLoaded: true,
viewCount: viewCount,
likeCount: likeCount,
favoriteCount: favoriteCount,
commentCount: commentCount,