merge: 合并 K9 首页全部剧目网格

This commit is contained in:
Zhou Weidong committed 2026-10-17 17:24:58 +08:00
commit 2c381be5e8
11 files changed
+498 -230

No files matched your search

+1
View File
@@ -55,6 +55,7 @@
"animatedTab": "Animated",
"recommendedTab": "Recommended",
"noCategoryDramas": "No dramas in this category yet.",
"allDramas": "All Dramas",
"trendingTab": "Trending",
"liveActionTab": "Live Action",
"search": "Search",
+1
View File
@@ -55,6 +55,7 @@
"animatedTab": "Animasi",
"recommendedTab": "Rekomendasi",
"noCategoryDramas": "Belum ada drama di kategori ini.",
"allDramas": "Semua Drama",
"trendingTab": "Sedang Tren",
"liveActionTab": "Live Action",
"search": "Cari",
+6
View File
@@ -388,6 +388,12 @@ abstract class AppLocalizations {
/// **'No dramas in this category yet.'**
String get noCategoryDramas;
/// No description provided for @allDramas.
///
/// In en, this message translates to:
/// **'All Dramas'**
String get allDramas;
/// No description provided for @trendingTab.
///
/// In en, this message translates to:
+3
View File
@@ -157,6 +157,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get noCategoryDramas => 'No dramas in this category yet.';
@override
String get allDramas => 'All Dramas';
@override
String get trendingTab => 'Trending';
+3
View File
@@ -157,6 +157,9 @@ class AppLocalizationsId extends AppLocalizations {
@override
String get noCategoryDramas => 'Belum ada drama di kategori ini.';
@override
String get allDramas => 'Semua Drama';
@override
String get trendingTab => 'Sedang Tren';
+3
View File
@@ -154,6 +154,9 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get noCategoryDramas => '这个分类暂时没有剧集。';
@override
String get allDramas => '全部剧目';
@override
String get trendingTab => '热门';
+1
View File
@@ -55,6 +55,7 @@
"animatedTab": "漫剧",
"recommendedTab": "推荐",
"noCategoryDramas": "这个分类暂时没有剧集。",
"allDramas": "全部剧目",
"trendingTab": "热门",
"liveActionTab": "真人剧",
"search": "搜索",
+57 -219
View File
@@ -17,6 +17,8 @@ import 'discover_binding.dart';
import 'discover_logic.dart';
import 'widgets/cover_carousel.dart';
part 'widgets/home_drama_grid.dart';
class DiscoverPage extends StatefulWidget {
const DiscoverPage({
super.key,
@@ -101,40 +103,12 @@ class _DiscoverPageState extends State<DiscoverPage> {
final categories = context.watch<CategoryController>();
final homeBanners = context.watch<CatalogController>().feed.banners;
final allDramas = [...?widget.dramas, ...categories.visibleDramas];
final cards = _cardsFor(categories.visibleDramas, '');
final content = SafeArea(
bottom: !widget.embedded,
child: Column(
children: [
_header(l10n),
Expanded(
child: ListView(
controller: logic.scroll,
padding: const EdgeInsets.only(bottom: 24),
children: [
Padding(
padding: const EdgeInsets.fromLTRB(16, 4, 16, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(18),
child: _carousel(l10n, homeBanners, allDramas),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(16, 18, 16, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_categories(l10n, categories),
const SizedBox(height: 18),
_continueHeader(l10n),
const SizedBox(height: 12),
_dramaContent(l10n, categories, cards),
],
),
),
],
),
),
Expanded(child: _feed(l10n, categories, homeBanners, allDramas)),
if (!widget.embedded) _bottomNav(l10n),
],
),
@@ -150,6 +124,60 @@ class _DiscoverPageState extends State<DiscoverPage> {
);
}
Widget _feed(
AppLocalizations l10n,
CategoryController categories,
List<FeedBanner> banners,
List<Drama> allDramas,
) => CustomScrollView(
controller: logic.scroll,
slivers: [
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 4, 16, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(18),
child: _carousel(l10n, banners, allDramas),
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 18, 16, 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_categories(l10n, categories),
const SizedBox(height: 18),
Text(
l10n.allDramas,
key: const Key('home-all-dramas-title'),
style: const TextStyle(
color: AppColors.onPrimary,
fontSize: 18,
fontWeight: FontWeight.w700,
height: 1.2,
),
),
],
),
),
),
_HomeDramaGrid(
l10n: l10n,
categories: categories,
onOpen: (drama) => logic.openCard(
context,
drama,
embedded: widget.embedded,
onDramaSelected: widget.onDramaSelected,
onAction: widget.onAction,
),
),
const SliverToBoxAdapter(child: SizedBox(height: 24)),
],
);
Widget _header(AppLocalizations l10n) {
return Padding(
padding: const EdgeInsets.fromLTRB(16, 6, 12, 8),
@@ -239,164 +267,6 @@ class _DiscoverPageState extends State<DiscoverPage> {
}
}
Widget _continueHeader(AppLocalizations l10n) => Row(
children: [
Expanded(
child: Text(
l10n.continueWatching,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
letterSpacing: 0.2,
height: 1.2,
),
),
),
const SizedBox(width: 8),
Text(
l10n.seeAll,
style: const TextStyle(
color: AppColors.blueSoft,
fontSize: 13,
fontWeight: FontWeight.w500,
),
),
],
);
Widget _dramaContent(
AppLocalizations l10n,
CategoryController categories,
List<_ShowcaseCard> cards,
) {
if (categories.loading && categories.feed.sections.isEmpty) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 24),
child: Center(child: CircularProgressIndicator(strokeWidth: 2)),
);
}
if (categories.error != null) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 18),
child: Row(
children: [
Expanded(
child: Text(
l10n.categoriesError,
style: const TextStyle(color: Color(0xFFE6E1E3)),
),
),
TextButton(onPressed: categories.load, child: Text(l10n.retry)),
],
),
);
}
if (cards.isEmpty) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 24),
child: Text(
categories.selectedSectionMissing
? l10n.noCategoryDramas
: l10n.noSearchResults,
style: const TextStyle(color: Color(0xFFE6E1E3)),
),
);
}
return SizedBox(
height: 196,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
for (final card in cards) ...[
_continueTile(l10n, card, categories.visibleDramas),
const SizedBox(width: 12),
],
],
),
);
}
Widget _continueTile(
AppLocalizations l10n,
_ShowcaseCard card,
List<Drama> source,
) {
final drama = logic.dramaFor(card.dramaId, source);
return SizedBox(
width: 132,
child: InkWell(
onTap: () => logic.openCard(
context,
drama,
embedded: widget.embedded,
onDramaSelected: widget.onDramaSelected,
onAction: widget.onAction,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(14),
child: Stack(
fit: StackFit.expand,
children: [
RemoteImage(card.image),
const DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0x00000000), Color(0xE6000000)],
stops: [0.45, 1],
),
),
),
if (drama == null)
const ColoredBox(
color: Color(0x99000000),
child: Center(
child: Icon(Icons.image_outlined, color: Colors.white),
),
),
Positioned(
left: 10,
right: 10,
bottom: 10,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
card.title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
fontSize: 13,
fontWeight: FontWeight.w600,
height: 1.2,
),
),
const SizedBox(height: 3),
Text(
drama == null ? l10n.videoPending : card.genre,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Color(0xE6FFFFFF),
fontSize: 11,
fontWeight: FontWeight.w400,
height: 1.2,
),
),
],
),
),
],
),
),
),
);
}
Widget _categories(AppLocalizations l10n, CategoryController categories) {
final choices = <({String code, String label})>[
(code: CategoryController.allCode, label: l10n.forYou),
@@ -523,38 +393,6 @@ class _DiscoverNavItem extends StatelessWidget {
);
}
class _ShowcaseCard {
const _ShowcaseCard({
required this.title,
required this.genre,
required this.image,
this.dramaId,
});
final String title;
final String genre;
final String image;
final String? dramaId;
}
/// 分区由服务端下发:0 为全部,其余按分区顺序对应筛选菜单(热门 / 最新 / 各分类)。
List<_ShowcaseCard> _cardsFor(List<Drama> dramas, String query) {
final normalized = query.trim().toLowerCase();
return [
for (final drama in dramas)
if (normalized.isEmpty ||
drama.title.toLowerCase().contains(normalized) ||
drama.genre.toLowerCase().contains(normalized) ||
drama.category.toLowerCase().contains(normalized))
_ShowcaseCard(
title: drama.title,
genre: drama.genre.isEmpty ? drama.category : drama.genre,
image: drama.posterUrl,
dramaId: drama.id,
),
];
}
const _accent = AppColors.blueSoft;
const _coin = Color(0xFFF5C451);
@@ -0,0 +1,167 @@
// Author: fruit.com.cn
part of '../discover_view.dart';
class _HomeDramaGrid extends StatelessWidget {
const _HomeDramaGrid({
required this.l10n,
required this.categories,
required this.onOpen,
});
final AppLocalizations l10n;
final CategoryController categories;
final ValueChanged<Drama> onOpen;
@override
Widget build(BuildContext context) {
if (categories.loading && categories.feed.sections.isEmpty) {
return const SliverPadding(
padding: EdgeInsets.symmetric(vertical: 24),
sliver: SliverToBoxAdapter(
child: Center(child: CircularProgressIndicator(strokeWidth: 2)),
),
);
}
if (categories.error != null) {
return SliverPadding(
padding: const EdgeInsets.fromLTRB(16, 6, 16, 18),
sliver: SliverToBoxAdapter(
child: Row(
children: [
Expanded(
child: Text(
l10n.categoriesError,
style: const TextStyle(color: AppColors.muted),
),
),
TextButton(onPressed: categories.load, child: Text(l10n.retry)),
],
),
),
);
}
final dramas = categories.visibleDramas;
if (dramas.isEmpty) {
return SliverPadding(
padding: const EdgeInsets.fromLTRB(16, 6, 16, 24),
sliver: SliverToBoxAdapter(
child: Text(
categories.selectedSectionMissing
? l10n.noCategoryDramas
: l10n.noSearchResults,
style: const TextStyle(color: AppColors.muted),
),
),
);
}
return SliverPadding(
key: const Key('home-all-dramas-section'),
padding: const EdgeInsets.symmetric(horizontal: 16),
sliver: SliverGrid(
key: const Key('home-all-dramas-grid'),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 16,
crossAxisSpacing: 12,
childAspectRatio: 2 / 3,
),
delegate: SliverChildBuilderDelegate(
(context, index) => _HomeDramaCard(
l10n: l10n,
drama: dramas[index],
onTap: () => onOpen(dramas[index]),
),
childCount: dramas.length,
),
),
);
}
}
class _HomeDramaCard extends StatelessWidget {
const _HomeDramaCard({
required this.l10n,
required this.drama,
required this.onTap,
});
final AppLocalizations l10n;
final Drama drama;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
final genre = drama.genre.isEmpty ? drama.category : drama.genre;
return InkWell(
key: Key('home-drama-card-${drama.id}'),
onTap: onTap,
borderRadius: BorderRadius.circular(14),
child: AspectRatio(
key: Key('home-drama-cover-${drama.id}'),
aspectRatio: 2 / 3,
child: ClipRRect(
borderRadius: BorderRadius.circular(14),
child: Stack(
fit: StackFit.expand,
children: [
RemoteImage(
drama.posterUrl,
fit: BoxFit.cover,
showFallbackIcon: true,
),
const DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0x00000000), Color(0xE6000000)],
stops: [0.4, 1],
),
),
),
Positioned(
left: 10,
right: 10,
bottom: 10,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
drama.title,
key: Key('home-drama-title-${drama.id}'),
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w700,
height: 1.2,
),
),
const SizedBox(height: 4),
Text(
genre.isEmpty ? l10n.videoPending : genre,
key: Key('home-drama-genre-${drama.id}'),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Color(0xE6FFFFFF),
fontSize: 11,
fontWeight: FontWeight.w400,
height: 1.2,
),
),
],
),
),
],
),
),
),
);
}
}
@@ -0,0 +1,245 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.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';
import 'package:fruitshorts/app.dart';
import 'package:fruitshorts/core/data/models/content_category.dart';
import 'package:fruitshorts/core/data/models/drama.dart';
import 'package:fruitshorts/core/data/models/home_feed.dart';
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';
import '../support/fake_notice_repository.dart';
import '../support/widget_player.dart';
void main() {
setUp(() {
SharedPreferencesAsyncPlatform.instance =
InMemorySharedPreferencesAsync.empty();
});
testWidgets(
'should_show_all_dramas_in_two_column_sliver_grid_without_continue_watching',
(tester) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await _pumpApp(tester, categoryRepository: _GridCategoryRepository());
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
expect(find.text('Continue Watching'), findsNothing);
expect(find.text('All Dramas'), findsOneWidget);
final grid = tester.widget<SliverGrid>(
find.byKey(const Key('home-all-dramas-grid')),
);
final delegate =
grid.gridDelegate as SliverGridDelegateWithFixedCrossAxisCount;
expect(delegate.crossAxisCount, 2);
expect(delegate.crossAxisSpacing, 12);
expect(delegate.mainAxisSpacing, 16);
expect(delegate.childAspectRatio, closeTo(2 / 3, 0.001));
expect(
tester
.widget<SliverPadding>(
find.byKey(const Key('home-all-dramas-section')),
)
.padding,
const EdgeInsets.symmetric(horizontal: 16),
);
expect(find.byType(GridView), findsNothing);
expect(find.byType(CustomScrollView), findsOneWidget);
expect(find.byType(RemoteImage), findsWidgets);
final cover = tester.widget<AspectRatio>(
find.byKey(const Key('home-drama-cover-city-lights-demo')),
);
expect(cover.aspectRatio, closeTo(2 / 3, 0.001));
expect(
tester
.widget<Text>(
find.byKey(const Key('home-drama-title-city-lights-demo')),
)
.maxLines,
2,
);
expect(
tester
.widget<Text>(
find.byKey(const Key('home-drama-genre-city-lights-demo')),
)
.maxLines,
1,
);
expect(tester.takeException(), isNull);
},
);
testWidgets('should_update_grid_when_category_is_selected', (tester) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await _pumpApp(tester, categoryRepository: _GridCategoryRepository());
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
expect(find.text('The Signal'), findsOneWidget);
expect(find.text('City Lights & Velvet Nights'), findsOneWidget);
await tester.tap(find.text('Romance'));
await tester.pumpAndSettle();
expect(find.text('The Signal'), findsNothing);
expect(find.text('City Lights & Velvet Nights'), findsOneWidget);
expect(
find.byKey(const Key('home-drama-card-the-signal-demo')),
findsNothing,
);
expect(
find.byKey(const Key('home-drama-card-city-lights-demo')),
findsOneWidget,
);
});
testWidgets('should_keep_empty_messages_when_feed_has_no_dramas', (
tester,
) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await _pumpApp(
tester,
categoryRepository: _GridCategoryRepository(
discoverFeed: const HomeFeed(),
),
);
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
expect(find.text('All Dramas'), findsOneWidget);
expect(find.text('No matching dramas.'), findsOneWidget);
await tester.tap(find.text('Romance'));
await tester.pumpAndSettle();
expect(find.text('No dramas in this category yet.'), findsOneWidget);
});
testWidgets('should_show_retry_when_category_feed_fails', (tester) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await _pumpApp(tester, categoryRepository: _FailingCategoryRepository());
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
expect(find.text('All Dramas'), findsOneWidget);
expect(find.text('Categories could not be loaded.'), findsOneWidget);
expect(find.text('Retry'), findsOneWidget);
expect(find.byKey(const Key('home-all-dramas-grid')), findsNothing);
});
testWidgets('should_fit_two_column_grid_on_compact_screen', (tester) async {
tester.view.physicalSize = const Size(320, 568);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await _pumpApp(tester, categoryRepository: _GridCategoryRepository());
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
await tester.scrollUntilVisible(
find.byKey(const Key('home-drama-card-city-lights-demo')),
180,
scrollable: find.byType(Scrollable).last,
);
await tester.pumpAndSettle();
expect(find.text('All Dramas'), findsOneWidget);
expect(find.text('City Lights & Velvet Nights'), findsOneWidget);
expect(tester.takeException(), isNull);
});
}
Future<void> _pumpApp(
WidgetTester tester, {
required CategoryRepository categoryRepository,
}) async {
final catalog = FakeCatalogRepository();
await tester.pumpWidget(
LumaDramaApp(
playerFactory: createWidgetPlayer,
catalogRepository: catalog,
categoryRepository: categoryRepository,
watchHistoryRepository: InMemoryWatchHistoryRepository(),
favoriteRepository: InMemoryFavoriteRepository(),
playbackRepository: FakePlaybackRepository(),
commentRepository: FakeCommentRepository(),
interactionRepository: FakeInteractionRepository(),
noticeRepository: FakeNoticeRepository(),
),
);
await tester.pumpAndSettle();
}
class _GridCategoryRepository implements CategoryRepository {
_GridCategoryRepository({HomeFeed? discoverFeed})
: discoverFeed = discoverFeed ?? _defaultDiscoverFeed;
final HomeFeed discoverFeed;
@override
Future<List<ContentCategory>> fetchCategories() async => const [
ContentCategory(id: '7', name: 'Romance'),
];
@override
Future<HomeFeed> fetchDiscoverFeed() async => discoverFeed;
}
class _FailingCategoryRepository implements CategoryRepository {
@override
Future<List<ContentCategory>> fetchCategories() async => const [
ContentCategory(id: '7', name: 'Romance'),
];
@override
Future<HomeFeed> fetchDiscoverFeed() async {
throw StateError('discover feed unavailable');
}
}
final _defaultDiscoverFeed = HomeFeed(
sections: [
FeedSection(code: 'hot', title: 'Hot', dramas: demoDramas),
FeedSection(
code: 'category-7',
title: 'Romance',
dramas: [
Drama(
id: 'city-lights-demo',
title: 'City Lights & Velvet Nights',
synopsis: 'City Lights & Velvet Nights synopsis',
posterUrl: '/files/city-lights-demo.png',
genre: 'Urban Romance',
detailLoaded: true,
),
],
),
],
);
+11 -11
View File
@@ -155,7 +155,7 @@ void main() {
await tester.pumpWidget(appUnderTest());
await tester.pumpAndSettle();
expect(find.text('Continue Watching'), findsOneWidget);
expect(find.text('All Dramas'), findsOneWidget);
await tester.binding.handlePopRoute();
await tester.pumpAndSettle();
expect(
@@ -186,15 +186,15 @@ void main() {
.active,
isFalse,
);
expect(find.text('Continue Watching'), findsOneWidget);
expect(find.text('All Dramas'), findsOneWidget);
await tester.binding.handlePopRoute();
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('drawer-discover')));
await tester.pumpAndSettle();
expect(find.text('Continue Watching'), findsOneWidget);
expect(find.text('All Dramas'), findsOneWidget);
expect(
Navigator.of(tester.element(find.text('Continue Watching'))).canPop(),
Navigator.of(tester.element(find.text('All Dramas'))).canPop(),
isFalse,
);
},
@@ -313,7 +313,7 @@ void main() {
await tester.pumpAndSettle();
expect(find.text('For You'), findsOneWidget);
expect(find.text('Continue Watching'), findsOneWidget);
expect(find.text('All Dramas'), findsOneWidget);
expect(find.text('Rewards'), findsOneWidget);
expect(find.text(r'$ 0'), findsOneWidget);
expect(find.text('Urban Romance', skipOffstage: false), findsOneWidget);
@@ -345,10 +345,10 @@ void main() {
await tester.pumpAndSettle();
await tester.tap(find.text('Home'));
await tester.pumpAndSettle();
expect(find.text('Continue Watching'), findsOneWidget);
expect(find.text('All Dramas'), findsOneWidget);
expect(find.byTooltip('Search'), findsNothing);
expect(
Navigator.of(tester.element(find.text('Continue Watching'))).canPop(),
Navigator.of(tester.element(find.text('All Dramas'))).canPop(),
isFalse,
);
@@ -365,10 +365,10 @@ void main() {
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
expect(find.text('Continue Watching'), findsOneWidget);
expect(find.text('All Dramas'), findsOneWidget);
expect(find.byTooltip('Search'), findsNothing);
expect(
Navigator.of(tester.element(find.text('Continue Watching'))).canPop(),
Navigator.of(tester.element(find.text('All Dramas'))).canPop(),
isFalse,
);
await tester.tap(find.byKey(const Key('tab-my-list')));
@@ -564,7 +564,7 @@ void main() {
await tester.pumpWidget(appUnderTest());
await tester.pumpAndSettle();
expect(find.text('Continue Watching'), findsOneWidget);
expect(find.text('All Dramas'), findsOneWidget);
await tester.binding.handlePopRoute();
await tester.pumpAndSettle();
expect(find.text('Quick access'), findsOneWidget);
@@ -572,7 +572,7 @@ void main() {
await tester.binding.handlePopRoute();
await tester.pumpAndSettle();
expect(find.text('Quick access'), findsNothing);
expect(find.text('Continue Watching'), findsOneWidget);
expect(find.text('All Dramas'), findsOneWidget);
expect(
Navigator.of(
tester.element(find.byKey(const Key('home-tabs-bar'))),