fix(flutter): 去除关注 tab 并加深色首页导航
This commit is contained in:
1 parent
ee6f0d7e72
commit
d36d62f6a6
12 files changed
+48
-39
No files matched your search
@@ -26,18 +26,20 @@ class AppBottomNavItem {
|
|||||||
final bool selected;
|
final bool selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 四槽底部导航,仅做浅色暖橙视觉换肤。
|
/// 四槽底部导航:首页 feed 用深色样式,其它页面保持浅色暖橙风格。
|
||||||
class AppBottomNav extends StatelessWidget {
|
class AppBottomNav extends StatelessWidget {
|
||||||
const AppBottomNav({
|
const AppBottomNav({
|
||||||
super.key,
|
super.key,
|
||||||
required this.items,
|
required this.items,
|
||||||
this.backgroundColor = AppColors.bar,
|
this.backgroundColor = AppColors.bar,
|
||||||
this.barKey,
|
this.barKey,
|
||||||
|
this.dark = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
final List<AppBottomNavItem> items;
|
final List<AppBottomNavItem> items;
|
||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
final Key? barKey;
|
final Key? barKey;
|
||||||
|
final bool dark;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -50,11 +52,25 @@ class AppBottomNav extends StatelessWidget {
|
|||||||
key: barKey,
|
key: barKey,
|
||||||
height: AppDimens.navHeight,
|
height: AppDimens.navHeight,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: backgroundColor.withValues(alpha: 0.95),
|
color: dark
|
||||||
border: const Border(top: BorderSide(color: AppColors.border)),
|
? const Color(0xE6000000)
|
||||||
|
: backgroundColor.withValues(alpha: 0.95),
|
||||||
|
border: Border(
|
||||||
|
top: BorderSide(
|
||||||
|
color: dark ? Colors.white12 : AppColors.border,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [for (final item in items) _NavDestination(item: item)],
|
children: [
|
||||||
|
for (final item in items)
|
||||||
|
_NavDestination(
|
||||||
|
item: item,
|
||||||
|
unselectedColor: dark
|
||||||
|
? Colors.white70
|
||||||
|
: AppColors.navUnselected,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -64,9 +80,10 @@ class AppBottomNav extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _NavDestination extends StatelessWidget {
|
class _NavDestination extends StatelessWidget {
|
||||||
const _NavDestination({required this.item});
|
const _NavDestination({required this.item, required this.unselectedColor});
|
||||||
|
|
||||||
final AppBottomNavItem item;
|
final AppBottomNavItem item;
|
||||||
|
final Color unselectedColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Expanded(
|
Widget build(BuildContext context) => Expanded(
|
||||||
@@ -89,9 +106,7 @@ class _NavDestination extends StatelessWidget {
|
|||||||
child: Icon(
|
child: Icon(
|
||||||
item.selected ? item.selectedIcon : item.icon,
|
item.selected ? item.selectedIcon : item.icon,
|
||||||
size: AppDimens.navIcon,
|
size: AppDimens.navIcon,
|
||||||
color: item.selected
|
color: item.selected ? AppColors.blue : unselectedColor,
|
||||||
? AppColors.blue
|
|
||||||
: AppColors.navUnselected,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
@@ -102,9 +117,7 @@ class _NavDestination extends StatelessWidget {
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: AppDimens.navLabel,
|
fontSize: AppDimens.navLabel,
|
||||||
fontWeight: item.selected ? FontWeight.w700 : FontWeight.w500,
|
fontWeight: item.selected ? FontWeight.w700 : FontWeight.w500,
|
||||||
color: item.selected
|
color: item.selected ? AppColors.blue : unselectedColor,
|
||||||
? AppColors.blue
|
|
||||||
: AppColors.navUnselected,
|
|
||||||
letterSpacing: 0,
|
letterSpacing: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -44,7 +44,6 @@
|
|||||||
"episodes": {"type": "String"}
|
"episodes": {"type": "String"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"feedTabFollowing": "Following",
|
|
||||||
"feedTabAnime": "Anime",
|
"feedTabAnime": "Anime",
|
||||||
"feedTabReal": "Live-action",
|
"feedTabReal": "Live-action",
|
||||||
"feedTabForYou": "For you",
|
"feedTabForYou": "For you",
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
"watchFullscreen": "Layar penuh",
|
"watchFullscreen": "Layar penuh",
|
||||||
"seriesMeta": "Serial · {episodes} eps | {viewers} menonton",
|
"seriesMeta": "Serial · {episodes} eps | {viewers} menonton",
|
||||||
"watchFullSeries": "Tonton serial lengkap · {episodes} eps",
|
"watchFullSeries": "Tonton serial lengkap · {episodes} eps",
|
||||||
"feedTabFollowing": "Mengikuti",
|
|
||||||
"feedTabAnime": "Anime",
|
"feedTabAnime": "Anime",
|
||||||
"feedTabReal": "Live-action",
|
"feedTabReal": "Live-action",
|
||||||
"feedTabForYou": "Untukmu",
|
"feedTabForYou": "Untukmu",
|
||||||
|
|||||||
@@ -298,12 +298,6 @@ abstract class AppLocalizations {
|
|||||||
/// **'Watch full series · {episodes} eps'**
|
/// **'Watch full series · {episodes} eps'**
|
||||||
String watchFullSeries(String episodes);
|
String watchFullSeries(String episodes);
|
||||||
|
|
||||||
/// No description provided for @feedTabFollowing.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Following'**
|
|
||||||
String get feedTabFollowing;
|
|
||||||
|
|
||||||
/// No description provided for @feedTabAnime.
|
/// No description provided for @feedTabAnime.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|||||||
@@ -114,9 +114,6 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
return 'Watch full series · $episodes eps';
|
return 'Watch full series · $episodes eps';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
String get feedTabFollowing => 'Following';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get feedTabAnime => 'Anime';
|
String get feedTabAnime => 'Anime';
|
||||||
|
|
||||||
|
|||||||
@@ -114,9 +114,6 @@ class AppLocalizationsId extends AppLocalizations {
|
|||||||
return 'Tonton serial lengkap · $episodes eps';
|
return 'Tonton serial lengkap · $episodes eps';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
String get feedTabFollowing => 'Mengikuti';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get feedTabAnime => 'Anime';
|
String get feedTabAnime => 'Anime';
|
||||||
|
|
||||||
|
|||||||
@@ -111,9 +111,6 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||||||
return '观看完整剧集 · 全$episodes集';
|
return '观看完整剧集 · 全$episodes集';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
String get feedTabFollowing => '关注';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get feedTabAnime => '漫剧';
|
String get feedTabAnime => '漫剧';
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
"watchFullscreen": "全屏观看",
|
"watchFullscreen": "全屏观看",
|
||||||
"seriesMeta": "系列剧 · 共{episodes}集 | 共{viewers}人在追",
|
"seriesMeta": "系列剧 · 共{episodes}集 | 共{viewers}人在追",
|
||||||
"watchFullSeries": "观看完整剧集 · 全{episodes}集",
|
"watchFullSeries": "观看完整剧集 · 全{episodes}集",
|
||||||
"feedTabFollowing": "关注",
|
|
||||||
"feedTabAnime": "漫剧",
|
"feedTabAnime": "漫剧",
|
||||||
"feedTabReal": "真人剧",
|
"feedTabReal": "真人剧",
|
||||||
"feedTabForYou": "推荐",
|
"feedTabForYou": "推荐",
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ class _HomeTabsState extends State<_HomeTabs> {
|
|||||||
Widget _nav(BuildContext context, AppLocalizations l10n) {
|
Widget _nav(BuildContext context, AppLocalizations l10n) {
|
||||||
return AppBottomNav(
|
return AppBottomNav(
|
||||||
barKey: const Key('home-tabs-bar'),
|
barKey: const Key('home-tabs-bar'),
|
||||||
|
dark: logic.tab == 0,
|
||||||
items: [
|
items: [
|
||||||
_navItem(context, l10n, 0),
|
_navItem(context, l10n, 0),
|
||||||
_navItem(context, l10n, 1),
|
_navItem(context, l10n, 1),
|
||||||
|
|||||||
@@ -2,24 +2,21 @@
|
|||||||
|
|
||||||
part of 'home_feed_overlay.dart';
|
part of 'home_feed_overlay.dart';
|
||||||
|
|
||||||
/// 顶部频道 tab:关注/漫剧点击提示即将上线。
|
/// 顶部频道 tab:漫剧点击提示即将上线。
|
||||||
enum _FeedTab {
|
enum _FeedTab {
|
||||||
following,
|
|
||||||
anime,
|
anime,
|
||||||
real,
|
real,
|
||||||
recommend;
|
recommend;
|
||||||
|
|
||||||
bool get comingSoon => this == _FeedTab.following || this == _FeedTab.anime;
|
bool get comingSoon => this == _FeedTab.anime;
|
||||||
|
|
||||||
String get keyName => switch (this) {
|
String get keyName => switch (this) {
|
||||||
_FeedTab.following => 'follow',
|
|
||||||
_FeedTab.anime => 'anime',
|
_FeedTab.anime => 'anime',
|
||||||
_FeedTab.real => 'real',
|
_FeedTab.real => 'real',
|
||||||
_FeedTab.recommend => 'recommend',
|
_FeedTab.recommend => 'recommend',
|
||||||
};
|
};
|
||||||
|
|
||||||
String label(AppLocalizations l10n) => switch (this) {
|
String label(AppLocalizations l10n) => switch (this) {
|
||||||
_FeedTab.following => l10n.feedTabFollowing,
|
|
||||||
_FeedTab.anime => l10n.feedTabAnime,
|
_FeedTab.anime => l10n.feedTabAnime,
|
||||||
_FeedTab.real => l10n.feedTabReal,
|
_FeedTab.real => l10n.feedTabReal,
|
||||||
_FeedTab.recommend => l10n.feedTabForYou,
|
_FeedTab.recommend => l10n.feedTabForYou,
|
||||||
|
|||||||
@@ -52,9 +52,21 @@ void main() {
|
|||||||
final bar = tester.widget<Container>(barFinder);
|
final bar = tester.widget<Container>(barFinder);
|
||||||
final decoration = bar.decoration as BoxDecoration;
|
final decoration = bar.decoration as BoxDecoration;
|
||||||
final border = decoration.border as Border;
|
final border = decoration.border as Border;
|
||||||
expect(decoration.color, AppColors.bar.withValues(alpha: 0.95));
|
// 首页 feed 用深色导航。
|
||||||
expect(border.top.color, AppColors.border);
|
expect(decoration.color, const Color(0xE6000000));
|
||||||
expect(border.top.color, isNot(Colors.white));
|
expect(border.top.color, Colors.white12);
|
||||||
|
expect(
|
||||||
|
tester
|
||||||
|
.widget<Text>(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('tab-theater')),
|
||||||
|
matching: find.text('Theater'),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.style
|
||||||
|
?.color,
|
||||||
|
Colors.white70,
|
||||||
|
);
|
||||||
expect(
|
expect(
|
||||||
tester
|
tester
|
||||||
.widget<AnimatedScale>(
|
.widget<AnimatedScale>(
|
||||||
@@ -88,6 +100,10 @@ void main() {
|
|||||||
await tester.tap(find.byKey(const Key('tab-theater')));
|
await tester.tap(find.byKey(const Key('tab-theater')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(haptics.selectionClicks, 1);
|
expect(haptics.selectionClicks, 1);
|
||||||
|
final lightBar = tester.widget<Container>(barFinder);
|
||||||
|
final lightDecoration = lightBar.decoration as BoxDecoration;
|
||||||
|
expect(lightDecoration.color, AppColors.bar.withValues(alpha: 0.95));
|
||||||
|
expect((lightDecoration.border as Border).top.color, AppColors.border);
|
||||||
await tester.tap(find.byKey(const Key('tab-theater')));
|
await tester.tap(find.byKey(const Key('tab-theater')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(haptics.selectionClicks, 1);
|
expect(haptics.selectionClicks, 1);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ void main() {
|
|||||||
expect(find.byKey(const Key('player-episodes-sheet')), findsOneWidget);
|
expect(find.byKey(const Key('player-episodes-sheet')), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_show_coming_soon_for_danmaku_and_following_tab', (
|
testWidgets('should_show_coming_soon_for_danmaku_and_anime_tab', (
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
await _pumpApp(tester);
|
await _pumpApp(tester);
|
||||||
@@ -86,7 +86,7 @@ void main() {
|
|||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('Coming soon'), findsOneWidget);
|
expect(find.text('Coming soon'), findsOneWidget);
|
||||||
|
|
||||||
await tester.tap(find.byKey(const Key('home-feed-tab-follow')));
|
await tester.tap(find.byKey(const Key('home-feed-tab-anime')));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('Coming soon'), findsOneWidget);
|
expect(find.text('Coming soon'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in new issue
Block a user