fix(home): 修正封面角标与题材标签
This commit is contained in:
1 parent
3abf69e886
commit
e16faa258a
10 files changed
+199
-199
No files matched your search
@@ -1112,7 +1112,8 @@ $ flutter test
|
|||||||
## 2026-10-22 首页布局对齐修正
|
## 2026-10-22 首页布局对齐修正
|
||||||
|
|
||||||
- 一级分类改为页内切换 6 个列表,未选 16/w400 灰字、选中 20/w700 白字,无下划线;二级 chips 仅精选显示。
|
- 一级分类改为页内切换 6 个列表,未选 16/w400 灰字、选中 20/w700 白字,无下划线;二级 chips 仅精选显示。
|
||||||
- 四类短剧卡片移除底板/描边,封面统一 8 圆角,网格行距 10、封底到标题 6,题材移至右上角异形丝带。
|
- 四类短剧卡片移除底板/描边,封面统一 8 圆角,网格行距 10、封底到标题 6;热剧/新剧/漫剧角标移至右上角异形丝带。
|
||||||
|
- 标题下方恢复左对齐题材文字,使用 `|` 分隔、灰色小字,与封面状态角标保持独立。
|
||||||
- 首页搜索栏到一级、一级到二级、二级到网格间距为 8/8/10;非精选 tab 直接以 10 衔接网格。
|
- 首页搜索栏到一级、一级到二级、二级到网格间距为 8/8/10;非精选 tab 直接以 10 衔接网格。
|
||||||
- 播放量统一 spark 图标与 `w` 格式,整数无小数;首页、剧单、全部短剧、追剧共用。
|
- 播放量统一 spark 图标与 `w` 格式,整数无小数;首页、剧单、全部短剧、追剧共用。
|
||||||
- 全部短剧的地区、字幕、配音筛选 UI 已占位;以下接口待补:地区、字幕/配音筛选数据。
|
- 全部短剧的地区、字幕、配音筛选 UI 已占位;以下接口待补:地区、字幕/配音筛选数据。
|
||||||
@@ -92,13 +92,8 @@ abstract final class AppDimens {
|
|||||||
static const double cardGenreRibbonLeftInset = 8;
|
static const double cardGenreRibbonLeftInset = 8;
|
||||||
static const double cardGenreRibbonMaxWidth = 86;
|
static const double cardGenreRibbonMaxWidth = 86;
|
||||||
static const double cardTagFont = 11;
|
static const double cardTagFont = 11;
|
||||||
static const double cardTagHeight = 18;
|
|
||||||
static const double cardTagRadius = 9;
|
|
||||||
static const double cardTagHorizontalPadding = 6;
|
static const double cardTagHorizontalPadding = 6;
|
||||||
static const double cardBadgeFont = 10;
|
static const double cardBadgeFont = 10;
|
||||||
static const double cardBadgeRadius = 3;
|
|
||||||
static const double cardBadgeHorizontalPadding = 6;
|
|
||||||
static const double cardBadgeVerticalPadding = 2;
|
|
||||||
static const double cardCoverTitleGap = 6;
|
static const double cardCoverTitleGap = 6;
|
||||||
static const double cardTitleTagGap = 6;
|
static const double cardTitleTagGap = 6;
|
||||||
static const double cardCoverAspectRatio = 5 / 6;
|
static const double cardCoverAspectRatio = 5 / 6;
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
// Author: fruit.com.cn
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../theme/app_colors.dart';
|
||||||
|
import '../theme/app_dimens.dart';
|
||||||
|
|
||||||
|
/// 封面右上角的斜边状态角标。
|
||||||
|
class DramaCoverBadgeRibbon extends StatelessWidget {
|
||||||
|
const DramaCoverBadgeRibbon({
|
||||||
|
super.key,
|
||||||
|
required this.label,
|
||||||
|
required this.color,
|
||||||
|
required this.keyPrefix,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String label;
|
||||||
|
final Color color;
|
||||||
|
final String keyPrefix;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ClipPath(
|
||||||
|
key: Key('drama-cover-badge-ribbon-$keyPrefix'),
|
||||||
|
clipper: const _SlantedRibbonClipper(),
|
||||||
|
child: Container(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: AppDimens.cardGenreRibbonMaxWidth,
|
||||||
|
),
|
||||||
|
height: AppDimens.cardGenreRibbonHeight,
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left:
|
||||||
|
AppDimens.cardTagHorizontalPadding +
|
||||||
|
AppDimens.cardGenreRibbonLeftInset,
|
||||||
|
right: AppDimens.cardTagHorizontalPadding,
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
color: color,
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: AppColors.textPrimary,
|
||||||
|
fontSize: AppDimens.cardBadgeFont,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SlantedRibbonClipper extends CustomClipper<Path> {
|
||||||
|
const _SlantedRibbonClipper();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Path getClip(Size size) {
|
||||||
|
return Path()
|
||||||
|
..moveTo(AppDimens.cardGenreRibbonLeftInset, 0)
|
||||||
|
..lineTo(size.width, 0)
|
||||||
|
..lineTo(size.width, size.height)
|
||||||
|
..lineTo(0, size.height)
|
||||||
|
..close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldReclip(_SlantedRibbonClipper oldClipper) => false;
|
||||||
|
}
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
// Author: fruit.com.cn
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../theme/app_colors.dart';
|
|
||||||
import '../theme/app_dimens.dart';
|
|
||||||
|
|
||||||
const List<Color> _ribbonColors = [
|
|
||||||
AppColors.badgeHot,
|
|
||||||
AppColors.badgeNew,
|
|
||||||
AppColors.badgeAnime,
|
|
||||||
];
|
|
||||||
|
|
||||||
/// 封面右上角的斜边题材丝带。
|
|
||||||
class DramaGenreRibbon extends StatelessWidget {
|
|
||||||
const DramaGenreRibbon({
|
|
||||||
super.key,
|
|
||||||
required this.tags,
|
|
||||||
required this.keyPrefix,
|
|
||||||
});
|
|
||||||
|
|
||||||
final List<String> tags;
|
|
||||||
final String keyPrefix;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final visible = tags
|
|
||||||
.map((tag) => tag.trim())
|
|
||||||
.where((tag) => tag.isNotEmpty)
|
|
||||||
.take(3)
|
|
||||||
.toList(growable: false);
|
|
||||||
if (visible.isEmpty) return const SizedBox.shrink();
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
for (final (index, tag) in visible.indexed) ...[
|
|
||||||
if (index > 0) const SizedBox(height: 2),
|
|
||||||
ClipPath(
|
|
||||||
key: Key('drama-genre-ribbon-$keyPrefix-$index'),
|
|
||||||
clipper: const _SlantedRibbonClipper(),
|
|
||||||
child: Container(
|
|
||||||
constraints: const BoxConstraints(
|
|
||||||
maxWidth: AppDimens.cardGenreRibbonMaxWidth,
|
|
||||||
),
|
|
||||||
height: AppDimens.cardGenreRibbonHeight,
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left:
|
|
||||||
AppDimens.cardTagHorizontalPadding +
|
|
||||||
AppDimens.cardGenreRibbonLeftInset,
|
|
||||||
right: AppDimens.cardTagHorizontalPadding,
|
|
||||||
),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
color: _ribbonColors[index % _ribbonColors.length],
|
|
||||||
child: Text(
|
|
||||||
tag,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: const TextStyle(
|
|
||||||
color: AppColors.textPrimary,
|
|
||||||
fontSize: AppDimens.cardBadgeFont,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SlantedRibbonClipper extends CustomClipper<Path> {
|
|
||||||
const _SlantedRibbonClipper();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Path getClip(Size size) {
|
|
||||||
return Path()
|
|
||||||
..moveTo(AppDimens.cardGenreRibbonLeftInset, 0)
|
|
||||||
..lineTo(size.width, 0)
|
|
||||||
..lineTo(size.width, size.height)
|
|
||||||
..lineTo(0, size.height)
|
|
||||||
..close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool shouldReclip(_SlantedRibbonClipper oldClipper) => false;
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
|
|||||||
import '../../core/formatting/count_format.dart';
|
import '../../core/formatting/count_format.dart';
|
||||||
import '../../core/theme/app_colors.dart';
|
import '../../core/theme/app_colors.dart';
|
||||||
import '../../core/theme/app_dimens.dart';
|
import '../../core/theme/app_dimens.dart';
|
||||||
import '../../core/widgets/drama_genre_ribbon.dart';
|
|
||||||
import '../../core/widgets/remote_image.dart';
|
import '../../core/widgets/remote_image.dart';
|
||||||
|
|
||||||
class FollowingGridCard extends StatelessWidget {
|
class FollowingGridCard extends StatelessWidget {
|
||||||
@@ -95,12 +94,6 @@ class FollowingGridCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (!editing)
|
|
||||||
Positioned(
|
|
||||||
top: 0,
|
|
||||||
right: 0,
|
|
||||||
child: DramaGenreRibbon(tags: tags, keyPrefix: dramaId),
|
|
||||||
),
|
|
||||||
if (editing)
|
if (editing)
|
||||||
Positioned(
|
Positioned(
|
||||||
top: -6,
|
top: -6,
|
||||||
@@ -135,6 +128,10 @@ class FollowingGridCard extends StatelessWidget {
|
|||||||
height: AppDimens.cardTitleLineHeight,
|
height: AppDimens.cardTitleLineHeight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (tags.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: AppDimens.cardTitleTagGap),
|
||||||
|
_tags(),
|
||||||
|
],
|
||||||
const SizedBox(height: AppDimens.spaceXs),
|
const SizedBox(height: AppDimens.spaceXs),
|
||||||
Text(
|
Text(
|
||||||
subtitle,
|
subtitle,
|
||||||
@@ -164,4 +161,19 @@ class FollowingGridCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _tags() {
|
||||||
|
final visible = tags.take(3).toList(growable: false);
|
||||||
|
return Text(
|
||||||
|
visible.join(' | '),
|
||||||
|
key: Key('following-tags-$dramaId'),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: AppColors.textTertiary,
|
||||||
|
fontSize: AppDimens.cardTagFont,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ import '../../../core/data/models/drama.dart';
|
|||||||
import '../../../core/formatting/count_format.dart';
|
import '../../../core/formatting/count_format.dart';
|
||||||
import '../../../core/theme/app_colors.dart';
|
import '../../../core/theme/app_colors.dart';
|
||||||
import '../../../core/theme/app_dimens.dart';
|
import '../../../core/theme/app_dimens.dart';
|
||||||
import '../../../core/widgets/drama_genre_ribbon.dart';
|
import '../../../core/widgets/drama_cover_badge_ribbon.dart';
|
||||||
import '../../../core/widgets/remote_image.dart';
|
import '../../../core/widgets/remote_image.dart';
|
||||||
import '../../../l10n/app_localizations.dart';
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'home_drama_classification.dart';
|
import 'home_drama_classification.dart';
|
||||||
@@ -63,6 +63,8 @@ class HomeFeedCard extends StatelessWidget {
|
|||||||
height: AppDimens.cardTitleLineHeight,
|
height: AppDimens.cardTitleLineHeight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: AppDimens.cardTitleTagGap),
|
||||||
|
_tags(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -92,15 +94,14 @@ class HomeFeedCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
if (badge != null)
|
if (badge != null)
|
||||||
Positioned(
|
Positioned(
|
||||||
top: AppDimens.spaceXs,
|
top: 0,
|
||||||
left: AppDimens.spaceXs,
|
right: 0,
|
||||||
child: _badgeChip(l10n, badge),
|
child: DramaCoverBadgeRibbon(
|
||||||
|
label: _badgeLabel(l10n, badge),
|
||||||
|
color: _badgeColor(badge),
|
||||||
|
keyPrefix: '${drama.id}-${badge.name}',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
|
||||||
top: 0,
|
|
||||||
right: 0,
|
|
||||||
child: DramaGenreRibbon(tags: _cardTags(), keyPrefix: drama.id),
|
|
||||||
),
|
|
||||||
Positioned(
|
Positioned(
|
||||||
left: AppDimens.spaceXs,
|
left: AppDimens.spaceXs,
|
||||||
bottom: AppDimens.spaceXs,
|
bottom: AppDimens.spaceXs,
|
||||||
@@ -123,32 +124,20 @@ class HomeFeedCard extends StatelessWidget {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _badgeChip(AppLocalizations l10n, HomeDramaBadge badge) {
|
String _badgeLabel(AppLocalizations l10n, HomeDramaBadge badge) {
|
||||||
final (label, color) = switch (badge) {
|
return switch (badge) {
|
||||||
HomeDramaBadge.hot => (l10n.homeBadgeHot, AppColors.badgeHot),
|
HomeDramaBadge.hot => l10n.homeBadgeHot,
|
||||||
HomeDramaBadge.newRelease => (l10n.homeBadgeNew, AppColors.badgeNew),
|
HomeDramaBadge.newRelease => l10n.homeBadgeNew,
|
||||||
HomeDramaBadge.anime => (l10n.homeBadgeAnime, AppColors.badgeAnime),
|
HomeDramaBadge.anime => l10n.homeBadgeAnime,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Color _badgeColor(HomeDramaBadge badge) {
|
||||||
|
return switch (badge) {
|
||||||
|
HomeDramaBadge.hot => AppColors.badgeHot,
|
||||||
|
HomeDramaBadge.newRelease => AppColors.badgeNew,
|
||||||
|
HomeDramaBadge.anime => AppColors.badgeAnime,
|
||||||
};
|
};
|
||||||
return Container(
|
|
||||||
key: Key('home-feed-badge-${badge.name}-${drama.id}'),
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: AppDimens.cardBadgeHorizontalPadding,
|
|
||||||
vertical: AppDimens.cardBadgeVerticalPadding,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: color,
|
|
||||||
borderRadius: BorderRadius.circular(AppDimens.cardBadgeRadius),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
label,
|
|
||||||
style: const TextStyle(
|
|
||||||
color: AppColors.navSelected,
|
|
||||||
fontSize: AppDimens.cardBadgeFont,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
letterSpacing: 0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _views() {
|
Widget _views() {
|
||||||
@@ -182,6 +171,23 @@ class HomeFeedCard extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _tags() {
|
||||||
|
final tags = _cardTags();
|
||||||
|
if (tags.isEmpty) return const SizedBox.shrink();
|
||||||
|
return Text(
|
||||||
|
tags.join(' | '),
|
||||||
|
key: Key('home-feed-tags-${drama.id}'),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: AppColors.textTertiary,
|
||||||
|
fontSize: AppDimens.cardTagFont,
|
||||||
|
letterSpacing: 0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
List<String> _cardTags() {
|
List<String> _cardTags() {
|
||||||
final seen = <String>{};
|
final seen = <String>{};
|
||||||
return [drama.genre, drama.category]
|
return [drama.genre, drama.category]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import '../../../core/data/models/drama.dart';
|
|||||||
import '../../../core/formatting/count_format.dart';
|
import '../../../core/formatting/count_format.dart';
|
||||||
import '../../../core/theme/app_colors.dart';
|
import '../../../core/theme/app_colors.dart';
|
||||||
import '../../../core/theme/app_dimens.dart';
|
import '../../../core/theme/app_dimens.dart';
|
||||||
import '../../../core/widgets/drama_genre_ribbon.dart';
|
import '../../../core/widgets/drama_cover_badge_ribbon.dart';
|
||||||
import '../../../core/widgets/remote_image.dart';
|
import '../../../core/widgets/remote_image.dart';
|
||||||
import '../../../l10n/app_localizations.dart';
|
import '../../../l10n/app_localizations.dart';
|
||||||
import '../../home/widgets/home_drama_classification.dart';
|
import '../../home/widgets/home_drama_classification.dart';
|
||||||
@@ -54,38 +54,14 @@ class RecommendSectionCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
if (isHotDrama(drama))
|
if (isHotDrama(drama))
|
||||||
Positioned(
|
Positioned(
|
||||||
top: AppDimens.spaceXs,
|
top: 0,
|
||||||
left: AppDimens.spaceXs,
|
right: 0,
|
||||||
child: Container(
|
child: DramaCoverBadgeRibbon(
|
||||||
key: Key('recommend-hot-$sectionKey-${drama.id}'),
|
label: l10n.homeBadgeHot,
|
||||||
padding: const EdgeInsets.symmetric(
|
color: AppColors.badgeHot,
|
||||||
horizontal: AppDimens.cardBadgeHorizontalPadding,
|
keyPrefix: '$sectionKey-${drama.id}-hot',
|
||||||
vertical: AppDimens.cardBadgeVerticalPadding,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColors.badgeHot,
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
AppDimens.cardBadgeRadius,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
l10n.homeBadgeHot,
|
|
||||||
style: const TextStyle(
|
|
||||||
color: AppColors.textPrimary,
|
|
||||||
fontSize: AppDimens.cardBadgeFont,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
|
||||||
top: 0,
|
|
||||||
right: 0,
|
|
||||||
child: DramaGenreRibbon(
|
|
||||||
tags: _cardTags(),
|
|
||||||
keyPrefix: '$sectionKey-${drama.id}',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -123,6 +99,8 @@ class RecommendSectionCard extends StatelessWidget {
|
|||||||
height: AppDimens.cardTitleLineHeight,
|
height: AppDimens.cardTitleLineHeight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: AppDimens.cardTitleTagGap),
|
||||||
|
_tags(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -138,4 +116,20 @@ class RecommendSectionCard extends StatelessWidget {
|
|||||||
.take(3)
|
.take(3)
|
||||||
.toList(growable: false);
|
.toList(growable: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _tags() {
|
||||||
|
final tags = _cardTags();
|
||||||
|
if (tags.isEmpty) return const SizedBox.shrink();
|
||||||
|
return Text(
|
||||||
|
tags.join(' | '),
|
||||||
|
key: Key('recommend-tags-$sectionKey-${drama.id}'),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: AppColors.textTertiary,
|
||||||
|
fontSize: AppDimens.cardTagFont,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -96,17 +96,14 @@ void main() {
|
|||||||
),
|
),
|
||||||
findsOneWidget,
|
findsOneWidget,
|
||||||
);
|
);
|
||||||
final ribbon = find.byKey(
|
final tags = tester.widget<Text>(
|
||||||
const Key('drama-genre-ribbon-the-signal-demo-0'),
|
find.byKey(const Key('following-tags-the-signal-demo')),
|
||||||
);
|
);
|
||||||
expect(ribbon, findsOneWidget);
|
expect(tags.data, 'Suspense | Mystery');
|
||||||
final ribbonText = tester.widget<Text>(
|
expect(tags.style?.fontSize, AppDimens.cardTagFont);
|
||||||
find.descendant(of: ribbon, matching: find.byType(Text)),
|
expect(tags.style?.color, AppColors.textTertiary);
|
||||||
);
|
|
||||||
expect(ribbonText.data, 'Suspense');
|
|
||||||
expect(ribbonText.style?.fontSize, AppDimens.cardBadgeFont);
|
|
||||||
expect(ribbonText.style?.color, AppColors.textPrimary);
|
|
||||||
expect(tester.getTopLeft(title).dx, tester.getTopLeft(cover).dx);
|
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.tap(find.byKey(const Key('following-edit')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|||||||
@@ -48,13 +48,10 @@ void main() {
|
|||||||
coverClip.borderRadius,
|
coverClip.borderRadius,
|
||||||
BorderRadius.circular(AppDimens.cardCoverRadius),
|
BorderRadius.circular(AppDimens.cardCoverRadius),
|
||||||
);
|
);
|
||||||
final badge = find.byKey(const Key('home-feed-badge-anime-anime-card'));
|
final badge = find.byKey(
|
||||||
expect(badge, findsOneWidget);
|
const Key('drama-cover-badge-ribbon-anime-card-anime'),
|
||||||
final badgeContainer = tester.widget<Container>(badge);
|
|
||||||
expect(
|
|
||||||
(badgeContainer.decoration! as BoxDecoration).borderRadius,
|
|
||||||
BorderRadius.circular(AppDimens.cardBadgeRadius),
|
|
||||||
);
|
);
|
||||||
|
expect(badge, findsOneWidget);
|
||||||
expect(
|
expect(
|
||||||
tester
|
tester
|
||||||
.widget<Text>(find.descendant(of: badge, matching: find.byType(Text)))
|
.widget<Text>(find.descendant(of: badge, matching: find.byType(Text)))
|
||||||
@@ -62,6 +59,14 @@ void main() {
|
|||||||
?.fontSize,
|
?.fontSize,
|
||||||
AppDimens.cardBadgeFont,
|
AppDimens.cardBadgeFont,
|
||||||
);
|
);
|
||||||
|
expect(
|
||||||
|
tester.getTopRight(badge).dx,
|
||||||
|
closeTo(tester.getTopRight(cover).dx, 1),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester.getTopRight(badge).dy,
|
||||||
|
closeTo(tester.getTopRight(cover).dy, 1),
|
||||||
|
);
|
||||||
expect(find.text('Anime'), findsOneWidget);
|
expect(find.text('Anime'), findsOneWidget);
|
||||||
expect(find.byKey(const Key('home-feed-views-anime-card')), findsOneWidget);
|
expect(find.byKey(const Key('home-feed-views-anime-card')), findsOneWidget);
|
||||||
final views = find.byKey(const Key('home-feed-views-anime-card'));
|
final views = find.byKey(const Key('home-feed-views-anime-card'));
|
||||||
@@ -85,15 +90,14 @@ void main() {
|
|||||||
expect(title.style?.fontSize, AppDimens.cardTitleFont);
|
expect(title.style?.fontSize, AppDimens.cardTitleFont);
|
||||||
expect(title.style?.fontWeight, FontWeight.w500);
|
expect(title.style?.fontWeight, FontWeight.w500);
|
||||||
expect(title.style?.height, AppDimens.cardTitleLineHeight);
|
expect(title.style?.height, AppDimens.cardTitleLineHeight);
|
||||||
final ribbon = find.byKey(const Key('drama-genre-ribbon-anime-card-0'));
|
final tags = tester.widget<Text>(
|
||||||
expect(ribbon, findsOneWidget);
|
find.byKey(const Key('home-feed-tags-anime-card')),
|
||||||
final ribbonText = tester.widget<Text>(
|
|
||||||
find.descendant(of: ribbon, matching: find.byType(Text)),
|
|
||||||
);
|
);
|
||||||
expect(ribbonText.data, 'Romance');
|
expect(tags.data, 'Romance | Urban');
|
||||||
expect(ribbonText.style?.fontSize, AppDimens.cardBadgeFont);
|
expect(tags.style?.fontSize, AppDimens.cardTagFont);
|
||||||
expect(ribbonText.style?.color, AppColors.textPrimary);
|
expect(tags.style?.color, AppColors.textTertiary);
|
||||||
expect(tester.getTopLeft(title).dx, tester.getTopLeft(cover).dx);
|
expect(tester.getTopLeft(title).dx, tester.getTopLeft(cover).dx);
|
||||||
|
expect(tester.getTopLeft(tags).dx, tester.getTopLeft(cover).dx);
|
||||||
|
|
||||||
await tester.tap(card);
|
await tester.tap(card);
|
||||||
expect(taps, 1);
|
expect(taps, 1);
|
||||||
@@ -134,14 +138,17 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
find.byKey(const Key('home-feed-badge-anime-anime')),
|
find.byKey(const Key('drama-cover-badge-ribbon-anime-anime')),
|
||||||
findsOneWidget,
|
findsOneWidget,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
find.byKey(const Key('home-feed-badge-newRelease-new')),
|
find.byKey(const Key('drama-cover-badge-ribbon-new-newRelease')),
|
||||||
|
findsOneWidget,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
find.byKey(const Key('drama-cover-badge-ribbon-hot-hot')),
|
||||||
findsOneWidget,
|
findsOneWidget,
|
||||||
);
|
);
|
||||||
expect(find.byKey(const Key('home-feed-badge-hot-hot')), findsOneWidget);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,17 +115,24 @@ void main() {
|
|||||||
matching: find.byIcon(Icons.auto_awesome_rounded),
|
matching: find.byIcon(Icons.auto_awesome_rounded),
|
||||||
);
|
);
|
||||||
expect(viewIcon, findsOneWidget);
|
expect(viewIcon, findsOneWidget);
|
||||||
final ribbon = find.byKey(
|
final badge = find.byKey(
|
||||||
const Key('drama-genre-ribbon-hits-the-signal-demo-0'),
|
const Key('drama-cover-badge-ribbon-hits-the-signal-demo-hot'),
|
||||||
);
|
);
|
||||||
expect(ribbon, findsOneWidget);
|
expect(badge, findsOneWidget);
|
||||||
final ribbonText = tester.widget<Text>(
|
final badgeText = tester.widget<Text>(
|
||||||
find.descendant(of: ribbon, matching: find.byType(Text)),
|
find.descendant(of: badge, matching: find.byType(Text)),
|
||||||
);
|
);
|
||||||
expect(ribbonText.data, 'Suspense');
|
expect(badgeText.data, 'Hit');
|
||||||
expect(ribbonText.style?.fontSize, AppDimens.cardBadgeFont);
|
expect(badgeText.style?.fontSize, AppDimens.cardBadgeFont);
|
||||||
expect(ribbonText.style?.color, AppColors.textPrimary);
|
expect(badgeText.style?.color, AppColors.textPrimary);
|
||||||
|
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(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', (
|
testWidgets('should_switch_inner_tabs_without_losing_grid_filter_state', (
|
||||||
|
|||||||
Reference in new issue
Block a user