merge: 调整播放量行内展示

This commit is contained in:
Zhou Weidong committed 2026-10-22 18:28:00 +08:00
commit 5da836dded
8 files changed
+138 -114

No files matched your search

+1 -1
View File
@@ -1115,5 +1115,5 @@ $ flutter test
- 四类短剧卡片移除底板/描边,封面统一 8 圆角,网格行距 10、封底到标题 6;热剧/新剧/漫剧角标移至右上角异形丝带。 - 四类短剧卡片移除底板/描边,封面统一 8 圆角,网格行距 10、封底到标题 6;热剧/新剧/漫剧角标移至右上角异形丝带。
- 标题下方恢复左对齐题材文字,使用 `|` 分隔、灰色小字,与封面状态角标保持独立。 - 标题下方恢复左对齐题材文字,使用 `|` 分隔、灰色小字,与封面状态角标保持独立。
- 首页搜索栏到一级、一级到二级、二级到网格间距为 8/8/10;非精选 tab 直接以 10 衔接网格。 - 首页搜索栏到一级、一级到二级、二级到网格间距为 8/8/10;非精选 tab 直接以 10 衔接网格。
- 播放量统一 spark 图标与 `w` 格式,整数无小数;首页、剧单、全部短剧、追剧共用。 - 播放量移至标题行最右,使用 spark 图标与 12/w400 纯文字、`w` 格式,整数无小数;四类列表共用。
- 全部短剧的地区、字幕、配音筛选 UI 已占位;以下接口待补:地区、字幕/配音筛选数据。 - 全部短剧的地区、字幕、配音筛选 UI 已占位;以下接口待补:地区、字幕/配音筛选数据。
+2
View File
@@ -87,6 +87,8 @@ abstract final class AppDimens {
static const double cardTitleLineHeight = 1.3; static const double cardTitleLineHeight = 1.3;
static const double cardViewsFont = 11; static const double cardViewsFont = 11;
static const double cardViewsIcon = 11; static const double cardViewsIcon = 11;
static const double cardPlayCountFont = 12;
static const double cardPlayCountGap = 2;
static const double cardGenreRibbonHeight = 20; static const double cardGenreRibbonHeight = 20;
static const double cardGenreRibbonRadius = 10; static const double cardGenreRibbonRadius = 10;
static const double cardGenreRibbonLeftInset = 8; static const double cardGenreRibbonLeftInset = 8;
+45 -43
View File
@@ -62,38 +62,6 @@ class FollowingGridCard extends StatelessWidget {
), ),
), ),
), ),
Positioned(
left: AppDimens.spaceXs,
bottom: AppDimens.spaceXs,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
decoration: BoxDecoration(
color: AppColors.playerOverlayPill,
borderRadius: BorderRadius.circular(AppDimens.pillRadius),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(
Icons.auto_awesome_rounded,
color: AppColors.textPrimary,
size: AppDimens.cardViewsIcon,
),
Text(
formatPlayCount(viewCount),
key: Key('following-views-$dramaId'),
style: const TextStyle(
color: AppColors.textPrimary,
fontSize: AppDimens.cardViewsFont,
),
),
],
),
),
),
if (editing) if (editing)
Positioned( Positioned(
top: -6, top: -6,
@@ -116,17 +84,27 @@ class FollowingGridCard extends StatelessWidget {
), ),
), ),
const SizedBox(height: AppDimens.cardCoverTitleGap), const SizedBox(height: AppDimens.cardCoverTitleGap),
Text( Row(
title, mainAxisAlignment: MainAxisAlignment.spaceBetween,
maxLines: 2, crossAxisAlignment: CrossAxisAlignment.center,
overflow: TextOverflow.ellipsis, children: [
textAlign: TextAlign.left, Expanded(
style: const TextStyle( child: Text(
color: AppColors.textPrimary, title,
fontSize: AppDimens.cardTitleFont, maxLines: 2,
fontWeight: FontWeight.w500, overflow: TextOverflow.ellipsis,
height: AppDimens.cardTitleLineHeight, textAlign: TextAlign.left,
), style: const TextStyle(
color: AppColors.textPrimary,
fontSize: AppDimens.cardTitleFont,
fontWeight: FontWeight.w500,
height: AppDimens.cardTitleLineHeight,
),
),
),
const SizedBox(width: AppDimens.spaceXs),
_views(),
],
), ),
if (tags.isNotEmpty) ...[ if (tags.isNotEmpty) ...[
const SizedBox(height: AppDimens.cardTitleTagGap), const SizedBox(height: AppDimens.cardTitleTagGap),
@@ -162,6 +140,30 @@ class FollowingGridCard extends StatelessWidget {
); );
} }
Widget _views() {
return Row(
key: Key('following-views-$dramaId'),
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
Icons.auto_awesome_rounded,
color: AppColors.textPrimary,
size: AppDimens.cardViewsIcon,
),
const SizedBox(width: AppDimens.cardPlayCountGap),
Text(
formatPlayCount(viewCount),
style: const TextStyle(
color: AppColors.textPrimary,
fontSize: AppDimens.cardPlayCountFont,
fontWeight: FontWeight.w400,
),
),
],
);
}
Widget _tags() { Widget _tags() {
final visible = tags.take(3).toList(growable: false); final visible = tags.take(3).toList(growable: false);
return Text( return Text(
+40 -41
View File
@@ -50,18 +50,28 @@ class HomeFeedCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Text( Row(
drama.title, mainAxisAlignment: MainAxisAlignment.spaceBetween,
key: Key('home-feed-title-${drama.id}'), crossAxisAlignment: CrossAxisAlignment.center,
maxLines: 2, children: [
overflow: TextOverflow.ellipsis, Expanded(
textAlign: TextAlign.left, child: Text(
style: const TextStyle( drama.title,
color: AppColors.navSelected, key: Key('home-feed-title-${drama.id}'),
fontSize: AppDimens.cardTitleFont, maxLines: 2,
fontWeight: FontWeight.w500, overflow: TextOverflow.ellipsis,
height: AppDimens.cardTitleLineHeight, textAlign: TextAlign.left,
), style: const TextStyle(
color: AppColors.navSelected,
fontSize: AppDimens.cardTitleFont,
fontWeight: FontWeight.w500,
height: AppDimens.cardTitleLineHeight,
),
),
),
const SizedBox(width: AppDimens.spaceXs),
_views(),
],
), ),
const SizedBox(height: AppDimens.cardTitleTagGap), const SizedBox(height: AppDimens.cardTitleTagGap),
_tags(), _tags(),
@@ -102,11 +112,6 @@ class HomeFeedCard extends StatelessWidget {
keyPrefix: '${drama.id}-${badge.name}', keyPrefix: '${drama.id}-${badge.name}',
), ),
), ),
Positioned(
left: AppDimens.spaceXs,
bottom: AppDimens.spaceXs,
child: _views(),
),
], ],
), ),
), ),
@@ -141,33 +146,27 @@ class HomeFeedCard extends StatelessWidget {
} }
Widget _views() { Widget _views() {
return Container( return Row(
key: Key('home-feed-views-${drama.id}'), key: Key('home-feed-views-${drama.id}'),
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 2), mainAxisSize: MainAxisSize.min,
decoration: BoxDecoration( crossAxisAlignment: CrossAxisAlignment.center,
color: AppColors.playerOverlayPill, children: [
borderRadius: BorderRadius.circular(AppDimens.pillRadius), const Icon(
), Icons.auto_awesome_rounded,
child: Row( size: AppDimens.cardViewsIcon,
mainAxisSize: MainAxisSize.min, color: AppColors.navSelected,
children: [ ),
const Icon( const SizedBox(width: AppDimens.cardPlayCountGap),
Icons.auto_awesome_rounded, Text(
size: AppDimens.cardViewsIcon, formatPlayCount(drama.viewCount),
style: const TextStyle(
color: AppColors.navSelected, color: AppColors.navSelected,
fontSize: AppDimens.cardPlayCountFont,
fontWeight: FontWeight.w400,
letterSpacing: 0,
), ),
const SizedBox(width: 1), ),
Text( ],
formatPlayCount(drama.viewCount),
style: const TextStyle(
color: AppColors.navSelected,
fontSize: AppDimens.cardViewsFont,
fontWeight: FontWeight.w600,
letterSpacing: 0,
),
),
],
),
); );
} }
@@ -68,37 +68,27 @@ class RecommendSectionCard extends StatelessWidget {
), ),
const SizedBox(height: AppDimens.cardCoverTitleGap), const SizedBox(height: AppDimens.cardCoverTitleGap),
Row( Row(
key: Key('recommend-views-$sectionKey-${drama.id}'), mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
const Icon( Expanded(
Icons.auto_awesome_rounded, child: Text(
color: AppColors.textPrimary, drama.title,
size: AppDimens.cardViewsIcon, key: Key('recommend-title-$sectionKey-${drama.id}'),
), maxLines: 2,
Text( overflow: TextOverflow.ellipsis,
formatPlayCount(drama.viewCount), style: const TextStyle(
style: const TextStyle( color: AppColors.textPrimary,
color: AppColors.textPrimary, fontSize: AppDimens.cardTitleFont,
fontSize: AppDimens.cardViewsFont, fontWeight: FontWeight.w500,
height: AppDimens.cardTitleLineHeight,
),
), ),
), ),
const SizedBox(width: AppDimens.spaceXs),
_views(),
], ],
), ),
const SizedBox(height: 2),
Text(
drama.title,
key: Key('recommend-title-$sectionKey-${drama.id}'),
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.textPrimary,
fontSize: AppDimens.cardTitleFont,
fontWeight: FontWeight.w500,
height: AppDimens.cardTitleLineHeight,
),
),
const SizedBox(height: AppDimens.cardTitleTagGap), const SizedBox(height: AppDimens.cardTitleTagGap),
_tags(), _tags(),
], ],
@@ -107,6 +97,30 @@ class RecommendSectionCard extends StatelessWidget {
); );
} }
Widget _views() {
return Row(
key: Key('recommend-views-$sectionKey-${drama.id}'),
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
Icons.auto_awesome_rounded,
color: AppColors.textPrimary,
size: AppDimens.cardViewsIcon,
),
const SizedBox(width: AppDimens.cardPlayCountGap),
Text(
formatPlayCount(drama.viewCount),
style: const TextStyle(
color: AppColors.textPrimary,
fontSize: AppDimens.cardPlayCountFont,
fontWeight: FontWeight.w400,
),
),
],
);
}
List<String> _cardTags() { List<String> _cardTags() {
final seen = <String>{}; final seen = <String>{};
return [drama.genre, drama.category] return [drama.genre, drama.category]
+2 -1
View File
@@ -87,7 +87,8 @@ void main() {
final views = tester.widget<Text>( final views = tester.widget<Text>(
find.byKey(const Key('following-views-the-signal-demo')), find.byKey(const Key('following-views-the-signal-demo')),
); );
expect(views.style?.fontSize, AppDimens.cardViewsFont); expect(views.style?.fontSize, AppDimens.cardPlayCountFont);
expect(views.style?.fontWeight, FontWeight.w400);
expect(views.style?.color, AppColors.textPrimary); expect(views.style?.color, AppColors.textPrimary);
expect( expect(
find.descendant( find.descendant(
+6 -1
View File
@@ -74,8 +74,13 @@ void main() {
find.descendant(of: views, matching: find.byType(Text)), find.descendant(of: views, matching: find.byType(Text)),
); );
expect(viewsText.data, '44.5w'); expect(viewsText.data, '44.5w');
expect(viewsText.style?.fontSize, AppDimens.cardViewsFont); expect(viewsText.style?.fontSize, AppDimens.cardPlayCountFont);
expect(viewsText.style?.fontWeight, FontWeight.w400);
expect(viewsText.style?.color, AppColors.navSelected); expect(viewsText.style?.color, AppColors.navSelected);
expect(
find.descendant(of: cover, matching: find.byKey(views)),
findsNothing,
);
expect( expect(
find.descendant( find.descendant(
of: views, of: views,
+2 -1
View File
@@ -108,7 +108,8 @@ void main() {
matching: find.byType(Text), matching: find.byType(Text),
), ),
); );
expect(views.style?.fontSize, AppDimens.cardViewsFont); expect(views.style?.fontSize, AppDimens.cardPlayCountFont);
expect(views.style?.fontWeight, FontWeight.w400);
expect(views.style?.color, AppColors.textPrimary); expect(views.style?.color, AppColors.textPrimary);
final viewIcon = find.descendant( final viewIcon = find.descendant(
of: find.byKey(const Key('recommend-views-hits-the-signal-demo')), of: find.byKey(const Key('recommend-views-hits-the-signal-demo')),