merge: 合并 K29.5 清屏范围

This commit is contained in:
Zhou Weidong committed 2026-10-20 11:33:23 +08:00
commit b26ca6cb9f
2 files changed
+136 -134

No files matched your search

+98 -97
View File
@@ -5,7 +5,6 @@ import '../../../core/formatting/localized_content.dart';
import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_colors.dart';
import '../../../core/theme/app_dimens.dart'; import '../../../core/theme/app_dimens.dart';
import '../../../l10n/app_localizations.dart'; import '../../../l10n/app_localizations.dart';
import 'exit_clear_screen_button.dart';
import 'player_center_toggle.dart'; import 'player_center_toggle.dart';
import 'player_overlay_models.dart'; import 'player_overlay_models.dart';
import 'seek_progress_bar.dart'; import 'seek_progress_bar.dart';
@@ -51,21 +50,9 @@ class PlayerPlaybackOverlay extends StatelessWidget {
onTap: actions.onTogglePlay, onTap: actions.onTogglePlay,
), ),
), ),
if (controlsVisible) ...[ _top(context),
_top(context), _bottom(context),
_bottom(context), if (controlsVisible) _rail(context),
_rail(context),
],
if (!controlsVisible)
Positioned(
top: AppDimens.spaceSm,
right: AppDimens.spaceMd,
child: ExitClearScreenButton(
key: const Key('player-exit-clear-screen'),
tooltip: data.l10n.exitClearScreen,
onPressed: actions.onExitClear,
),
),
if (!data.playing) if (!data.playing)
Center( Center(
child: PlayerCenterToggle( child: PlayerCenterToggle(
@@ -153,43 +140,49 @@ class PlayerPlaybackOverlay extends StatelessWidget {
} }
Widget _bottom(BuildContext context) { Widget _bottom(BuildContext context) {
final series = localizedDramaTitle(data.l10n, data.drama);
final synopsis = localizedDramaSynopsis(data.l10n, data.drama);
return Positioned( return Positioned(
left: 0, left: 0,
right: 0, right: 0,
bottom: 0, bottom: 0,
child: Padding( child: Column(
key: const Key('player-controls-bottom'), mainAxisSize: MainAxisSize.min,
padding: const EdgeInsets.fromLTRB(14, 8, 14, 6), children: [if (controlsVisible) _bottomInfo(context), _bottomActions()],
child: Column( ),
mainAxisSize: MainAxisSize.min, );
crossAxisAlignment: CrossAxisAlignment.start, }
children: [
_detailRow(series), Widget _bottomInfo(BuildContext context) {
const SizedBox(height: 4), final series = localizedDramaTitle(data.l10n, data.drama);
_EpisodeSynopsis( final synopsis = localizedDramaSynopsis(data.l10n, data.drama);
key: const Key('player-episode-synopsis'), return Padding(
l10n: data.l10n, key: const Key('player-controls-bottom'),
episodeNumber: data.episode.number, padding: const EdgeInsets.fromLTRB(14, 8, 14, 0),
synopsis: synopsis, child: Column(
authorNote: data.authorNote, mainAxisSize: MainAxisSize.min,
textScale: data.textScale, crossAxisAlignment: CrossAxisAlignment.start,
), children: [
const SizedBox(height: 2), _detailRow(series),
SeekProgressBar( const SizedBox(height: 4),
key: const Key('player-progress'), _EpisodeSynopsis(
valueListenable: data.controller, key: const Key('player-episode-synopsis'),
semanticsLabel: data.l10n.seekVideo, l10n: data.l10n,
showTimes: true, episodeNumber: data.episode.number,
compact: true, synopsis: synopsis,
inactiveTrackColor: Colors.white24, authorNote: data.authorNote,
onScrubStart: actions.onScrubStart, textScale: data.textScale,
onSeek: actions.onSeek, ),
), const SizedBox(height: 2),
_bottomActions(), SeekProgressBar(
], key: const Key('player-progress'),
), valueListenable: data.controller,
semanticsLabel: data.l10n.seekVideo,
showTimes: true,
compact: true,
inactiveTrackColor: Colors.white24,
onScrubStart: actions.onScrubStart,
onSeek: actions.onSeek,
),
],
), ),
); );
} }
@@ -234,61 +227,69 @@ class PlayerPlaybackOverlay extends StatelessWidget {
} }
Widget _bottomActions() { Widget _bottomActions() {
return Row( return Padding(
children: [ key: const Key('player-bottom-actions'),
Expanded( padding: const EdgeInsets.fromLTRB(14, 6, 14, 6),
child: Material( child: Row(
key: const Key('player-episodes-pill'), children: [
color: AppColors.playerOverlayPill, Expanded(
borderRadius: BorderRadius.circular(999), child: Material(
clipBehavior: Clip.antiAlias, key: const Key('player-episodes-pill'),
child: InkWell( color: AppColors.playerOverlayPill,
key: const Key('player-episodes'),
onTap: actions.onEpisodes,
borderRadius: BorderRadius.circular(999), borderRadius: BorderRadius.circular(999),
child: Padding( clipBehavior: Clip.antiAlias,
padding: const EdgeInsets.symmetric( child: InkWell(
horizontal: 12, key: const Key('player-episodes'),
vertical: 4, onTap: actions.onEpisodes,
), borderRadius: BorderRadius.circular(999),
child: Row( child: Padding(
children: [ padding: const EdgeInsets.symmetric(
Flexible( horizontal: 12,
child: Text( vertical: 4,
'${data.l10n.episodes} · ' ),
'${data.l10n.allEpisodesBadge(data.totalEpisodes)} · ' child: Row(
'${data.l10n.freeWatch}', children: [
maxLines: 1, Flexible(
overflow: TextOverflow.ellipsis, child: Text(
style: const TextStyle( '${data.l10n.episodes} · '
color: AppColors.onPrimary, '${data.l10n.allEpisodesBadge(data.totalEpisodes)} · '
fontSize: 11, '${data.l10n.freeWatch}',
fontWeight: FontWeight.w700, maxLines: 1,
shadows: _playerTextShadows, overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.onPrimary,
fontSize: 11,
fontWeight: FontWeight.w700,
shadows: _playerTextShadows,
),
), ),
), ),
), const SizedBox(width: 3),
const SizedBox(width: 3), const Icon(
const Icon( Icons.keyboard_arrow_up_rounded,
Icons.keyboard_arrow_up_rounded, color: AppColors.onPrimary,
color: AppColors.onPrimary, size: 16,
size: 16, shadows: _playerTextShadows,
shadows: _playerTextShadows, ),
), ],
], ),
), ),
), ),
), ),
), ),
), const SizedBox(width: 8),
const SizedBox(width: 8), _BottomIconButton(
_BottomIconButton( key: const Key('player-bottom-clear-screen'),
key: const Key('player-bottom-clear-screen'), tooltip: controlsVisible
tooltip: data.l10n.clearScreen, ? data.l10n.clearScreen
icon: Icons.fullscreen_rounded, : data.l10n.exitClearScreen,
onPressed: actions.onClear, icon: controlsVisible
), ? Icons.fullscreen_rounded
], : Icons.fullscreen_exit_rounded,
onPressed: controlsVisible ? actions.onClear : actions.onExitClear,
),
],
),
); );
} }
} }
+38 -37
View File
@@ -110,8 +110,10 @@ void main() {
await _clearFromMore(tester); await _clearFromMore(tester);
await tester.pump(); await tester.pump();
expect(find.byKey(const Key('player-controls-top')), findsNothing); expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
expect(find.byKey(const Key('player-controls-bottom')), findsNothing); expect(find.byKey(const Key('player-controls-bottom')), findsNothing);
expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget);
expect(find.byKey(const Key('player-interaction-rail')), findsNothing);
expect(find.byType(PlayerCenterToggle), findsOneWidget); expect(find.byType(PlayerCenterToggle), findsOneWidget);
expect( expect(
tester tester
@@ -122,45 +124,30 @@ void main() {
isFalse, isFalse,
); );
expect(find.byKey(const Key('player-video-tap')), findsOneWidget); expect(find.byKey(const Key('player-video-tap')), findsOneWidget);
expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); expect(find.byKey(const Key('player-bottom-clear-screen')), findsOneWidget);
expect(find.byTooltip('Exit clear screen'), findsOneWidget);
expect( expect(
tester.getSize(find.byKey(const Key('player-exit-clear-screen'))), tester.getSize(find.byKey(const Key('player-bottom-clear-screen'))),
const Size(36, 36), const Size(30, 30),
); );
await tester.tapAt(const Offset(80, 300)); await tester.tapAt(const Offset(80, 300));
await tester.pump(); await tester.pump();
expect(find.byKey(const Key('player-controls-top')), findsNothing); expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget);
expect(find.byType(PlayerCenterToggle), findsNothing); expect(find.byType(PlayerCenterToggle), findsNothing);
await tester.tapAt(const Offset(80, 300)); await tester.tapAt(const Offset(80, 300));
await tester.pump(); await tester.pump();
expect(find.byKey(const Key('player-controls-top')), findsNothing); expect(find.byType(PlayerCenterToggle), findsOneWidget);
expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget);
expect(
tester
.widget<PlayerCenterToggle>(
find.byKey(const Key('player-play-toggle')),
)
.playing,
isFalse,
);
await tester.tap(find.byKey(const Key('player-exit-clear-screen'))); await tester.tap(find.byKey(const Key('player-bottom-clear-screen')));
await tester.pump(); await tester.pump();
expect(find.byKey(const Key('player-controls-top')), findsOneWidget); expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget); expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
expect(find.byKey(const Key('player-interaction-rail')), findsOneWidget);
expect(find.byType(PlayerCenterToggle), findsOneWidget); expect(find.byType(PlayerCenterToggle), findsOneWidget);
expect( expect(find.byTooltip('Clear screen'), findsOneWidget);
tester
.widget<PlayerCenterToggle>(
find.byKey(const Key('player-play-toggle')),
)
.playing,
isFalse,
);
expect(find.byKey(const Key('player-exit-clear-screen')), findsNothing);
}); });
testWidgets('should_fit_player_header_on_320_width', (tester) async { testWidgets('should_fit_player_header_on_320_width', (tester) async {
@@ -251,20 +238,22 @@ void main() {
await _clearFromMore(tester); await _clearFromMore(tester);
await tester.pump(); await tester.pump();
expect(find.byKey(const Key('player-controls-top')), findsNothing); expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
await tester.drag(find.byType(PageView), const Offset(0, -550)); await tester.drag(find.byType(PageView), const Offset(0, -550));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.byKey(const Key('player-controls-top')), findsNothing); expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
expect(find.byKey(const Key('player-controls-bottom')), findsNothing); expect(find.byKey(const Key('player-controls-bottom')), findsNothing);
expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget);
expect(find.byKey(const Key('player-interaction-rail')), findsNothing);
expect(find.byKey(const Key('player-bottom-clear-screen')), findsOneWidget);
await tester.tap(find.byKey(const Key('player-exit-clear-screen'))); await tester.tap(find.byKey(const Key('player-bottom-clear-screen')));
await tester.pump(); await tester.pump();
expect(find.byKey(const Key('player-controls-top')), findsOneWidget); expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget); expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
expect(find.byKey(const Key('player-exit-clear-screen')), findsNothing); expect(find.byKey(const Key('player-interaction-rail')), findsOneWidget);
}); });
testWidgets('should_open_speed_sheet_and_apply_selected_speed', ( testWidgets('should_open_speed_sheet_and_apply_selected_speed', (
@@ -309,9 +298,9 @@ void main() {
await _clearFromMore(tester); await _clearFromMore(tester);
await tester.pump(); await tester.pump();
expect(find.byKey(const Key('player-more')), findsNothing); expect(find.byKey(const Key('player-more')), findsOneWidget);
await tester.tap(find.byKey(const Key('player-exit-clear-screen'))); await tester.tap(find.byKey(const Key('player-bottom-clear-screen')));
await tester.pump(); await tester.pump();
await tester.drag(find.byType(PageView), const Offset(0, -550)); await tester.drag(find.byType(PageView), const Offset(0, -550));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
@@ -448,9 +437,11 @@ void main() {
await tester.tap(find.byKey(const Key('player-more-clear'))); await tester.tap(find.byKey(const Key('player-more-clear')));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.byKey(const Key('player-controls-top')), findsNothing); expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
expect(find.byKey(const Key('player-controls-bottom')), findsNothing); expect(find.byKey(const Key('player-controls-bottom')), findsNothing);
expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget);
expect(find.byKey(const Key('player-interaction-rail')), findsNothing);
expect(find.byTooltip('Exit clear screen'), findsOneWidget);
}); });
testWidgets('should_enter_clear_screen_from_bottom_button', (tester) async { testWidgets('should_enter_clear_screen_from_bottom_button', (tester) async {
@@ -462,9 +453,19 @@ void main() {
await tester.tap(find.byKey(const Key('player-bottom-clear-screen'))); await tester.tap(find.byKey(const Key('player-bottom-clear-screen')));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.byKey(const Key('player-controls-top')), findsNothing); expect(find.byKey(const Key('player-controls-top')), findsOneWidget);
expect(find.byKey(const Key('player-controls-bottom')), findsNothing); expect(find.byKey(const Key('player-controls-bottom')), findsNothing);
expect(find.byKey(const Key('player-exit-clear-screen')), findsOneWidget); expect(find.byKey(const Key('player-bottom-actions')), findsOneWidget);
expect(find.byKey(const Key('player-interaction-rail')), findsNothing);
expect(find.byType(PlayerCenterToggle), findsNothing);
expect(find.byTooltip('Exit clear screen'), findsOneWidget);
await tester.tap(find.byKey(const Key('player-bottom-clear-screen')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('player-controls-bottom')), findsOneWidget);
expect(find.byKey(const Key('player-interaction-rail')), findsOneWidget);
expect(find.byType(PlayerCenterToggle), findsNothing);
expect(find.byTooltip('Clear screen'), findsOneWidget);
}); });
testWidgets('should_open_unlock_panel_with_honest_method_states', ( testWidgets('should_open_unlock_panel_with_honest_method_states', (