feat(player): 更多面板按参考图重做
This commit is contained in:
1 parent
c06a67c4b0
commit
7fccd16750
3 files changed
+260
-131
No files matched your search
@@ -6,12 +6,21 @@ import '../../../core/theme/app_colors.dart';
|
|||||||
import '../../../l10n/app_localizations.dart';
|
import '../../../l10n/app_localizations.dart';
|
||||||
|
|
||||||
const double _sheetRadius = 20;
|
const double _sheetRadius = 20;
|
||||||
const double _rowHeight = 44;
|
const double _rowHeight = 56;
|
||||||
const double _groupGap = 12;
|
const double _groupGap = 12;
|
||||||
const double _segmentHeight = 28;
|
const double _groupVerticalPadding = 6;
|
||||||
|
const double _groupRadius = 16;
|
||||||
|
const double _rowHorizontalPadding = 14;
|
||||||
|
const double _rowIconSize = 22;
|
||||||
|
const double _rowIconGap = 14;
|
||||||
|
const double _rowLabelSize = 16;
|
||||||
|
const double _rowChevronGap = 10;
|
||||||
|
const double _segmentTrackHeight = 34;
|
||||||
|
const double _segmentHeight = 26;
|
||||||
const double _segmentRadius = 8;
|
const double _segmentRadius = 8;
|
||||||
|
const double _segmentTrackRadius = 10;
|
||||||
|
const double _segmentTrackPadding = 4;
|
||||||
const double _segmentPadding = 10;
|
const double _segmentPadding = 10;
|
||||||
const double _segmentGap = 6;
|
|
||||||
const List<double> _speedOptions = [0.75, 1.0, 1.25, 1.5, 2.0, 3.0];
|
const List<double> _speedOptions = [0.75, 1.0, 1.25, 1.5, 2.0, 3.0];
|
||||||
const List<String> _qualityOptions = ['AUTO', '720P', '1080P'];
|
const List<String> _qualityOptions = ['AUTO', '720P', '1080P'];
|
||||||
const String _autoQuality = 'AUTO';
|
const String _autoQuality = 'AUTO';
|
||||||
@@ -82,7 +91,7 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
|||||||
final l10n = widget.l10n;
|
final l10n = widget.l10n;
|
||||||
return Material(
|
return Material(
|
||||||
key: const Key('player-more-sheet'),
|
key: const Key('player-more-sheet'),
|
||||||
color: AppColors.card,
|
color: AppColors.ink,
|
||||||
borderRadius: const BorderRadius.vertical(
|
borderRadius: const BorderRadius.vertical(
|
||||||
top: Radius.circular(_sheetRadius),
|
top: Radius.circular(_sheetRadius),
|
||||||
),
|
),
|
||||||
@@ -90,7 +99,7 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
|||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
top: false,
|
top: false,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 20),
|
padding: const EdgeInsets.fromLTRB(12, 8, 12, 16),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@@ -105,31 +114,30 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 12),
|
||||||
_header(l10n),
|
_group([_speedPicker(), _qualityPicker(l10n)]),
|
||||||
_speedPicker(),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
_qualityPicker(l10n),
|
|
||||||
const SizedBox(height: _groupGap),
|
const SizedBox(height: _groupGap),
|
||||||
_actionRow(
|
_group([
|
||||||
key: const Key('player-more-clear'),
|
|
||||||
icon: Icons.fullscreen_rounded,
|
|
||||||
title: l10n.clearPlayback,
|
|
||||||
onTap: _clear,
|
|
||||||
),
|
|
||||||
if (widget.actions.onPip != null)
|
|
||||||
_actionRow(
|
_actionRow(
|
||||||
key: const Key('player-more-pip'),
|
key: const Key('player-more-clear'),
|
||||||
icon: Icons.picture_in_picture_alt_rounded,
|
icon: Icons.fullscreen,
|
||||||
title: l10n.pictureInPicture,
|
title: l10n.clearPlayback,
|
||||||
onTap: () => _closeThen(widget.actions.onPip!),
|
onTap: _clear,
|
||||||
),
|
),
|
||||||
_actionRow(
|
if (widget.actions.onPip != null)
|
||||||
key: const Key('player-more-offline'),
|
_actionRow(
|
||||||
icon: Icons.download_rounded,
|
key: const Key('player-more-pip'),
|
||||||
title: l10n.offlineCache,
|
icon: Icons.picture_in_picture_alt_outlined,
|
||||||
onTap: () => _closeThen(widget.actions.onDownload),
|
title: l10n.pictureInPicture,
|
||||||
),
|
onTap: () => _closeThen(widget.actions.onPip!),
|
||||||
|
),
|
||||||
|
_actionRow(
|
||||||
|
key: const Key('player-more-offline'),
|
||||||
|
icon: Icons.download_outlined,
|
||||||
|
title: l10n.offlineCache,
|
||||||
|
onTap: () => _closeThen(widget.actions.onDownload),
|
||||||
|
),
|
||||||
|
]),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -137,35 +145,21 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _header(AppLocalizations l10n) => Row(
|
Widget _group(List<Widget> rows) => Container(
|
||||||
children: [
|
width: double.infinity,
|
||||||
Expanded(
|
padding: const EdgeInsets.symmetric(vertical: _groupVerticalPadding),
|
||||||
child: Text(
|
decoration: BoxDecoration(
|
||||||
l10n.more,
|
color: AppColors.card,
|
||||||
style: const TextStyle(
|
borderRadius: BorderRadius.circular(_groupRadius),
|
||||||
color: AppColors.onSurface,
|
),
|
||||||
fontSize: 15,
|
child: Column(mainAxisSize: MainAxisSize.min, children: rows),
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox.square(
|
|
||||||
dimension: 32,
|
|
||||||
child: IconButton(
|
|
||||||
key: const Key('player-more-close'),
|
|
||||||
tooltip: l10n.close,
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
icon: const Icon(Icons.close_rounded, size: 18),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _speedPicker() => _optionRow(
|
Widget _speedPicker() => _optionRow(
|
||||||
rowKey: const Key('player-more-speed-row'),
|
rowKey: const Key('player-more-speed-row'),
|
||||||
optionsKey: const Key('player-more-speed'),
|
optionsKey: const Key('player-more-speed'),
|
||||||
icon: Icons.speed_rounded,
|
trackKey: const Key('player-more-speed-track'),
|
||||||
|
icon: Icons.speed_outlined,
|
||||||
title: widget.l10n.playbackSpeed,
|
title: widget.l10n.playbackSpeed,
|
||||||
options: [
|
options: [
|
||||||
for (final value in _speedOptions)
|
for (final value in _speedOptions)
|
||||||
@@ -184,7 +178,8 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
|||||||
Widget _qualityPicker(AppLocalizations l10n) => _optionRow(
|
Widget _qualityPicker(AppLocalizations l10n) => _optionRow(
|
||||||
rowKey: const Key('player-more-quality-row'),
|
rowKey: const Key('player-more-quality-row'),
|
||||||
optionsKey: const Key('player-more-quality'),
|
optionsKey: const Key('player-more-quality'),
|
||||||
icon: Icons.high_quality_rounded,
|
trackKey: const Key('player-more-quality-track'),
|
||||||
|
icon: Icons.high_quality_outlined,
|
||||||
title: l10n.playbackQuality,
|
title: l10n.playbackQuality,
|
||||||
options: [
|
options: [
|
||||||
for (final quality in _qualityOptions) _qualitySegment(l10n, quality),
|
for (final quality in _qualityOptions) _qualitySegment(l10n, quality),
|
||||||
@@ -194,6 +189,7 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
|||||||
Widget _optionRow({
|
Widget _optionRow({
|
||||||
required Key rowKey,
|
required Key rowKey,
|
||||||
required Key optionsKey,
|
required Key optionsKey,
|
||||||
|
required Key trackKey,
|
||||||
required IconData icon,
|
required IconData icon,
|
||||||
required String title,
|
required String title,
|
||||||
required List<Widget> options,
|
required List<Widget> options,
|
||||||
@@ -201,45 +197,52 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
key: rowKey,
|
key: rowKey,
|
||||||
height: _rowHeight,
|
height: _rowHeight,
|
||||||
child: Row(
|
child: Padding(
|
||||||
children: [
|
padding: const EdgeInsets.symmetric(horizontal: _rowHorizontalPadding),
|
||||||
SizedBox(
|
child: Row(
|
||||||
width: 88,
|
children: [
|
||||||
child: Row(
|
Icon(icon, color: AppColors.onSurface, size: _rowIconSize),
|
||||||
children: [
|
const SizedBox(width: _rowIconGap),
|
||||||
Icon(icon, color: AppColors.muted, size: 18),
|
Expanded(
|
||||||
const SizedBox(width: 6),
|
child: Text(
|
||||||
Expanded(
|
title,
|
||||||
child: Text(
|
maxLines: 1,
|
||||||
title,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 1,
|
style: const TextStyle(
|
||||||
overflow: TextOverflow.ellipsis,
|
color: AppColors.onSurface,
|
||||||
style: const TextStyle(
|
fontSize: _rowLabelSize,
|
||||||
color: AppColors.onSurface,
|
fontWeight: FontWeight.w600,
|
||||||
fontSize: 12,
|
),
|
||||||
fontWeight: FontWeight.w600,
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: _rowChevronGap),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
key: optionsKey,
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Container(
|
||||||
|
key: trackKey,
|
||||||
|
height: _segmentTrackHeight,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: _segmentTrackPadding,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.raised,
|
||||||
|
borderRadius: BorderRadius.circular(_segmentTrackRadius),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: options,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
Expanded(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
key: optionsKey,
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
for (var index = 0; index < options.length; index++) ...[
|
|
||||||
if (index > 0) const SizedBox(width: _segmentGap),
|
|
||||||
options[index],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -275,26 +278,34 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
|||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: _rowHeight,
|
height: _rowHeight,
|
||||||
child: Row(
|
child: Padding(
|
||||||
children: [
|
padding: const EdgeInsets.symmetric(
|
||||||
Icon(icon, color: AppColors.muted, size: 20),
|
horizontal: _rowHorizontalPadding,
|
||||||
const SizedBox(width: 12),
|
),
|
||||||
Expanded(
|
child: Row(
|
||||||
child: Text(
|
children: [
|
||||||
title,
|
Icon(icon, color: AppColors.onSurface, size: _rowIconSize),
|
||||||
style: const TextStyle(
|
const SizedBox(width: _rowIconGap),
|
||||||
color: AppColors.onSurface,
|
Expanded(
|
||||||
fontSize: 14,
|
child: Text(
|
||||||
fontWeight: FontWeight.w600,
|
title,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: AppColors.onSurface,
|
||||||
|
fontSize: _rowLabelSize,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: _rowChevronGap),
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.chevron_right_rounded,
|
Icons.chevron_right_rounded,
|
||||||
color: AppColors.subtle,
|
color: AppColors.subtle,
|
||||||
size: 18,
|
size: _rowIconSize,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -330,36 +341,41 @@ class _SegmentButton extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final background = selected
|
|
||||||
? AppColors.blue
|
|
||||||
: enabled
|
|
||||||
? AppColors.raised
|
|
||||||
: AppColors.cardAlt;
|
|
||||||
final foreground = selected
|
final foreground = selected
|
||||||
? AppColors.onPrimary
|
|
||||||
: enabled
|
|
||||||
? AppColors.onSurface
|
? AppColors.onSurface
|
||||||
|
: enabled
|
||||||
|
? AppColors.muted
|
||||||
: AppColors.subtle;
|
: AppColors.subtle;
|
||||||
return Material(
|
return Material(
|
||||||
color: background,
|
color: Colors.transparent,
|
||||||
borderRadius: BorderRadius.circular(_segmentRadius),
|
borderRadius: BorderRadius.circular(_segmentRadius),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
borderRadius: BorderRadius.circular(_segmentRadius),
|
borderRadius: BorderRadius.circular(_segmentRadius),
|
||||||
child: SizedBox(
|
child: Container(
|
||||||
height: _segmentHeight,
|
height: _segmentHeight,
|
||||||
child: Padding(
|
padding: const EdgeInsets.symmetric(horizontal: _segmentPadding),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: _segmentPadding),
|
alignment: Alignment.center,
|
||||||
child: Center(
|
decoration: BoxDecoration(
|
||||||
child: Text(
|
color: selected ? AppColors.card : Colors.transparent,
|
||||||
label,
|
borderRadius: BorderRadius.circular(_segmentRadius),
|
||||||
maxLines: 1,
|
boxShadow: selected
|
||||||
style: TextStyle(
|
? const [
|
||||||
color: foreground,
|
BoxShadow(
|
||||||
fontSize: 12,
|
color: Color(0x14000000),
|
||||||
fontWeight: selected ? FontWeight.w700 : FontWeight.w500,
|
blurRadius: 4,
|
||||||
),
|
offset: Offset(0, 1),
|
||||||
),
|
),
|
||||||
|
]
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
maxLines: 1,
|
||||||
|
style: TextStyle(
|
||||||
|
color: foreground,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: selected ? FontWeight.w700 : FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(find.byKey(const Key('player-more-quality-AUTO')), findsOneWidget);
|
expect(find.byKey(const Key('player-more-quality-AUTO')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('player-more-offline')), findsOneWidget);
|
expect(find.byKey(const Key('player-more-offline')), findsOneWidget);
|
||||||
await tester.tap(find.byKey(const Key('player-more-close')));
|
await tester.tapAt(const Offset(10, 10));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(tester.takeException(), isNull);
|
expect(tester.takeException(), isNull);
|
||||||
});
|
});
|
||||||
@@ -290,7 +290,7 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(find.byKey(const Key('player-more-sheet')), findsOneWidget);
|
expect(find.byKey(const Key('player-more-sheet')), findsOneWidget);
|
||||||
await tester.tap(find.byKey(const Key('player-more-close')));
|
await tester.tapAt(const Offset(10, 10));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
// 长按弹更多不改播放状态,仍处于播放中。
|
// 长按弹更多不改播放状态,仍处于播放中。
|
||||||
expect(find.byKey(const Key('player-play-toggle')), findsNothing);
|
expect(find.byKey(const Key('player-play-toggle')), findsNothing);
|
||||||
@@ -832,6 +832,7 @@ void main() {
|
|||||||
expect(find.byKey(const Key('player-more-offline')), findsOneWidget);
|
expect(find.byKey(const Key('player-more-offline')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('player-more-clear')), findsOneWidget);
|
expect(find.byKey(const Key('player-more-clear')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('player-more-drag-handle')), findsOneWidget);
|
expect(find.byKey(const Key('player-more-drag-handle')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('player-more-close')), findsNothing);
|
||||||
for (final removed in const [
|
for (final removed in const [
|
||||||
Key('player-more-not-interested'),
|
Key('player-more-not-interested'),
|
||||||
Key('player-more-danmaku'),
|
Key('player-more-danmaku'),
|
||||||
@@ -845,15 +846,27 @@ void main() {
|
|||||||
}
|
}
|
||||||
expect(
|
expect(
|
||||||
tester.getSize(find.byKey(const Key('player-more-speed-1.0'))).height,
|
tester.getSize(find.byKey(const Key('player-more-speed-1.0'))).height,
|
||||||
28,
|
26,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester.getSize(find.byKey(const Key('player-more-speed-track'))).height,
|
||||||
|
34,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.getSize(find.byKey(const Key('player-more-speed-row'))).height,
|
tester.getSize(find.byKey(const Key('player-more-speed-row'))).height,
|
||||||
44,
|
56,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.getSize(find.byKey(const Key('player-more-quality-row'))).height,
|
tester.getSize(find.byKey(const Key('player-more-quality-row'))).height,
|
||||||
44,
|
56,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester.getSize(find.byKey(const Key('player-more-clear'))).height,
|
||||||
|
56,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester.getSize(find.byKey(const Key('player-more-offline'))).height,
|
||||||
|
56,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester
|
tester
|
||||||
@@ -881,7 +894,7 @@ void main() {
|
|||||||
)
|
)
|
||||||
.style
|
.style
|
||||||
?.fontSize,
|
?.fontSize,
|
||||||
12,
|
14,
|
||||||
);
|
);
|
||||||
await tester.ensureVisible(find.byKey(const Key('player-more-speed-1.5')));
|
await tester.ensureVisible(find.byKey(const Key('player-more-speed-1.5')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import 'package:fruitshorts/core/theme/app_colors.dart';
|
||||||
import 'package:fruitshorts/l10n/app_localizations.dart';
|
import 'package:fruitshorts/l10n/app_localizations.dart';
|
||||||
import 'package:fruitshorts/pages/player/widgets/player_more_sheet.dart';
|
import 'package:fruitshorts/pages/player/widgets/player_more_sheet.dart';
|
||||||
|
|
||||||
@@ -14,6 +15,105 @@ void main() {
|
|||||||
expect(find.byKey(const Key('player-more-clear')), findsOneWidget);
|
expect(find.byKey(const Key('player-more-clear')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('player-more-offline')), findsOneWidget);
|
expect(find.byKey(const Key('player-more-offline')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('player-more-pip')), findsNothing);
|
expect(find.byKey(const Key('player-more-pip')), findsNothing);
|
||||||
|
expect(find.byKey(const Key('player-more-close')), findsNothing);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('should_render_reference_layout_metrics', (tester) async {
|
||||||
|
await _openSheet(tester);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
tester.widget<Material>(find.byKey(const Key('player-more-sheet'))).color,
|
||||||
|
AppColors.ink,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester.getSize(find.byKey(const Key('player-more-drag-handle'))),
|
||||||
|
const Size(36, 4),
|
||||||
|
);
|
||||||
|
for (final key in const [
|
||||||
|
Key('player-more-speed-row'),
|
||||||
|
Key('player-more-quality-row'),
|
||||||
|
Key('player-more-clear'),
|
||||||
|
Key('player-more-offline'),
|
||||||
|
]) {
|
||||||
|
expect(tester.getSize(find.byKey(key)).height, 56);
|
||||||
|
}
|
||||||
|
for (final key in const [
|
||||||
|
Key('player-more-speed-track'),
|
||||||
|
Key('player-more-quality-track'),
|
||||||
|
]) {
|
||||||
|
expect(tester.getSize(find.byKey(key)).height, 34);
|
||||||
|
final trackDecoration =
|
||||||
|
tester.widget<Container>(find.byKey(key)).decoration!
|
||||||
|
as BoxDecoration;
|
||||||
|
expect(trackDecoration.color, AppColors.raised);
|
||||||
|
}
|
||||||
|
for (final key in const [
|
||||||
|
Key('player-more-speed-0.75'),
|
||||||
|
Key('player-more-speed-1.0'),
|
||||||
|
Key('player-more-speed-1.25'),
|
||||||
|
]) {
|
||||||
|
expect(tester.getSize(find.byKey(key)).height, 26);
|
||||||
|
}
|
||||||
|
|
||||||
|
final speedLabel = tester.widget<Text>(
|
||||||
|
find
|
||||||
|
.descendant(
|
||||||
|
of: find.byKey(const Key('player-more-speed-row')),
|
||||||
|
matching: find.byType(Text),
|
||||||
|
)
|
||||||
|
.first,
|
||||||
|
);
|
||||||
|
expect(speedLabel.style?.fontSize, 16);
|
||||||
|
expect(speedLabel.style?.fontWeight, FontWeight.w600);
|
||||||
|
expect(tester.widget<Icon>(find.byIcon(Icons.speed_outlined)).size, 22);
|
||||||
|
expect(tester.widget<Icon>(find.byIcon(Icons.fullscreen)).size, 22);
|
||||||
|
|
||||||
|
final selected = tester.widget<Container>(
|
||||||
|
find
|
||||||
|
.descendant(
|
||||||
|
of: find.byKey(const Key('player-more-speed-1.0')),
|
||||||
|
matching: find.byType(Container),
|
||||||
|
)
|
||||||
|
.first,
|
||||||
|
);
|
||||||
|
final selectedDecoration = selected.decoration! as BoxDecoration;
|
||||||
|
expect(selectedDecoration.color, AppColors.card);
|
||||||
|
expect(selectedDecoration.boxShadow, isNotEmpty);
|
||||||
|
final selectedText = tester.widget<Text>(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('player-more-speed-1.0')),
|
||||||
|
matching: find.text('1.0x'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(selectedText.style?.color, AppColors.onSurface);
|
||||||
|
expect(selectedText.style?.fontWeight, FontWeight.w700);
|
||||||
|
|
||||||
|
final unselected = tester.widget<Container>(
|
||||||
|
find
|
||||||
|
.descendant(
|
||||||
|
of: find.byKey(const Key('player-more-speed-1.25')),
|
||||||
|
matching: find.byType(Container),
|
||||||
|
)
|
||||||
|
.first,
|
||||||
|
);
|
||||||
|
final unselectedDecoration = unselected.decoration! as BoxDecoration;
|
||||||
|
expect(unselectedDecoration.color, Colors.transparent);
|
||||||
|
final unselectedText = tester.widget<Text>(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('player-more-speed-1.25')),
|
||||||
|
matching: find.text('1.25x'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(unselectedText.style?.color, AppColors.muted);
|
||||||
|
expect(unselectedText.style?.fontWeight, FontWeight.w500);
|
||||||
|
|
||||||
|
final disabledText = tester.widget<Text>(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byKey(const Key('player-more-quality-720P')),
|
||||||
|
matching: find.byType(Text),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(disabledText.style?.color, AppColors.subtle);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_trigger_pip_and_close_sheet_when_tapped', (tester) async {
|
testWidgets('should_trigger_pip_and_close_sheet_when_tapped', (tester) async {
|
||||||
|
|||||||
Reference in new issue
Block a user