merge: 合并 K82-A 右侧互动栏图标升级
This commit is contained in:
commit
35de4095b0
5 files changed
+128
-24
No files matched your search
@@ -173,7 +173,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
|
|||||||
items: [
|
items: [
|
||||||
InteractionRailItem(
|
InteractionRailItem(
|
||||||
key: const Key('rail-save'),
|
key: const Key('rail-save'),
|
||||||
icon: Icons.star_border_rounded,
|
icon: Icons.star_rounded,
|
||||||
activeIcon: Icons.star_rounded,
|
activeIcon: Icons.star_rounded,
|
||||||
label: widget.l10n.favorite,
|
label: widget.l10n.favorite,
|
||||||
count: widget.favoriteCount,
|
count: widget.favoriteCount,
|
||||||
@@ -192,7 +192,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
|
|||||||
),
|
),
|
||||||
InteractionRailItem(
|
InteractionRailItem(
|
||||||
key: const Key('rail-like'),
|
key: const Key('rail-like'),
|
||||||
icon: Icons.favorite_border_rounded,
|
icon: Icons.favorite_rounded,
|
||||||
activeIcon: Icons.favorite_rounded,
|
activeIcon: Icons.favorite_rounded,
|
||||||
label: widget.l10n.like,
|
label: widget.l10n.like,
|
||||||
count: widget.likeCount,
|
count: widget.likeCount,
|
||||||
@@ -202,9 +202,10 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
|
|||||||
),
|
),
|
||||||
InteractionRailItem(
|
InteractionRailItem(
|
||||||
key: const Key('rail-share'),
|
key: const Key('rail-share'),
|
||||||
icon: Icons.ios_share_rounded,
|
icon: Icons.reply_rounded,
|
||||||
activeIcon: Icons.ios_share_rounded,
|
activeIcon: Icons.reply_rounded,
|
||||||
label: widget.l10n.share,
|
label: widget.l10n.share,
|
||||||
|
mirrorIcon: true,
|
||||||
onTap: widget.onShare,
|
onTap: widget.onShare,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ 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';
|
||||||
|
|
||||||
const double _buttonSize = 34;
|
const double _buttonSize = 44;
|
||||||
const double _iconSize = 24;
|
const double _iconSize = 30;
|
||||||
const double _itemGap = 18;
|
const double _itemGap = 22;
|
||||||
const Color _buttonBackground = Color(0x80000000);
|
|
||||||
|
|
||||||
/// 互动栏单项:图标、计数与点击。
|
/// 互动栏单项:图标、计数与点击。
|
||||||
class InteractionRailItem {
|
class InteractionRailItem {
|
||||||
@@ -21,6 +20,7 @@ class InteractionRailItem {
|
|||||||
this.count,
|
this.count,
|
||||||
this.countKey,
|
this.countKey,
|
||||||
this.selected = false,
|
this.selected = false,
|
||||||
|
this.mirrorIcon = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Key key;
|
final Key key;
|
||||||
@@ -31,6 +31,7 @@ class InteractionRailItem {
|
|||||||
final int? count;
|
final int? count;
|
||||||
final Key? countKey;
|
final Key? countKey;
|
||||||
final bool selected;
|
final bool selected;
|
||||||
|
final bool mirrorIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 播放页与首页 feed 共用的右侧互动栏:收藏/评论/喜欢/分享。
|
/// 播放页与首页 feed 共用的右侧互动栏:收藏/评论/喜欢/分享。
|
||||||
@@ -60,6 +61,10 @@ class _RailButton extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final icon = Icon(
|
||||||
|
item.selected ? item.activeIcon : item.icon,
|
||||||
|
size: _iconSize,
|
||||||
|
);
|
||||||
return Column(
|
return Column(
|
||||||
key: item.key,
|
key: item.key,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@@ -69,14 +74,10 @@ class _RailButton extends StatelessWidget {
|
|||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: item.onTap,
|
onPressed: item.onTap,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
style: IconButton.styleFrom(
|
color: item.selected ? AppColors.blue : Colors.white,
|
||||||
backgroundColor: _buttonBackground,
|
icon: item.mirrorIcon
|
||||||
foregroundColor: item.selected ? AppColors.blue : Colors.white,
|
? Transform.flip(flipX: true, child: icon)
|
||||||
),
|
: icon,
|
||||||
icon: Icon(
|
|
||||||
item.selected ? item.activeIcon : item.icon,
|
|
||||||
size: _iconSize,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
@@ -88,7 +89,7 @@ class _RailButton extends StatelessWidget {
|
|||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
height: 1,
|
height: 1,
|
||||||
fontSize: 11,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
shadows: [Shadow(blurRadius: 6, color: Colors.black)],
|
shadows: [Shadow(blurRadius: 6, color: Colors.black)],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -141,13 +141,13 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
|||||||
final compact = MediaQuery.sizeOf(context).height < 700;
|
final compact = MediaQuery.sizeOf(context).height < 700;
|
||||||
return Positioned(
|
return Positioned(
|
||||||
right: AppDimens.spaceMd,
|
right: AppDimens.spaceMd,
|
||||||
top: MediaQuery.sizeOf(context).height * (compact ? 0.42 : 0.55),
|
top: MediaQuery.sizeOf(context).height * (compact ? 0.30 : 0.43),
|
||||||
child: InteractionRail(
|
child: InteractionRail(
|
||||||
key: const Key('player-interaction-rail'),
|
key: const Key('player-interaction-rail'),
|
||||||
items: [
|
items: [
|
||||||
InteractionRailItem(
|
InteractionRailItem(
|
||||||
key: const Key('player-rail-save'),
|
key: const Key('player-rail-save'),
|
||||||
icon: Icons.star_border_rounded,
|
icon: Icons.star_rounded,
|
||||||
activeIcon: Icons.star_rounded,
|
activeIcon: Icons.star_rounded,
|
||||||
label: data.l10n.favorite,
|
label: data.l10n.favorite,
|
||||||
count: data.favoriteCount,
|
count: data.favoriteCount,
|
||||||
@@ -166,7 +166,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
InteractionRailItem(
|
InteractionRailItem(
|
||||||
key: const Key('player-rail-like'),
|
key: const Key('player-rail-like'),
|
||||||
icon: Icons.favorite_border_rounded,
|
icon: Icons.favorite_rounded,
|
||||||
activeIcon: Icons.favorite_rounded,
|
activeIcon: Icons.favorite_rounded,
|
||||||
label: data.l10n.like,
|
label: data.l10n.like,
|
||||||
count: data.likeCount,
|
count: data.likeCount,
|
||||||
@@ -176,9 +176,10 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
InteractionRailItem(
|
InteractionRailItem(
|
||||||
key: const Key('player-rail-share'),
|
key: const Key('player-rail-share'),
|
||||||
icon: Icons.ios_share_rounded,
|
icon: Icons.reply_rounded,
|
||||||
activeIcon: Icons.ios_share_rounded,
|
activeIcon: Icons.reply_rounded,
|
||||||
label: data.l10n.share,
|
label: data.l10n.share,
|
||||||
|
mirrorIcon: true,
|
||||||
onTap: actions.onShare,
|
onTap: actions.onShare,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -150,6 +150,39 @@ void main() {
|
|||||||
tester.widget<Text>(find.byKey(const Key('rail-comments-count'))).data,
|
tester.widget<Text>(find.byKey(const Key('rail-comments-count'))).data,
|
||||||
'12',
|
'12',
|
||||||
);
|
);
|
||||||
|
expect(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('rail-save')),
|
||||||
|
matching: find.byIcon(Icons.star_rounded),
|
||||||
|
),
|
||||||
|
findsOneWidget,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('rail-like')),
|
||||||
|
matching: find.byIcon(Icons.favorite_rounded),
|
||||||
|
),
|
||||||
|
findsOneWidget,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('rail-share')),
|
||||||
|
matching: find.byIcon(Icons.reply_rounded),
|
||||||
|
),
|
||||||
|
findsOneWidget,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester
|
||||||
|
.widget<Transform>(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('rail-share')),
|
||||||
|
matching: find.byType(Transform),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.transform
|
||||||
|
.storage[0],
|
||||||
|
-1,
|
||||||
|
);
|
||||||
expect(find.byKey(const Key('progress-loading')), findsOneWidget);
|
expect(find.byKey(const Key('progress-loading')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('home-feed-progress-thumb')), findsNothing);
|
expect(find.byKey(const Key('home-feed-progress-thumb')), findsNothing);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -466,7 +466,7 @@ void main() {
|
|||||||
|
|
||||||
expect(bottom.height, lessThanOrEqualTo(200));
|
expect(bottom.height, lessThanOrEqualTo(200));
|
||||||
expect(bottom.top, greaterThanOrEqualTo(screenHeight * 0.78));
|
expect(bottom.top, greaterThanOrEqualTo(screenHeight * 0.78));
|
||||||
expect(rail.top, greaterThanOrEqualTo(screenHeight * 0.55 - 2));
|
expect(rail.top, greaterThanOrEqualTo(screenHeight * 0.40));
|
||||||
expect(rail.bottom, lessThanOrEqualTo(bottom.top));
|
expect(rail.bottom, lessThanOrEqualTo(bottom.top));
|
||||||
expect(find.byKey(const Key('player-author-note')), findsNothing);
|
expect(find.byKey(const Key('player-author-note')), findsNothing);
|
||||||
expect(
|
expect(
|
||||||
@@ -478,7 +478,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.width,
|
.width,
|
||||||
24,
|
30,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.tap(find.byKey(const Key('player-synopsis-toggle')));
|
await tester.tap(find.byKey(const Key('player-synopsis-toggle')));
|
||||||
@@ -580,6 +580,74 @@ void main() {
|
|||||||
expect(railLabel(const Key('player-rail-save')), '3201');
|
expect(railLabel(const Key('player-rail-save')), '3201');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('should_render_reference_rail_icons_without_background', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
|
await _pumpApp(tester);
|
||||||
|
await _openSeriesPlayer(tester);
|
||||||
|
|
||||||
|
Finder railIcon(Key key, IconData icon) =>
|
||||||
|
find.descendant(of: find.byKey(key), matching: find.byIcon(icon));
|
||||||
|
expect(
|
||||||
|
railIcon(const Key('player-rail-save'), Icons.star_rounded),
|
||||||
|
findsOneWidget,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
railIcon(const Key('player-rail-like'), Icons.favorite_rounded),
|
||||||
|
findsOneWidget,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
railIcon(
|
||||||
|
const Key('player-rail-comments'),
|
||||||
|
Icons.chat_bubble_outline_rounded,
|
||||||
|
),
|
||||||
|
findsOneWidget,
|
||||||
|
);
|
||||||
|
final shareIcon = railIcon(
|
||||||
|
const Key('player-rail-share'),
|
||||||
|
Icons.reply_rounded,
|
||||||
|
);
|
||||||
|
expect(shareIcon, findsOneWidget);
|
||||||
|
expect(tester.widget<Icon>(shareIcon).size, 30);
|
||||||
|
|
||||||
|
final mirror = tester.widget<Transform>(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('player-rail-share')),
|
||||||
|
matching: find.byType(Transform),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(mirror.transform.storage[0], -1);
|
||||||
|
|
||||||
|
final saveButton = tester.widget<IconButton>(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('player-rail-save')),
|
||||||
|
matching: find.byType(IconButton),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(saveButton.style?.backgroundColor, isNull);
|
||||||
|
expect(
|
||||||
|
tester.getSize(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('player-rail-save')),
|
||||||
|
matching: find.byType(IconButton),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Size(44, 44),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester
|
||||||
|
.widget<Text>(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('player-rail-like')),
|
||||||
|
matching: find.byType(Text),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.style
|
||||||
|
?.fontSize,
|
||||||
|
12,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('should_toggle_synopsis_with_inline_text_button', (tester) async {
|
testWidgets('should_toggle_synopsis_with_inline_text_button', (tester) async {
|
||||||
await _pumpApp(tester);
|
await _pumpApp(tester);
|
||||||
await _openSeriesPlayer(tester);
|
await _openSeriesPlayer(tester);
|
||||||
|
|||||||
Reference in new issue
Block a user