merge: 合并 K29.1 播放页视觉收紧
This commit is contained in:
commit
cc26c5472b
10 files changed
+167
-240
No files matched your search
@@ -592,9 +592,7 @@
|
||||
"unlockMethodsVary": "Available unlock methods vary by title.",
|
||||
"unlockEpisode": "Unlock this episode",
|
||||
"language": "Language",
|
||||
"fullScreenWatch": "Full screen",
|
||||
"freeWatch": "Free watch",
|
||||
"showMore": "More",
|
||||
"qualityUnavailable": "Unavailable",
|
||||
"notInterested": "Not interested",
|
||||
"clearPlayback": "Clear-screen playback",
|
||||
|
||||
@@ -590,9 +590,7 @@
|
||||
"unlockMethodsVary": "Metode pembukaan tersedia dapat berbeda per judul.",
|
||||
"unlockEpisode": "Buka episode ini",
|
||||
"language": "Bahasa",
|
||||
"fullScreenWatch": "Layar penuh",
|
||||
"freeWatch": "Tonton gratis",
|
||||
"showMore": "Selengkapnya",
|
||||
"qualityUnavailable": "Tidak tersedia",
|
||||
"notInterested": "Tidak tertarik",
|
||||
"clearPlayback": "Putar tanpa kontrol",
|
||||
|
||||
@@ -2638,24 +2638,12 @@ abstract class AppLocalizations {
|
||||
/// **'Language'**
|
||||
String get language;
|
||||
|
||||
/// No description provided for @fullScreenWatch.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Full screen'**
|
||||
String get fullScreenWatch;
|
||||
|
||||
/// No description provided for @freeWatch.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Free watch'**
|
||||
String get freeWatch;
|
||||
|
||||
/// No description provided for @showMore.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'More'**
|
||||
String get showMore;
|
||||
|
||||
/// No description provided for @qualityUnavailable.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
||||
@@ -1368,15 +1368,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
@override
|
||||
String get language => 'Language';
|
||||
|
||||
@override
|
||||
String get fullScreenWatch => 'Full screen';
|
||||
|
||||
@override
|
||||
String get freeWatch => 'Free watch';
|
||||
|
||||
@override
|
||||
String get showMore => 'More';
|
||||
|
||||
@override
|
||||
String get qualityUnavailable => 'Unavailable';
|
||||
|
||||
|
||||
@@ -1368,15 +1368,9 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
@override
|
||||
String get language => 'Bahasa';
|
||||
|
||||
@override
|
||||
String get fullScreenWatch => 'Layar penuh';
|
||||
|
||||
@override
|
||||
String get freeWatch => 'Tonton gratis';
|
||||
|
||||
@override
|
||||
String get showMore => 'Selengkapnya';
|
||||
|
||||
@override
|
||||
String get qualityUnavailable => 'Tidak tersedia';
|
||||
|
||||
|
||||
@@ -1344,15 +1344,9 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
@override
|
||||
String get language => '语言';
|
||||
|
||||
@override
|
||||
String get fullScreenWatch => '全屏观看';
|
||||
|
||||
@override
|
||||
String get freeWatch => '免费观看';
|
||||
|
||||
@override
|
||||
String get showMore => '展开';
|
||||
|
||||
@override
|
||||
String get qualityUnavailable => '暂不可用';
|
||||
|
||||
|
||||
@@ -552,9 +552,7 @@
|
||||
"unlockMethodsVary": "具体解锁方式以作品而定。",
|
||||
"unlockEpisode": "解锁本集",
|
||||
"language": "语言",
|
||||
"fullScreenWatch": "全屏观看",
|
||||
"freeWatch": "免费观看",
|
||||
"showMore": "展开",
|
||||
"qualityUnavailable": "暂不可用",
|
||||
"notInterested": "不感兴趣",
|
||||
"clearPlayback": "清屏播放",
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
import '../../../core/formatting/localized_content.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
@@ -14,11 +12,10 @@ import 'seek_progress_bar.dart';
|
||||
|
||||
part 'player_overlay_parts.dart';
|
||||
|
||||
const double _topBarHeight = 58;
|
||||
const double _topButtonSize = 36;
|
||||
const double _railButtonSize = 36;
|
||||
const double _railGap = 9;
|
||||
const double _fullScreenPillBottom = 246;
|
||||
const double _topBarHeight = 58;
|
||||
const double _railButtonSize = 34;
|
||||
const double _railGap = 18;
|
||||
const double _panelRadius = 16;
|
||||
|
||||
/// K29 竖屏播放页浮层。
|
||||
@@ -57,7 +54,6 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
_bottom(context),
|
||||
_rail(context),
|
||||
],
|
||||
_fullScreenPill(),
|
||||
if (!controlsVisible)
|
||||
Positioned(
|
||||
top: AppDimens.spaceSm,
|
||||
@@ -144,7 +140,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
final compact = MediaQuery.sizeOf(context).height < 700;
|
||||
return Positioned(
|
||||
right: AppDimens.spaceMd,
|
||||
top: _topBarHeight + (compact ? 18 : 54),
|
||||
top: MediaQuery.sizeOf(context).height * (compact ? 0.42 : 0.55),
|
||||
child: _Rail(
|
||||
l10n: data.l10n,
|
||||
liked: data.liked,
|
||||
@@ -156,7 +152,6 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
onComments: actions.onComments,
|
||||
onSave: actions.onSave,
|
||||
onShare: actions.onShare,
|
||||
compact: compact,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -170,7 +165,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
key: const Key('player-controls-bottom'),
|
||||
padding: const EdgeInsets.fromLTRB(14, 10, 14, 10),
|
||||
padding: const EdgeInsets.fromLTRB(14, 8, 14, 6),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xED000000),
|
||||
borderRadius: BorderRadius.vertical(
|
||||
@@ -182,27 +177,16 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_detailRow(series),
|
||||
const SizedBox(height: 6),
|
||||
const SizedBox(height: 4),
|
||||
_EpisodeSynopsis(
|
||||
key: const Key('player-episode-synopsis'),
|
||||
l10n: data.l10n,
|
||||
episodeNumber: data.episode.number,
|
||||
synopsis: synopsis,
|
||||
authorNote: data.authorNote,
|
||||
textScale: data.textScale,
|
||||
),
|
||||
if (data.authorNote.isNotEmpty) ...[
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
data.authorNote,
|
||||
key: const Key('player-author-note'),
|
||||
style: const TextStyle(color: Colors.white60, fontSize: 11),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 6),
|
||||
_PlayerTimeLabel(
|
||||
key: const Key('player-time-label'),
|
||||
controller: data.controller,
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
SeekProgressBar(
|
||||
key: const Key('player-progress'),
|
||||
valueListenable: data.controller,
|
||||
@@ -226,7 +210,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
key: const Key('player-open-detail'),
|
||||
onTap: actions.onDetail,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
padding: const EdgeInsets.symmetric(vertical: 1),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
@@ -238,7 +222,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
color: AppColors.onPrimary,
|
||||
fontFamily: 'Outfit',
|
||||
fontSize: 19 * data.textScale,
|
||||
fontSize: 18 * data.textScale,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
@@ -267,7 +251,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
onTap: actions.onEpisodes,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
@@ -288,7 +272,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
const Icon(
|
||||
Icons.keyboard_arrow_up_rounded,
|
||||
color: AppColors.onPrimary,
|
||||
size: 18,
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -298,57 +282,13 @@ class PlayerPlaybackOverlay extends StatelessWidget {
|
||||
),
|
||||
if (actions.onPip != null) ...[
|
||||
const SizedBox(width: 8),
|
||||
_TopButton(
|
||||
_PipButton(
|
||||
key: const Key('player-pip'),
|
||||
tooltip: data.l10n.pictureInPicture,
|
||||
icon: Icons.picture_in_picture_alt_rounded,
|
||||
onPressed: actions.onPip!,
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _fullScreenPill() {
|
||||
return Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: _fullScreenPillBottom,
|
||||
child: Center(
|
||||
child: Material(
|
||||
color: const Color(0x99000000),
|
||||
borderRadius: BorderRadius.circular(999),
|
||||
child: InkWell(
|
||||
key: const Key('player-fullscreen-toggle'),
|
||||
borderRadius: BorderRadius.circular(999),
|
||||
onTap: controlsVisible ? actions.onClear : actions.onExitClear,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 7),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.fullscreen_rounded,
|
||||
color: AppColors.onPrimary,
|
||||
size: 16,
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
controlsVisible
|
||||
? data.l10n.fullScreenWatch
|
||||
: data.l10n.exitClearScreen,
|
||||
style: const TextStyle(
|
||||
color: AppColors.onPrimary,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,30 @@ class _SpeedEntry extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _PipButton extends StatelessWidget {
|
||||
const _PipButton({super.key, required this.tooltip, required this.onPressed});
|
||||
|
||||
final String tooltip;
|
||||
final VoidCallback onPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox.square(
|
||||
dimension: 30,
|
||||
child: IconButton(
|
||||
tooltip: tooltip,
|
||||
padding: EdgeInsets.zero,
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: const Color(0x80000000),
|
||||
foregroundColor: AppColors.onPrimary,
|
||||
),
|
||||
onPressed: onPressed,
|
||||
icon: const Icon(Icons.picture_in_picture_alt_rounded, size: 17),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Rail extends StatelessWidget {
|
||||
const _Rail({
|
||||
required this.l10n,
|
||||
@@ -85,7 +109,6 @@ class _Rail extends StatelessWidget {
|
||||
required this.onComments,
|
||||
required this.onSave,
|
||||
required this.onShare,
|
||||
required this.compact,
|
||||
});
|
||||
|
||||
final AppLocalizations l10n;
|
||||
@@ -98,7 +121,6 @@ class _Rail extends StatelessWidget {
|
||||
final VoidCallback onComments;
|
||||
final VoidCallback onSave;
|
||||
final VoidCallback onShare;
|
||||
final bool compact;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -111,29 +133,28 @@ class _Rail extends StatelessWidget {
|
||||
label: favoriteCount?.toString() ?? l10n.favorite,
|
||||
active: saved,
|
||||
onTap: onSave,
|
||||
compact: compact,
|
||||
),
|
||||
const SizedBox(height: _railGap),
|
||||
_RailButton(
|
||||
key: const Key('player-rail-comments'),
|
||||
icon: Icons.chat_bubble_outline_rounded,
|
||||
label: commentCount?.toString() ?? l10n.comments,
|
||||
onTap: onComments,
|
||||
compact: compact,
|
||||
),
|
||||
const SizedBox(height: _railGap),
|
||||
_RailButton(
|
||||
key: const Key('player-rail-like'),
|
||||
icon: liked ? Icons.favorite_rounded : Icons.favorite_border_rounded,
|
||||
label: likeCount?.toString() ?? l10n.like,
|
||||
active: liked,
|
||||
onTap: onLike,
|
||||
compact: compact,
|
||||
),
|
||||
const SizedBox(height: _railGap),
|
||||
_RailButton(
|
||||
key: const Key('player-rail-share'),
|
||||
icon: Icons.ios_share_rounded,
|
||||
label: l10n.share,
|
||||
onTap: onShare,
|
||||
compact: compact,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -146,46 +167,41 @@ class _RailButton extends StatelessWidget {
|
||||
required this.icon,
|
||||
required this.label,
|
||||
required this.onTap,
|
||||
required this.compact,
|
||||
this.active = false,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final VoidCallback onTap;
|
||||
final bool compact;
|
||||
final bool active;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: compact ? 3 : _railGap),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox.square(
|
||||
dimension: _railButtonSize,
|
||||
child: IconButton(
|
||||
onPressed: onTap,
|
||||
padding: EdgeInsets.zero,
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: const Color(0x80000000),
|
||||
foregroundColor: active ? AppColors.blue : AppColors.onPrimary,
|
||||
),
|
||||
icon: Icon(icon, size: 18),
|
||||
return Column(
|
||||
children: [
|
||||
SizedBox.square(
|
||||
dimension: _railButtonSize,
|
||||
child: IconButton(
|
||||
onPressed: onTap,
|
||||
padding: EdgeInsets.zero,
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: const Color(0x80000000),
|
||||
foregroundColor: active ? AppColors.blue : AppColors.onPrimary,
|
||||
),
|
||||
icon: Icon(icon, size: 24),
|
||||
),
|
||||
SizedBox(height: compact ? 1 : 3),
|
||||
Text(
|
||||
label,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
color: AppColors.onPrimary,
|
||||
fontSize: compact ? 8 : 9,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
label,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
color: AppColors.onPrimary,
|
||||
fontSize: 11,
|
||||
height: 1,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -196,12 +212,14 @@ class _EpisodeSynopsis extends StatefulWidget {
|
||||
required this.l10n,
|
||||
required this.episodeNumber,
|
||||
required this.synopsis,
|
||||
required this.authorNote,
|
||||
required this.textScale,
|
||||
});
|
||||
|
||||
final AppLocalizations l10n;
|
||||
final int episodeNumber;
|
||||
final String synopsis;
|
||||
final String authorNote;
|
||||
final double textScale;
|
||||
|
||||
@override
|
||||
@@ -213,92 +231,64 @@ class _EpisodeSynopsisState extends State<_EpisodeSynopsis> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final canExpand = widget.synopsis.trim().length > 28;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
key: const Key('player-synopsis-toggle'),
|
||||
onTap: () => setState(() => _expanded = !_expanded),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
widget.l10n.episodeLabel(widget.episodeNumber),
|
||||
key: const Key('player-episode-label'),
|
||||
style: TextStyle(
|
||||
color: AppColors.blue,
|
||||
fontSize: 11 * widget.textScale,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 6),
|
||||
child: Text('|', style: TextStyle(color: Colors.white38)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.synopsis,
|
||||
key: const Key('player-synopsis'),
|
||||
maxLines: _expanded ? 4 : 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: Colors.white70,
|
||||
fontSize: 11 * widget.textScale,
|
||||
height: 1.45,
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
widget.l10n.episodeLabel(widget.episodeNumber),
|
||||
key: const Key('player-episode-label'),
|
||||
style: TextStyle(
|
||||
color: AppColors.blue,
|
||||
fontSize: 11 * widget.textScale,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 6),
|
||||
child: Text('|', style: TextStyle(color: Colors.white38)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.synopsis,
|
||||
key: const Key('player-synopsis'),
|
||||
maxLines: _expanded ? 3 : 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: Colors.white70,
|
||||
fontSize: 11 * widget.textScale,
|
||||
height: 1.35,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Icon(
|
||||
_expanded
|
||||
? Icons.keyboard_arrow_up_rounded
|
||||
: Icons.keyboard_arrow_down_rounded,
|
||||
color: Colors.white54,
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
if (_expanded && widget.authorNote.isNotEmpty) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
widget.authorNote,
|
||||
key: const Key('player-author-note'),
|
||||
style: const TextStyle(color: Colors.white54, fontSize: 10),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (canExpand)
|
||||
GestureDetector(
|
||||
key: const Key('player-synopsis-toggle'),
|
||||
onTap: () => setState(() => _expanded = !_expanded),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 2),
|
||||
child: Text(
|
||||
_expanded ? widget.l10n.showLess : widget.l10n.showMore,
|
||||
style: const TextStyle(
|
||||
color: Colors.white54,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PlayerTimeLabel extends StatelessWidget {
|
||||
const _PlayerTimeLabel({super.key, required this.controller});
|
||||
|
||||
final VideoPlayerController? controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final source = controller;
|
||||
if (source == null) return _label(Duration.zero, Duration.zero);
|
||||
return ValueListenableBuilder<VideoPlayerValue>(
|
||||
valueListenable: source,
|
||||
builder: (context, value, _) => _label(value.position, value.duration),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _label(Duration position, Duration duration) => Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${_format(position)} / ${_format(duration)}',
|
||||
style: const TextStyle(
|
||||
color: Colors.white60,
|
||||
fontSize: 9,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
String _format(Duration value) {
|
||||
final minutes = value.inMinutes.remainder(60).toString().padLeft(2, '0');
|
||||
final seconds = value.inSeconds.remainder(60).toString().padLeft(2, '0');
|
||||
return '$minutes:$seconds';
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ void main() {
|
||||
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
|
||||
expect(find.byType(PlayerCenterToggle), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byKey(const Key('player-fullscreen-toggle')));
|
||||
await _clearFromMore(tester);
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byKey(const Key('player-controls-top')), findsNothing);
|
||||
@@ -173,13 +173,53 @@ void main() {
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('should_keep_compact_bottom_panel_and_lower_rail', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpApp(tester);
|
||||
await _openSeriesPlayer(tester);
|
||||
|
||||
final screenHeight = tester.view.physicalSize.height;
|
||||
final bottom = tester.getRect(
|
||||
find.byKey(const Key('player-controls-bottom')),
|
||||
);
|
||||
final rail = tester.getRect(
|
||||
find.byKey(const Key('player-interaction-rail')),
|
||||
);
|
||||
|
||||
expect(bottom.height, lessThanOrEqualTo(200));
|
||||
expect(bottom.top, greaterThanOrEqualTo(screenHeight * 0.78));
|
||||
expect(rail.top, greaterThanOrEqualTo(screenHeight * 0.55 - 2));
|
||||
expect(rail.bottom, lessThanOrEqualTo(bottom.top));
|
||||
expect(find.byKey(const Key('player-author-note')), findsNothing);
|
||||
expect(
|
||||
tester
|
||||
.getSize(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('player-rail-comments')),
|
||||
matching: find.byIcon(Icons.chat_bubble_outline_rounded),
|
||||
),
|
||||
)
|
||||
.width,
|
||||
24,
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(const Key('player-synopsis-toggle')));
|
||||
await tester.pumpAndSettle();
|
||||
final expandedBottom = tester.getRect(
|
||||
find.byKey(const Key('player-controls-bottom')),
|
||||
);
|
||||
expect(expandedBottom.height, lessThanOrEqualTo(200));
|
||||
expect(expandedBottom.top, greaterThanOrEqualTo(screenHeight * 0.78));
|
||||
});
|
||||
|
||||
testWidgets('should_keep_series_clear_state_when_swiping_next_episode', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpApp(tester);
|
||||
await _openSeriesPlayer(tester);
|
||||
|
||||
await tester.tap(find.byKey(const Key('player-fullscreen-toggle')));
|
||||
await _clearFromMore(tester);
|
||||
await tester.pump();
|
||||
expect(find.byKey(const Key('player-controls-top')), findsNothing);
|
||||
|
||||
@@ -237,7 +277,7 @@ void main() {
|
||||
await tester.tap(find.byKey(const Key('player-speed-1.5')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byKey(const Key('player-fullscreen-toggle')));
|
||||
await _clearFromMore(tester);
|
||||
await tester.pump();
|
||||
expect(find.byKey(const Key('player-more')), findsNothing);
|
||||
|
||||
@@ -383,19 +423,6 @@ void main() {
|
||||
expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_toggle_fullscreen_from_the_same_pill', (tester) async {
|
||||
await _pumpApp(tester);
|
||||
await _openSeriesPlayer(tester);
|
||||
await tester.tap(find.byKey(const Key('player-fullscreen-toggle')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('player-controls-top')), findsNothing);
|
||||
|
||||
await tester.tap(find.byKey(const Key('player-fullscreen-toggle')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_open_unlock_panel_with_honest_method_states', (
|
||||
tester,
|
||||
) async {
|
||||
@@ -434,7 +461,6 @@ void _expectFullscreenOverlay(WidgetTester tester) {
|
||||
expect(find.byKey(const Key('player-drama-title')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-episode-label')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-synopsis')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-time-label')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-more')), findsOneWidget);
|
||||
for (final key in const [Key('player-back'), Key('player-more')]) {
|
||||
expect(tester.getSize(find.byKey(key)), const Size(36, 36));
|
||||
@@ -442,7 +468,7 @@ void _expectFullscreenOverlay(WidgetTester tester) {
|
||||
expect(find.byKey(const Key('player-play-toggle')), findsNothing);
|
||||
expect(find.byKey(const Key('player-episodes')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-rail-comments')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-fullscreen-toggle')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-fullscreen-toggle')), findsNothing);
|
||||
expect(find.byType(Slider), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-title')), findsNothing);
|
||||
expect(find.byKey(const Key('player-subtitle')), findsNothing);
|
||||
@@ -457,6 +483,13 @@ void _expectFullscreenOverlay(WidgetTester tester) {
|
||||
expect(find.byKey(const Key('player-rail-share')), findsOneWidget);
|
||||
}
|
||||
|
||||
Future<void> _clearFromMore(WidgetTester tester) async {
|
||||
await tester.tap(find.byKey(const Key('player-more')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('player-more-clear')));
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> _openSeriesPlayer(
|
||||
WidgetTester tester, {
|
||||
Key cardKey = const Key('home-drama-card-city-lights-demo'),
|
||||
|
||||
Reference in new issue
Block a user