fix(flutter): 底栏右侧改为清屏

This commit is contained in:
Zhou Weidong committed 2026-10-20 11:19:14 +08:00
1 parent 9429257d62
commit 1666bc220e
7 files changed
+51 -18

No files matched your search

-3
View File
@@ -431,9 +431,6 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
onSave: () => unawaited(_toggleSave(context, drama)), onSave: () => unawaited(_toggleSave(context, drama)),
onShare: () => logic.shareDrama(context, drama), onShare: () => logic.shareDrama(context, drama),
onMore: () => _openMore(context, drama, episode), onMore: () => _openMore(context, drama, episode),
onPip: logic.pictureInPicture.isPlatformSupported
? () => unawaited(logic.enterPip(context))
: null,
onScrubStart: ready ? () => logic.beginScrub(videoPort!) : null, onScrubStart: ready ? () => logic.beginScrub(videoPort!) : null,
onSeek: ready onSeek: ready
? (position) => logic.seekTo(context, videoPort!, position) ? (position) => logic.seekTo(context, videoPort!, position)
@@ -32,6 +32,7 @@ extension _PlayerViewActions on _PlayerPageState {
speed: _playbackSpeed, speed: _playbackSpeed,
qualities: logic.qualities, qualities: logic.qualities,
textScale: _textScale, textScale: _textScale,
pipAvailable: logic.pictureInPicture.isPlatformSupported,
), ),
actions: PlayerMoreActions( actions: PlayerMoreActions(
onSpeedChanged: (value) { onSpeedChanged: (value) {
@@ -42,6 +43,9 @@ extension _PlayerViewActions on _PlayerPageState {
onClear: _hideChrome, onClear: _hideChrome,
onDownload: () => requestEpisodeDownload(context, episode.id), onDownload: () => requestEpisodeDownload(context, episode.id),
onReport: () => unawaited(_reportDrama(context, drama, l10n)), onReport: () => unawaited(_reportDrama(context, drama, l10n)),
onPip: logic.pictureInPicture.isPlatformSupported
? () => unawaited(logic.enterPip(context))
: null,
), ),
), ),
); );
@@ -18,6 +18,7 @@ class PlayerMoreState {
required this.speed, required this.speed,
required this.qualities, required this.qualities,
required this.textScale, required this.textScale,
required this.pipAvailable,
}); });
/// 当前倍速。 /// 当前倍速。
@@ -28,6 +29,9 @@ class PlayerMoreState {
/// 当前文字缩放比例。 /// 当前文字缩放比例。
final double textScale; final double textScale;
/// 设备是否提供画中画入口。
final bool pipAvailable;
} }
/// 更多面板动作集合。 /// 更多面板动作集合。
@@ -39,6 +43,7 @@ class PlayerMoreActions {
required this.onClear, required this.onClear,
required this.onDownload, required this.onDownload,
required this.onReport, required this.onReport,
this.onPip,
}); });
/// 倍速变化。 /// 倍速变化。
@@ -55,6 +60,9 @@ class PlayerMoreActions {
/// 投诉当前剧。 /// 投诉当前剧。
final VoidCallback onReport; final VoidCallback onReport;
/// 进入画中画;平台不支持时为空。
final VoidCallback? onPip;
} }
/// K29 播放页白色更多面板。 /// K29 播放页白色更多面板。
@@ -136,6 +144,13 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
title: l10n.offlineCache, title: l10n.offlineCache,
onTap: () => _closeThen(widget.actions.onDownload), onTap: () => _closeThen(widget.actions.onDownload),
), ),
if (widget.state.pipAvailable && widget.actions.onPip != null)
_enabledRow(
key: const Key('player-more-pip'),
icon: Icons.picture_in_picture_alt_rounded,
title: l10n.pictureInPicture,
onTap: () => _closeThen(widget.actions.onPip!),
),
_textSizeRow(l10n), _textSizeRow(l10n),
_disabledRow( _disabledRow(
key: const Key('player-more-cast'), key: const Key('player-more-cast'),
+7 -8
View File
@@ -281,14 +281,13 @@ class PlayerPlaybackOverlay extends StatelessWidget {
), ),
), ),
), ),
if (actions.onPip != null) ...[ const SizedBox(width: 8),
const SizedBox(width: 8), _BottomIconButton(
_PipButton( key: const Key('player-bottom-clear-screen'),
key: const Key('player-pip'), tooltip: data.l10n.clearScreen,
tooltip: data.l10n.pictureInPicture, icon: Icons.fullscreen_rounded,
onPressed: actions.onPip!, onPressed: actions.onClear,
), ),
],
], ],
); );
} }
@@ -87,7 +87,6 @@ class PlayerOverlayActions {
required this.onMore, required this.onMore,
required this.onScrubStart, required this.onScrubStart,
required this.onSeek, required this.onSeek,
this.onPip,
}); });
/// 返回上一页。 /// 返回上一页。
@@ -131,7 +130,4 @@ class PlayerOverlayActions {
/// 提交进度跳转。 /// 提交进度跳转。
final Future<void> Function(Duration)? onSeek; final Future<void> Function(Duration)? onSeek;
/// 进入小窗播放。
final VoidCallback? onPip;
} }
@@ -73,10 +73,16 @@ class _SpeedEntry extends StatelessWidget {
} }
} }
class _PipButton extends StatelessWidget { class _BottomIconButton extends StatelessWidget {
const _PipButton({super.key, required this.tooltip, required this.onPressed}); const _BottomIconButton({
super.key,
required this.tooltip,
required this.icon,
required this.onPressed,
});
final String tooltip; final String tooltip;
final IconData icon;
final VoidCallback onPressed; final VoidCallback onPressed;
@override @override
@@ -91,7 +97,7 @@ class _PipButton extends StatelessWidget {
foregroundColor: AppColors.onSurface, foregroundColor: AppColors.onSurface,
), ),
onPressed: onPressed, onPressed: onPressed,
icon: const Icon(Icons.picture_in_picture_alt_rounded, size: 17), icon: Icon(icon, size: 17),
), ),
); );
} }
+16
View File
@@ -434,6 +434,20 @@ void main() {
expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget);
}); });
testWidgets('should_enter_clear_screen_from_bottom_button', (tester) async {
await _pumpApp(tester);
await _openSeriesPlayer(tester);
expect(find.byKey(const Key('player-bottom-clear-screen')), findsOneWidget);
expect(find.byKey(const Key('player-pip')), findsNothing);
await tester.tap(find.byKey(const Key('player-bottom-clear-screen')));
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);
});
testWidgets('should_open_unlock_panel_with_honest_method_states', ( testWidgets('should_open_unlock_panel_with_honest_method_states', (
tester, tester,
) async { ) async {
@@ -478,6 +492,8 @@ void _expectFullscreenOverlay(WidgetTester tester) {
} }
expect(find.byKey(const Key('player-play-toggle')), findsNothing); expect(find.byKey(const Key('player-play-toggle')), findsNothing);
expect(find.byKey(const Key('player-episodes')), findsOneWidget); expect(find.byKey(const Key('player-episodes')), findsOneWidget);
expect(find.byKey(const Key('player-bottom-clear-screen')), findsOneWidget);
expect(find.byKey(const Key('player-pip')), findsNothing);
expect(find.byKey(const Key('player-rail-comments')), findsOneWidget); expect(find.byKey(const Key('player-rail-comments')), findsOneWidget);
expect(find.byKey(const Key('player-fullscreen-toggle')), findsNothing); expect(find.byKey(const Key('player-fullscreen-toggle')), findsNothing);
expect(find.byType(Slider), findsOneWidget); expect(find.byType(Slider), findsOneWidget);