From a47af8c3adaaae4adc2d2b44cd3cb97420976c3e Mon Sep 17 00:00:00 2001 From: Vicky <10212746+haifeng-jiang@user.noreply.gitee.com> Date: Sat, 31 Oct 2026 09:41:19 +0800 Subject: [PATCH] =?UTF-8?q?style(player):=20=E8=A7=86=E9=A2=91=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E5=8C=BA=E6=96=87=E6=A1=88=E7=BB=9F=E4=B8=80=E4=B8=BA?= =?UTF-8?q?=2065%=20=E5=8D=8A=E9=80=8F=E6=98=8E=E7=99=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/theme/app_colors.dart | 3 +++ lib/pages/player/widgets/expandable_synopsis.dart | 14 ++++++++++---- lib/pages/player/widgets/home_feed_info_tags.dart | 2 +- .../player/widgets/home_feed_recommend_panel.dart | 1 + test/home/feed_info_hierarchy_test.dart | 8 ++++---- test/player/expandable_synopsis_test.dart | 9 +++++++++ test/player/player_fullscreen_test.dart | 2 +- 7 files changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/core/theme/app_colors.dart b/lib/core/theme/app_colors.dart index cef7b68..1b041f1 100644 --- a/lib/core/theme/app_colors.dart +++ b/lib/core/theme/app_colors.dart @@ -27,6 +27,9 @@ abstract final class AppColors { static const overlaySecondary = Color(0xFFC7C7CC); static const overlayLabel = Color(0xFFE6E6EB); + /// 首页及剧集播放页视频信息文案:参考设计图的 65% 半透明白。 + static const homeFeedVideoCopy = Color(0xA6FFFFFF); + /// 主操作、选中态、播放进度。旧品牌橙已全量映射为品牌红(2026-10 改版)。 static const blue = Color(0xFFF04E4E); static const primary = blue; diff --git a/lib/pages/player/widgets/expandable_synopsis.dart b/lib/pages/player/widgets/expandable_synopsis.dart index 6936288..b016751 100644 --- a/lib/pages/player/widgets/expandable_synopsis.dart +++ b/lib/pages/player/widgets/expandable_synopsis.dart @@ -12,7 +12,6 @@ const double _synopsisToggleWidthFraction = 0.55; const double _synopsisToggleGap = 6; const _synopsisMotion = Duration(milliseconds: 240); const _synopsisStyle = TextStyle( - color: AppColors.overlaySecondary, fontSize: _synopsisFont, fontWeight: FontWeight.w400, height: _synopsisLineHeight, @@ -32,6 +31,7 @@ class ExpandableSynopsis extends StatefulWidget { required this.synopsis, this.keyPrefix = 'home-feed', this.expandedFooter, + this.textColor = AppColors.homeFeedVideoCopy, }); /// 按当前语言获取的简介正文。 @@ -43,6 +43,9 @@ class ExpandableSynopsis extends StatefulWidget { /// 展开后附加的声明等内容。 final Widget? expandedFooter; + /// 简介正文颜色;默认使用视频信息区统一的半透明浅灰白。 + final Color textColor; + @override State createState() => _ExpandableSynopsisState(); } @@ -88,7 +91,7 @@ class _ExpandableSynopsisState extends State { } bool _needsToggle(double maxWidth) { - final painter = _painter(widget.synopsis, _synopsisStyle); + final painter = _painter(widget.synopsis, _bodyStyle); painter.layout(maxWidth: maxWidth); final overflows = painter.didExceedMaxLines; painter.dispose(); @@ -120,11 +123,14 @@ class _ExpandableSynopsisState extends State { Key _key(String suffix) => Key('${widget.keyPrefix}-synopsis-$suffix'); + TextStyle get _bodyStyle => _synopsisStyle.copyWith(color: widget.textColor); + Widget _body() { + final style = _bodyStyle; final text = Text.rich( - TextSpan(text: widget.synopsis, style: _synopsisStyle), + TextSpan(text: widget.synopsis, style: style), key: _expanded ? _key('expanded') : Key('${widget.keyPrefix}-synopsis'), - style: _synopsisStyle, + style: style, maxLines: _expanded ? null : _collapsedSynopsisLines, overflow: _expanded ? TextOverflow.clip : TextOverflow.ellipsis, ); diff --git a/lib/pages/player/widgets/home_feed_info_tags.dart b/lib/pages/player/widgets/home_feed_info_tags.dart index 36cffb1..0bd7a91 100644 --- a/lib/pages/player/widgets/home_feed_info_tags.dart +++ b/lib/pages/player/widgets/home_feed_info_tags.dart @@ -101,7 +101,7 @@ class _TagChip extends StatelessWidget { maxLines: 1, strutStyle: _metadataStrutStyle, style: const TextStyle( - color: AppColors.overlaySecondary, + color: AppColors.homeFeedVideoCopy, fontSize: _tagFont, fontWeight: FontWeight.w500, height: _metadataLineHeight, diff --git a/lib/pages/player/widgets/home_feed_recommend_panel.dart b/lib/pages/player/widgets/home_feed_recommend_panel.dart index 9fdd14c..8956862 100644 --- a/lib/pages/player/widgets/home_feed_recommend_panel.dart +++ b/lib/pages/player/widgets/home_feed_recommend_panel.dart @@ -103,6 +103,7 @@ class _HomeFeedInfoPanelState extends State { ExpandableSynopsis( key: ValueKey(widget.drama.id), synopsis: synopsis, + textColor: AppColors.homeFeedVideoCopy, ), ], ], diff --git a/test/home/feed_info_hierarchy_test.dart b/test/home/feed_info_hierarchy_test.dart index 04140e1..ac40c3e 100644 --- a/test/home/feed_info_hierarchy_test.dart +++ b/test/home/feed_info_hierarchy_test.dart @@ -136,7 +136,7 @@ void _expectExpandedSynopsis(WidgetTester tester) { final expanded = find.byKey(const Key('home-feed-synopsis-expanded')); expect( tester.widget(expanded).textSpan?.style?.color, - AppColors.overlaySecondary, + AppColors.homeFeedVideoCopy, ); _expectNoShadows(tester); _expectWatchGap(tester); @@ -187,7 +187,7 @@ void main() { matching: find.byType(Text), ), ); - expect(tag.style?.color, AppColors.overlaySecondary); + expect(tag.style?.color, AppColors.homeFeedVideoCopy); }); testWidgets('should_skip_motion_when_system_disables_animations', ( @@ -343,7 +343,7 @@ void main() { final synopsis = tester.widget( find.byKey(const Key('home-feed-synopsis')), ); - expect(synopsis.style?.color, AppColors.overlaySecondary); + expect(synopsis.style?.color, AppColors.homeFeedVideoCopy); expect(synopsis.style?.fontSize, 15); expect(synopsis.maxLines, 2); final episode = tester.widget( @@ -353,7 +353,7 @@ void main() { expect(episode.style?.fontSize, 14); expect(episode.data, 'Episode 2 / 24'); final tag = tester.widget(find.text('Romance')); - expect(tag.style?.color, AppColors.overlaySecondary); + expect(tag.style?.color, AppColors.homeFeedVideoCopy); expect(tag.style?.color, synopsis.style?.color); expect(tag.style?.fontSize, 13); final hotSearch = tester.widget( diff --git a/test/player/expandable_synopsis_test.dart b/test/player/expandable_synopsis_test.dart index f307808..8b8985d 100644 --- a/test/player/expandable_synopsis_test.dart +++ b/test/player/expandable_synopsis_test.dart @@ -2,6 +2,7 @@ // 职责:验证共用简介的短文案、展开声明、内容更新与减少动画行为。 import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:fruitshorts/core/theme/app_colors.dart'; import 'package:fruitshorts/core/theme/app_theme.dart'; import 'package:fruitshorts/l10n/app_localizations.dart'; import 'package:fruitshorts/pages/player/widgets/expandable_synopsis.dart'; @@ -54,6 +55,14 @@ Future _pump( } void main() { + testWidgets('should_use_video_copy_color_when_player_does_not_override', ( + tester, + ) async { + await _pump(tester, synopsis: _shortCopy); + final synopsis = tester.widget(find.byKey(_collapsed)); + expect(synopsis.style?.color, AppColors.homeFeedVideoCopy); + }); + testWidgets('should_hide_toggle_when_synopsis_fits_two_lines', ( tester, ) async { diff --git a/test/player/player_fullscreen_test.dart b/test/player/player_fullscreen_test.dart index 9b950f2..42dd98e 100644 --- a/test/player/player_fullscreen_test.dart +++ b/test/player/player_fullscreen_test.dart @@ -1517,7 +1517,7 @@ void main() { final style = line.style ?? const TextStyle(); expect(style.fontSize, 15); expect(style.fontWeight, FontWeight.w400); - expect(style.color, AppColors.overlaySecondary); + expect(style.color, AppColors.homeFeedVideoCopy); expect(style.shadows ?? [], isEmpty); expect(line.textSpan!.toPlainText(), isNot(startsWith('Episode '))); expect(line.textSpan!.toPlainText(), isNot(contains(' | ')));