merge: 共享清屏状态并左贴集数
This commit is contained in:
commit
5ca5846a26
4 files changed
+78
-50
No files matched your search
@@ -71,7 +71,7 @@ class PlayerPage extends StatefulWidget {
|
||||
|
||||
class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
late final PlayerLogic logic;
|
||||
bool _feedChromeVisible = true;
|
||||
bool _chromeVisible = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -190,7 +190,7 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
children: [
|
||||
const ColoredBox(color: AppColors.ink),
|
||||
?video,
|
||||
if (!logic.chromeHidden && (!widget.homeMode || _feedChromeVisible))
|
||||
if (!logic.chromeHidden && (!widget.homeMode || _chromeVisible))
|
||||
IgnorePointer(
|
||||
key: widget.homeMode ? const Key('home-feed-scrim') : null,
|
||||
child: const DecoratedBox(
|
||||
@@ -209,7 +209,7 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.homeMode && _feedChromeVisible && !logic.chromeHidden)
|
||||
if (widget.homeMode && _chromeVisible && !logic.chromeHidden)
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
key: const Key('home-feed-video-toggle'),
|
||||
@@ -317,7 +317,7 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
if (logic.pip || logic.pipPreparing)
|
||||
const SizedBox.expand()
|
||||
else if (widget.homeMode)
|
||||
_feedChromeVisible
|
||||
_chromeVisible
|
||||
? HomeFeedOverlay(
|
||||
l10n: l10n,
|
||||
drama: drama,
|
||||
@@ -359,7 +359,7 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
onShare: () => logic.shareDrama(context, drama),
|
||||
onEpisodes: () => logic.showEpisodes(context),
|
||||
onDownload: () => requestEpisodeDownload(context, episode.id),
|
||||
onClear: () => setState(() => _feedChromeVisible = false),
|
||||
onClear: () => setState(() => _chromeVisible = false),
|
||||
onSearch:
|
||||
widget.onSearch ?? () => logic.showDiscover(context),
|
||||
onPip: logic.pictureInPicture.isPlatformSupported
|
||||
@@ -384,6 +384,9 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
? () => unawaited(logic.playNextEpisode())
|
||||
: null,
|
||||
playing: logic.session.userWantsPlay,
|
||||
controlsVisible: _chromeVisible,
|
||||
onClear: () => setState(() => _chromeVisible = false),
|
||||
onExitClear: () => setState(() => _chromeVisible = true),
|
||||
onTogglePlay: () =>
|
||||
logic.session.setUserWantsPlay(!logic.session.userWantsPlay),
|
||||
// 收藏/点赞要对到具体账号:未登录先引导登录(首页/详情仍可匿名浏览)
|
||||
@@ -427,7 +430,7 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
? (position) => logic.seekTo(context, videoPort!, position)
|
||||
: null,
|
||||
),
|
||||
if (widget.homeMode && !_feedChromeVisible)
|
||||
if (widget.homeMode && !_chromeVisible)
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
key: const Key('home-feed-video-tap'),
|
||||
@@ -436,7 +439,7 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
logic.session.setUserWantsPlay(!logic.session.userWantsPlay),
|
||||
),
|
||||
),
|
||||
if (widget.homeMode && !_feedChromeVisible)
|
||||
if (widget.homeMode && !_chromeVisible)
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
@@ -447,7 +450,7 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
child: ExitClearScreenButton(
|
||||
key: const Key('home-feed-exit-clear-screen'),
|
||||
tooltip: l10n.exitClearScreen,
|
||||
onPressed: () => setState(() => _feedChromeVisible = true),
|
||||
onPressed: () => setState(() => _chromeVisible = true),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -599,7 +602,10 @@ class _PlaybackOverlay extends StatefulWidget {
|
||||
required this.liked,
|
||||
required this.saved,
|
||||
required this.playing,
|
||||
required this.controlsVisible,
|
||||
required this.onTogglePlay,
|
||||
required this.onClear,
|
||||
required this.onExitClear,
|
||||
required this.onBack,
|
||||
required this.onEpisodes,
|
||||
required this.onComments,
|
||||
@@ -620,7 +626,10 @@ class _PlaybackOverlay extends StatefulWidget {
|
||||
final bool liked;
|
||||
final bool saved;
|
||||
final bool playing;
|
||||
final bool controlsVisible;
|
||||
final VoidCallback onTogglePlay;
|
||||
final VoidCallback onClear;
|
||||
final VoidCallback onExitClear;
|
||||
final VoidCallback? onBack;
|
||||
final VoidCallback onEpisodes;
|
||||
final VoidCallback onComments;
|
||||
@@ -638,14 +647,6 @@ class _PlaybackOverlay extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
||||
bool _controlsVisible = true;
|
||||
|
||||
void _onVideoTap() {
|
||||
widget.onTogglePlay();
|
||||
}
|
||||
|
||||
void _clearScreen() => setState(() => _controlsVisible = false);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
@@ -655,10 +656,10 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
||||
child: GestureDetector(
|
||||
key: const Key('player-video-tap'),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: _onVideoTap,
|
||||
onTap: widget.onTogglePlay,
|
||||
),
|
||||
),
|
||||
if (_controlsVisible)
|
||||
if (widget.controlsVisible)
|
||||
Column(
|
||||
key: const Key('player-controls-visible'),
|
||||
children: [
|
||||
@@ -766,14 +767,14 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
||||
),
|
||||
],
|
||||
),
|
||||
if (!_controlsVisible)
|
||||
if (!widget.controlsVisible)
|
||||
Positioned(
|
||||
top: 8,
|
||||
right: 12,
|
||||
child: ExitClearScreenButton(
|
||||
key: const Key('player-exit-clear-screen'),
|
||||
tooltip: widget.l10n.exitClearScreen,
|
||||
onPressed: () => setState(() => _controlsVisible = true),
|
||||
onPressed: widget.onExitClear,
|
||||
),
|
||||
),
|
||||
if (!widget.playing)
|
||||
@@ -828,7 +829,7 @@ class _PlaybackOverlayState extends State<_PlaybackOverlay> {
|
||||
key: const Key('player-clear-screen'),
|
||||
tooltip: widget.l10n.clearScreen,
|
||||
icon: Icons.fullscreen_rounded,
|
||||
onPressed: _clearScreen,
|
||||
onPressed: widget.onClear,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_TopAction(
|
||||
|
||||
@@ -167,38 +167,27 @@ class HomeFeedOverlay extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
Wrap(
|
||||
spacing: 6,
|
||||
runSpacing: 4,
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Wrap(
|
||||
spacing: 6,
|
||||
runSpacing: 4,
|
||||
children: [
|
||||
if (genre.isNotEmpty)
|
||||
_tag(
|
||||
genre,
|
||||
background: AppColors.blue,
|
||||
foreground: AppColors.onPrimary,
|
||||
),
|
||||
if (drama.category.isNotEmpty && drama.category != genre)
|
||||
_tag(
|
||||
drama.category,
|
||||
background: const Color(0xFF333333),
|
||||
foreground: const Color(0xFFDDDDDD),
|
||||
),
|
||||
],
|
||||
if (genre.isNotEmpty)
|
||||
_tag(
|
||||
genre,
|
||||
background: AppColors.blue,
|
||||
foreground: AppColors.onPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Flexible(
|
||||
child: Text(
|
||||
l10n.episodeOfTotal(episode.number, drama.episodeCount),
|
||||
key: const Key('home-feed-episode'),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.right,
|
||||
style: const TextStyle(color: Color(0xFFBBBBBB), fontSize: 9),
|
||||
if (drama.category.isNotEmpty && drama.category != genre)
|
||||
_tag(
|
||||
drama.category,
|
||||
background: const Color(0xFF333333),
|
||||
foreground: const Color(0xFFDDDDDD),
|
||||
),
|
||||
Text(
|
||||
l10n.episodeOfTotal(episode.number, drama.episodeCount),
|
||||
key: const Key('home-feed-episode'),
|
||||
style: const TextStyle(color: Color(0xFFBBBBBB), fontSize: 9),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -54,6 +54,13 @@ void main() {
|
||||
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-episode')), findsOneWidget);
|
||||
final cardRect = tester.getRect(
|
||||
find.byKey(const Key('home-feed-info-card')),
|
||||
);
|
||||
final episodeRect = tester.getRect(
|
||||
find.byKey(const Key('home-feed-episode')),
|
||||
);
|
||||
expect(episodeRect.left, lessThan(cardRect.center.dx));
|
||||
expect(find.byKey(const Key('home-feed-follow-series')), findsOneWidget);
|
||||
expect(find.byKey(const Key('home-feed-episodes')), findsOneWidget);
|
||||
for (final key in const [Key('home-feed-search'), Key('home-feed-more')]) {
|
||||
|
||||
@@ -216,6 +216,37 @@ void main() {
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('should_keep_series_clear_state_when_swiping_next_episode', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpApp(tester);
|
||||
await tester.binding.handlePopRoute();
|
||||
await tester.pumpAndSettle();
|
||||
await tester.binding.handlePopRoute();
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('drawer-open-series')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('detail-cta')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byKey(const Key('player-clear-screen')));
|
||||
await tester.pump();
|
||||
expect(find.byKey(const Key('player-controls-top')), findsNothing);
|
||||
|
||||
await tester.drag(find.byType(PageView), const Offset(0, -550));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('player-controls-top')), findsNothing);
|
||||
expect(find.byKey(const Key('player-controls-bottom')), findsNothing);
|
||||
expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byKey(const Key('player-exit-clear-screen')));
|
||||
await tester.pump();
|
||||
expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-exit-clear-screen')), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('should_clear_and_restore_home_feed_chrome', (tester) async {
|
||||
await _pumpApp(tester);
|
||||
await tester.tap(find.byKey(const Key('tab-home')));
|
||||
|
||||
Reference in new issue
Block a user