merge: 改为显式清屏交互
This commit is contained in:
commit
60ec19f08d
12 files changed
+158
-166
No files matched your search
@@ -46,6 +46,7 @@
|
|||||||
"total": {"type": "int"}
|
"total": {"type": "int"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"clearScreen": "Clear screen",
|
||||||
"minutesAgo": "{count} min ago",
|
"minutesAgo": "{count} min ago",
|
||||||
"@minutesAgo": {
|
"@minutesAgo": {
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
"total": {"type": "int"}
|
"total": {"type": "int"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"clearScreen": "Bersihkan layar",
|
||||||
"minutesAgo": "{count} mnt lalu",
|
"minutesAgo": "{count} mnt lalu",
|
||||||
"@minutesAgo": {
|
"@minutesAgo": {
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
|
|||||||
@@ -340,6 +340,12 @@ abstract class AppLocalizations {
|
|||||||
/// **'Episode {current} / {total}'**
|
/// **'Episode {current} / {total}'**
|
||||||
String episodeOfTotal(int current, int total);
|
String episodeOfTotal(int current, int total);
|
||||||
|
|
||||||
|
/// No description provided for @clearScreen.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Clear screen'**
|
||||||
|
String get clearScreen;
|
||||||
|
|
||||||
/// No description provided for @minutesAgo.
|
/// No description provided for @minutesAgo.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|||||||
@@ -133,6 +133,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
return 'Episode $current / $total';
|
return 'Episode $current / $total';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearScreen => 'Clear screen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String minutesAgo(int count) {
|
String minutesAgo(int count) {
|
||||||
return '$count min ago';
|
return '$count min ago';
|
||||||
|
|||||||
@@ -133,6 +133,9 @@ class AppLocalizationsId extends AppLocalizations {
|
|||||||
return 'Episode $current / $total';
|
return 'Episode $current / $total';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearScreen => 'Bersihkan layar';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String minutesAgo(int count) {
|
String minutesAgo(int count) {
|
||||||
return '$count mnt lalu';
|
return '$count mnt lalu';
|
||||||
|
|||||||
@@ -130,6 +130,9 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||||||
return '第 $current 集 / 共 $total 集';
|
return '第 $current 集 / 共 $total 集';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearScreen => '清屏';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String minutesAgo(int count) {
|
String minutesAgo(int count) {
|
||||||
return '$count 分钟前';
|
return '$count 分钟前';
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
"total": {"type": "int"}
|
"total": {"type": "int"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"clearScreen": "清屏",
|
||||||
"minutesAgo": "{count} 分钟前",
|
"minutesAgo": "{count} 分钟前",
|
||||||
"@minutesAgo": {
|
"@minutesAgo": {
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
|
|||||||
@@ -30,16 +30,6 @@ import 'widgets/seek_progress_bar.dart';
|
|||||||
import '../../core/data/repositories/watch_history_repository.dart';
|
import '../../core/data/repositories/watch_history_repository.dart';
|
||||||
import '../../core/data/repositories/playback_repository.dart';
|
import '../../core/data/repositories/playback_repository.dart';
|
||||||
|
|
||||||
/// The home feed has no overlay play button, so it keeps its own center hint.
|
|
||||||
/// Detail/series playback uses `_PlaybackOverlay.player-play-toggle` instead.
|
|
||||||
bool shouldShowFeedPauseIndicator({
|
|
||||||
required bool homeMode,
|
|
||||||
required bool selected,
|
|
||||||
required bool ready,
|
|
||||||
required bool playing,
|
|
||||||
required bool pip,
|
|
||||||
}) => homeMode && selected && ready && !playing && !pip;
|
|
||||||
|
|
||||||
class PlayerPage extends StatefulWidget {
|
class PlayerPage extends StatefulWidget {
|
||||||
const PlayerPage({
|
const PlayerPage({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -80,6 +70,7 @@ class PlayerPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||||
late final PlayerLogic logic;
|
late final PlayerLogic logic;
|
||||||
|
bool _feedChromeVisible = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -198,9 +189,10 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
|||||||
children: [
|
children: [
|
||||||
const ColoredBox(color: AppColors.ink),
|
const ColoredBox(color: AppColors.ink),
|
||||||
?video,
|
?video,
|
||||||
if (!logic.chromeHidden)
|
if (!logic.chromeHidden && (!widget.homeMode || _feedChromeVisible))
|
||||||
const IgnorePointer(
|
IgnorePointer(
|
||||||
child: DecoratedBox(
|
key: widget.homeMode ? const Key('home-feed-scrim') : null,
|
||||||
|
child: const DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
@@ -312,67 +304,59 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (shouldShowFeedPauseIndicator(
|
|
||||||
homeMode: widget.homeMode,
|
|
||||||
selected: selected,
|
|
||||||
ready: ready,
|
|
||||||
playing: logic.session.userWantsPlay,
|
|
||||||
pip: logic.pip,
|
|
||||||
))
|
|
||||||
Center(
|
|
||||||
child: PlayerCenterToggle(
|
|
||||||
key: const Key('home-feed-center-play'),
|
|
||||||
playing: false,
|
|
||||||
onTap: () => logic.session.setUserWantsPlay(true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (logic.pip || logic.pipPreparing)
|
if (logic.pip || logic.pipPreparing)
|
||||||
const SizedBox.expand()
|
const SizedBox.expand()
|
||||||
else if (widget.homeMode)
|
else if (widget.homeMode)
|
||||||
HomeFeedOverlay(
|
_feedChromeVisible
|
||||||
l10n: l10n,
|
? HomeFeedOverlay(
|
||||||
drama: drama,
|
l10n: l10n,
|
||||||
episode: episode,
|
drama: drama,
|
||||||
liked: interactions.isLiked(drama.id),
|
episode: episode,
|
||||||
saved: context.watch<FavoriteController>().isSaved(drama.id),
|
liked: interactions.isLiked(drama.id),
|
||||||
onLike: () async {
|
saved: context.watch<FavoriteController>().isSaved(drama.id),
|
||||||
if (await ensureSignedIn(context)) {
|
onLike: () async {
|
||||||
if (!context.mounted) return;
|
if (await ensureSignedIn(context)) {
|
||||||
unawaited(context.read<Haptics>().lightImpact());
|
if (!context.mounted) return;
|
||||||
final result = await interactions.toggleDramaLike(drama.id);
|
unawaited(context.read<Haptics>().lightImpact());
|
||||||
if (!result.isSuccess && context.mounted) {
|
final result = await interactions.toggleDramaLike(
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
drama.id,
|
||||||
SnackBar(
|
);
|
||||||
content: Text(
|
if (!result.isSuccess && context.mounted) {
|
||||||
result.errorMessage ??
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
AppLocalizations.of(context)!.likeFailed,
|
SnackBar(
|
||||||
),
|
content: Text(
|
||||||
),
|
result.errorMessage ??
|
||||||
);
|
AppLocalizations.of(context)!.likeFailed,
|
||||||
}
|
),
|
||||||
}
|
),
|
||||||
},
|
);
|
||||||
onSave: () async {
|
}
|
||||||
final favorites = context.read<FavoriteController>();
|
}
|
||||||
if (await ensureSignedIn(context)) {
|
},
|
||||||
if (!context.mounted) return;
|
onSave: () async {
|
||||||
unawaited(context.read<Haptics>().lightImpact());
|
final favorites = context.read<FavoriteController>();
|
||||||
final ok = await favorites.toggle(drama.id, card: drama);
|
if (await ensureSignedIn(context)) {
|
||||||
if (ok || !context.mounted) return;
|
if (!context.mounted) return;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
unawaited(context.read<Haptics>().lightImpact());
|
||||||
SnackBar(content: Text(l10n.favoriteToggleFailed)),
|
final ok = await favorites.toggle(drama.id, card: drama);
|
||||||
);
|
if (ok || !context.mounted) return;
|
||||||
}
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
},
|
SnackBar(content: Text(l10n.favoriteToggleFailed)),
|
||||||
onComments: () => logic.showComments(context, drama),
|
);
|
||||||
onShare: () => logic.shareDrama(context, drama),
|
}
|
||||||
onEpisodes: () => logic.showEpisodes(context),
|
},
|
||||||
onDownload: () => requestEpisodeDownload(context, episode.id),
|
onComments: () => logic.showComments(context, drama),
|
||||||
onSearch: widget.onSearch ?? () => logic.showDiscover(context),
|
onShare: () => logic.shareDrama(context, drama),
|
||||||
onPip: logic.pictureInPicture.isPlatformSupported
|
onEpisodes: () => logic.showEpisodes(context),
|
||||||
? () => unawaited(logic.enterPip(context))
|
onDownload: () => requestEpisodeDownload(context, episode.id),
|
||||||
: null,
|
onClear: () => setState(() => _feedChromeVisible = false),
|
||||||
)
|
onSearch:
|
||||||
|
widget.onSearch ?? () => logic.showDiscover(context),
|
||||||
|
onPip: logic.pictureInPicture.isPlatformSupported
|
||||||
|
? () => unawaited(logic.enterPip(context))
|
||||||
|
: null,
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink()
|
||||||
else
|
else
|
||||||
_PlaybackOverlay(
|
_PlaybackOverlay(
|
||||||
l10n: l10n,
|
l10n: l10n,
|
||||||
@@ -433,6 +417,14 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
|||||||
? (position) => logic.seekTo(context, videoPort!, position)
|
? (position) => logic.seekTo(context, videoPort!, position)
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
|
if (widget.homeMode && !_feedChromeVisible)
|
||||||
|
Positioned.fill(
|
||||||
|
child: GestureDetector(
|
||||||
|
key: const Key('home-feed-video-tap'),
|
||||||
|
behavior: HitTestBehavior.opaque,
|
||||||
|
onTap: () => setState(() => _feedChromeVisible = true),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -608,50 +600,17 @@ class _PlaybackOverlay extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
||||||
Timer? _hideTimer;
|
|
||||||
bool _controlsVisible = true;
|
bool _controlsVisible = true;
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_scheduleHide();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_hideTimer?.cancel();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _scheduleHide() {
|
|
||||||
_hideTimer?.cancel();
|
|
||||||
_hideTimer = Timer(const Duration(milliseconds: 2500), () {
|
|
||||||
if (mounted) setState(() => _controlsVisible = false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _reveal() {
|
|
||||||
setState(() => _controlsVisible = true);
|
|
||||||
_scheduleHide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _togglePlay() {
|
|
||||||
widget.onTogglePlay();
|
|
||||||
_reveal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onVideoTap() {
|
void _onVideoTap() {
|
||||||
if (!_controlsVisible) {
|
if (!_controlsVisible) {
|
||||||
_reveal();
|
setState(() => _controlsVisible = true);
|
||||||
} else {
|
} else if (!widget.playing) {
|
||||||
_togglePlay();
|
widget.onTogglePlay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _run(VoidCallback action) {
|
void _clearScreen() => setState(() => _controlsVisible = false);
|
||||||
action();
|
|
||||||
_reveal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -673,13 +632,14 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Center(
|
if (widget.playing)
|
||||||
child: PlayerCenterToggle(
|
Center(
|
||||||
key: const Key('player-play-toggle'),
|
child: PlayerCenterToggle(
|
||||||
playing: widget.playing,
|
key: const Key('player-play-toggle'),
|
||||||
onTap: _togglePlay,
|
playing: true,
|
||||||
|
onTap: widget.onTogglePlay,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const Positioned(
|
const Positioned(
|
||||||
right: 10,
|
right: 10,
|
||||||
bottom: 14,
|
bottom: 14,
|
||||||
@@ -715,7 +675,7 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
|||||||
key: const Key('player-episodes'),
|
key: const Key('player-episodes'),
|
||||||
icon: Icons.view_list_rounded,
|
icon: Icons.view_list_rounded,
|
||||||
label: widget.l10n.episodes,
|
label: widget.l10n.episodes,
|
||||||
onTap: () => _run(widget.onEpisodes),
|
onTap: widget.onEpisodes,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
@@ -724,7 +684,7 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
|||||||
key: const Key('player-comments'),
|
key: const Key('player-comments'),
|
||||||
icon: Icons.chat_bubble_outline_rounded,
|
icon: Icons.chat_bubble_outline_rounded,
|
||||||
label: widget.l10n.comments,
|
label: widget.l10n.comments,
|
||||||
onTap: () => _run(widget.onComments),
|
onTap: widget.onComments,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
@@ -733,9 +693,7 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
|||||||
height: 32,
|
height: 32,
|
||||||
child: FilledButton(
|
child: FilledButton(
|
||||||
key: const Key('player-next'),
|
key: const Key('player-next'),
|
||||||
onPressed: widget.onNext == null
|
onPressed: widget.onNext,
|
||||||
? null
|
|
||||||
: () => _run(widget.onNext!),
|
|
||||||
style: FilledButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
backgroundColor: AppColors.blue,
|
backgroundColor: AppColors.blue,
|
||||||
disabledBackgroundColor: AppColors.raised,
|
disabledBackgroundColor: AppColors.raised,
|
||||||
@@ -775,7 +733,7 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
|||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
PlayerFeaturedComment(
|
PlayerFeaturedComment(
|
||||||
drama: widget.drama,
|
drama: widget.drama,
|
||||||
onViewAll: () => _run(widget.onComments),
|
onViewAll: widget.onComments,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -800,7 +758,7 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
|||||||
key: const Key('player-back'),
|
key: const Key('player-back'),
|
||||||
tooltip: widget.l10n.backToSeries,
|
tooltip: widget.l10n.backToSeries,
|
||||||
icon: Icons.chevron_left_rounded,
|
icon: Icons.chevron_left_rounded,
|
||||||
onPressed: () => _run(widget.onBack!),
|
onPressed: widget.onBack!,
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
const SizedBox(width: 36),
|
const SizedBox(width: 36),
|
||||||
@@ -822,6 +780,13 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
|
_TopAction(
|
||||||
|
key: const Key('player-clear-screen'),
|
||||||
|
tooltip: widget.l10n.clearScreen,
|
||||||
|
icon: Icons.fullscreen_rounded,
|
||||||
|
onPressed: _clearScreen,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
_TopAction(
|
_TopAction(
|
||||||
key: const Key('player-more'),
|
key: const Key('player-more'),
|
||||||
tooltip: widget.l10n.more,
|
tooltip: widget.l10n.more,
|
||||||
@@ -907,7 +872,6 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (mounted) _reveal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class HomeFeedOverlay extends StatelessWidget {
|
|||||||
required this.onShare,
|
required this.onShare,
|
||||||
required this.onEpisodes,
|
required this.onEpisodes,
|
||||||
required this.onDownload,
|
required this.onDownload,
|
||||||
|
required this.onClear,
|
||||||
required this.onSearch,
|
required this.onSearch,
|
||||||
this.onPip,
|
this.onPip,
|
||||||
});
|
});
|
||||||
@@ -41,6 +42,7 @@ class HomeFeedOverlay extends StatelessWidget {
|
|||||||
final VoidCallback onShare;
|
final VoidCallback onShare;
|
||||||
final VoidCallback onEpisodes;
|
final VoidCallback onEpisodes;
|
||||||
final VoidCallback onDownload;
|
final VoidCallback onDownload;
|
||||||
|
final VoidCallback onClear;
|
||||||
final VoidCallback onSearch;
|
final VoidCallback onSearch;
|
||||||
final VoidCallback? onPip;
|
final VoidCallback? onPip;
|
||||||
|
|
||||||
@@ -96,6 +98,13 @@ class HomeFeedOverlay extends StatelessWidget {
|
|||||||
onPressed: onSearch,
|
onPressed: onSearch,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
|
_RoundIcon(
|
||||||
|
key: const Key('home-feed-clear-screen'),
|
||||||
|
tooltip: l10n.clearScreen,
|
||||||
|
icon: Icons.fullscreen_rounded,
|
||||||
|
onPressed: onClear,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
_RoundIcon(
|
_RoundIcon(
|
||||||
key: const Key('home-feed-more'),
|
key: const Key('home-feed-more'),
|
||||||
tooltip: l10n.more,
|
tooltip: l10n.more,
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ void main() {
|
|||||||
onShare: () {},
|
onShare: () {},
|
||||||
onEpisodes: () {},
|
onEpisodes: () {},
|
||||||
onDownload: () {},
|
onDownload: () {},
|
||||||
|
onClear: () {},
|
||||||
onSearch: () {},
|
onSearch: () {},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,16 +5,14 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import 'package:fruitshorts/pages/player/widgets/player_center_toggle.dart';
|
import 'package:fruitshorts/pages/player/widgets/player_center_toggle.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('should_use_one_shared_52px_style_for_home_and_player', (
|
testWidgets('should_use_one_shared_52px_center_toggle_style', (tester) async {
|
||||||
tester,
|
|
||||||
) async {
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
body: Row(
|
body: Row(
|
||||||
children: [
|
children: [
|
||||||
PlayerCenterToggle(
|
PlayerCenterToggle(
|
||||||
key: const Key('home-feed-center-play'),
|
key: const Key('test-center-toggle-a'),
|
||||||
playing: false,
|
playing: false,
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
),
|
),
|
||||||
@@ -30,7 +28,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (final key in const [
|
for (final key in const [
|
||||||
Key('home-feed-center-play'),
|
Key('test-center-toggle-a'),
|
||||||
Key('player-play-toggle'),
|
Key('player-play-toggle'),
|
||||||
]) {
|
]) {
|
||||||
expect(tester.getSize(find.byKey(key)), const Size(52, 52));
|
expect(tester.getSize(find.byKey(key)), const Size(52, 52));
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import 'package:fruitshorts/app.dart';
|
|||||||
import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
|
import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
|
||||||
import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
|
import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
|
||||||
import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart';
|
import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart';
|
||||||
import 'package:fruitshorts/pages/player/player_view.dart';
|
|
||||||
import 'package:fruitshorts/pages/player/widgets/player_center_toggle.dart';
|
import 'package:fruitshorts/pages/player/widgets/player_center_toggle.dart';
|
||||||
|
|
||||||
import '../support/fake_catalog.dart';
|
import '../support/fake_catalog.dart';
|
||||||
@@ -70,7 +69,7 @@ void main() {
|
|||||||
expect(tester.takeException(), isNull);
|
expect(tester.takeException(), isNull);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_keep_single_pause_toggle_when_detail_player_is_paused', (
|
testWidgets('should_hide_pause_toggle_when_playback_is_paused', (
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
await _pumpApp(tester);
|
await _pumpApp(tester);
|
||||||
@@ -86,12 +85,16 @@ void main() {
|
|||||||
await tester.tap(find.byKey(const Key('player-play-toggle')));
|
await tester.tap(find.byKey(const Key('player-play-toggle')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(find.byKey(const Key('player-play-toggle')), findsNothing);
|
||||||
|
expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.tap(find.byKey(const Key('player-video-tap')));
|
||||||
|
await tester.pump();
|
||||||
expect(find.byKey(const Key('player-play-toggle')), findsOneWidget);
|
expect(find.byKey(const Key('player-play-toggle')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('home-feed-center-play')), findsNothing);
|
|
||||||
expect(find.byIcon(Icons.play_arrow_rounded), findsOneWidget);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_hide_controls_after_2_5s_and_reveal_on_video_tap', (
|
testWidgets('should_keep_controls_visible_until_clear_screen_is_tapped', (
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
await _pumpApp(tester);
|
await _pumpApp(tester);
|
||||||
@@ -108,7 +111,14 @@ void main() {
|
|||||||
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
|
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
|
||||||
expect(find.byType(PlayerCenterToggle), findsOneWidget);
|
expect(find.byType(PlayerCenterToggle), findsOneWidget);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 2600));
|
await tester.pump(const Duration(seconds: 5));
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
|
||||||
|
expect(find.byType(PlayerCenterToggle), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.tap(find.byKey(const Key('player-clear-screen')));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(find.byKey(const Key('player-controls-top')), findsNothing);
|
expect(find.byKey(const Key('player-controls-top')), findsNothing);
|
||||||
@@ -124,39 +134,6 @@ void main() {
|
|||||||
expect(find.byType(PlayerCenterToggle), findsOneWidget);
|
expect(find.byType(PlayerCenterToggle), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should_only_show_feed_pause_indicator_in_home_mode', () {
|
|
||||||
expect(
|
|
||||||
shouldShowFeedPauseIndicator(
|
|
||||||
homeMode: true,
|
|
||||||
selected: true,
|
|
||||||
ready: true,
|
|
||||||
playing: false,
|
|
||||||
pip: false,
|
|
||||||
),
|
|
||||||
isTrue,
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
shouldShowFeedPauseIndicator(
|
|
||||||
homeMode: false,
|
|
||||||
selected: true,
|
|
||||||
ready: true,
|
|
||||||
playing: false,
|
|
||||||
pip: false,
|
|
||||||
),
|
|
||||||
isFalse,
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
shouldShowFeedPauseIndicator(
|
|
||||||
homeMode: true,
|
|
||||||
selected: true,
|
|
||||||
ready: true,
|
|
||||||
playing: true,
|
|
||||||
pip: false,
|
|
||||||
),
|
|
||||||
isFalse,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('should_fit_player_header_on_320_width', (tester) async {
|
testWidgets('should_fit_player_header_on_320_width', (tester) async {
|
||||||
await _pumpApp(tester, size: const Size(320, 568));
|
await _pumpApp(tester, size: const Size(320, 568));
|
||||||
await tester.binding.handlePopRoute();
|
await tester.binding.handlePopRoute();
|
||||||
@@ -174,6 +151,31 @@ void main() {
|
|||||||
);
|
);
|
||||||
expect(tester.takeException(), isNull);
|
expect(tester.takeException(), isNull);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('should_clear_and_restore_home_feed_chrome', (tester) async {
|
||||||
|
await _pumpApp(tester);
|
||||||
|
await tester.tap(find.byKey(const Key('tab-home')));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(find.byKey(const Key('home-feed-title')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-feed-info-card')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-feed-scrim')), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.tap(find.byKey(const Key('home-feed-clear-screen')));
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(find.byKey(const Key('home-feed-title')), findsNothing);
|
||||||
|
expect(find.byKey(const Key('home-feed-info-card')), findsNothing);
|
||||||
|
expect(find.byKey(const Key('home-feed-scrim')), findsNothing);
|
||||||
|
expect(find.byKey(const Key('home-feed-video-tap')), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.tap(find.byKey(const Key('home-feed-video-tap')));
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(find.byKey(const Key('home-feed-title')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-feed-info-card')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-feed-scrim')), findsOneWidget);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _expectFullscreenOverlay(WidgetTester tester) {
|
void _expectFullscreenOverlay(WidgetTester tester) {
|
||||||
|
|||||||
Reference in new issue
Block a user