fix(flutter): feed 清屏保留顶栏并寻址恢复播放
This commit is contained in:
1 parent
9b99d96a07
commit
c87798fb16
5 files changed
+83
-28
No files matched your search
@@ -578,7 +578,11 @@ class PlayerLogic extends ChangeNotifier {
|
|||||||
await session.playbackSettled;
|
await session.playbackSettled;
|
||||||
if (scrubbingPlayer != player || session.active != player) return;
|
if (scrubbingPlayer != player || session.active != player) return;
|
||||||
await player.controller.seekTo(position);
|
await player.controller.seekTo(position);
|
||||||
if (session.active == player) await saveCurrentProgress();
|
if (session.active == player) {
|
||||||
|
// 暂停时拖动进度后直接恢复播放,避免画面停在旧位置。
|
||||||
|
resumeAfterSeek();
|
||||||
|
await saveCurrentProgress();
|
||||||
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
if (context.mounted && session.active == player) {
|
if (context.mounted && session.active == player) {
|
||||||
final l10n = AppLocalizations.of(context)!;
|
final l10n = AppLocalizations.of(context)!;
|
||||||
@@ -591,6 +595,12 @@ class PlayerLogic extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 拖动进度落点后恢复播放;暂停态拖动不应停留在暂停。
|
||||||
|
@visibleForTesting
|
||||||
|
void resumeAfterSeek() {
|
||||||
|
if (!session.userWantsPlay) session.setUserWantsPlay(true);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> leave(BuildContext context) async {
|
Future<void> leave(BuildContext context) async {
|
||||||
await saveCurrentProgress();
|
await saveCurrentProgress();
|
||||||
if (context.mounted) Navigator.of(context).pop();
|
if (context.mounted) Navigator.of(context).pop();
|
||||||
|
|||||||
@@ -510,17 +510,12 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
|||||||
),
|
),
|
||||||
if (widget.homeMode && !_chromeVisible)
|
if (widget.homeMode && !_chromeVisible)
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 0,
|
right: 12,
|
||||||
right: 0,
|
bottom: 56,
|
||||||
child: SafeArea(
|
child: ExitClearScreenButton(
|
||||||
left: false,
|
key: const Key('home-feed-exit-clear-screen'),
|
||||||
bottom: false,
|
tooltip: l10n.exitClearScreen,
|
||||||
minimum: const EdgeInsets.only(top: 8, right: 12),
|
onPressed: () => setState(() => _chromeVisible = true),
|
||||||
child: ExitClearScreenButton(
|
|
||||||
key: const Key('home-feed-exit-clear-screen'),
|
|
||||||
tooltip: l10n.exitClearScreen,
|
|
||||||
onPressed: () => setState(() => _chromeVisible = true),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.homeMode &&
|
if (widget.homeMode &&
|
||||||
|
|||||||
@@ -131,23 +131,17 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
|
|||||||
),
|
),
|
||||||
if (widget.boosting)
|
if (widget.boosting)
|
||||||
Column(children: [const Spacer(), _boostHint(), _fullSeriesBar()])
|
Column(children: [const Spacer(), _boostHint(), _fullSeriesBar()])
|
||||||
else if (widget.visible)
|
else
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
_header(context),
|
_header(context),
|
||||||
Expanded(
|
const Spacer(),
|
||||||
child: Align(
|
if (widget.visible) _bottomInfo(),
|
||||||
alignment: Alignment.bottomRight,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(0, 0, 10, 12),
|
|
||||||
child: _rail(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
_bottomInfo(),
|
|
||||||
_fullSeriesBar(),
|
_fullSeriesBar(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
if (widget.visible && !widget.boosting)
|
||||||
|
Positioned(right: 10, bottom: 56, child: _rail()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -307,7 +301,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
|
|||||||
|
|
||||||
Widget _bottomInfo() {
|
Widget _bottomInfo() {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(14, 0, 14, 8),
|
padding: const EdgeInsets.fromLTRB(14, 0, 56, 8),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
|||||||
@@ -114,13 +114,48 @@ void main() {
|
|||||||
final railBottom = tester
|
final railBottom = tester
|
||||||
.getRect(find.byKey(const Key('rail-share')))
|
.getRect(find.byKey(const Key('rail-share')))
|
||||||
.bottom;
|
.bottom;
|
||||||
final infoTop = tester
|
final seriesTop = tester
|
||||||
.getRect(find.byKey(const Key('home-feed-series-meta')))
|
.getRect(find.byKey(const Key('home-feed-full-series')))
|
||||||
.top;
|
.top;
|
||||||
|
final titleRight = tester
|
||||||
|
.getRect(find.byKey(const Key('home-feed-title')))
|
||||||
|
.right;
|
||||||
|
final railLeft = tester.getRect(find.byKey(const Key('rail-save'))).left;
|
||||||
|
|
||||||
expect(railTop, greaterThan(844 * 0.45));
|
expect(railTop, greaterThan(844 * 0.45));
|
||||||
expect(railBottom, lessThanOrEqualTo(infoTop));
|
expect(seriesTop - railBottom, closeTo(12, 1));
|
||||||
expect(infoTop - railBottom, lessThanOrEqualTo(20));
|
expect(titleRight, lessThanOrEqualTo(railLeft + 2));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('should_keep_feed_header_and_progress_after_clear', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
|
await _pumpApp(tester);
|
||||||
|
final gesture = await tester.startGesture(const Offset(195, 300));
|
||||||
|
await tester.pump(const Duration(milliseconds: 700));
|
||||||
|
await tester.pump();
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await tester.tap(find.byKey(const Key('player-more-clear')));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(find.byKey(const Key('home-feed-refresh')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-feed-tab-recommend')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-feed-search')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-feed-full-series')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-feed-progress')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('rail-save')), findsNothing);
|
||||||
|
expect(find.byKey(const Key('home-feed-title')), findsNothing);
|
||||||
|
final exit = tester.getRect(
|
||||||
|
find.byKey(const Key('home-feed-exit-clear-screen')),
|
||||||
|
);
|
||||||
|
expect(exit.right, greaterThan(340));
|
||||||
|
expect(exit.center.dy, greaterThan(600));
|
||||||
|
|
||||||
|
await tester.tap(find.byKey(const Key('home-feed-exit-clear-screen')));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.byKey(const Key('rail-save')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-feed-title')), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_boost_feed_on_side_long_press', (tester) async {
|
testWidgets('should_boost_feed_on_side_long_press', (tester) async {
|
||||||
|
|||||||
@@ -215,6 +215,27 @@ void main() {
|
|||||||
logic.dispose();
|
logic.dispose();
|
||||||
await _drain(logic);
|
await _drain(logic);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should_resume_playback_after_seek_when_paused', () async {
|
||||||
|
final logic = _logic(FakeWatchHistory());
|
||||||
|
logic.attach(
|
||||||
|
PlayerPage(drama: _drama('signal'), initialIndex: 0),
|
||||||
|
isMounted: () => true,
|
||||||
|
);
|
||||||
|
logic.start(
|
||||||
|
factory: _RecordingFactory().create,
|
||||||
|
coordinator: PlaybackCoordinator(),
|
||||||
|
);
|
||||||
|
await _drain(logic);
|
||||||
|
logic.session.setUserWantsPlay(false);
|
||||||
|
expect(logic.session.userWantsPlay, isFalse);
|
||||||
|
|
||||||
|
logic.resumeAfterSeek();
|
||||||
|
|
||||||
|
expect(logic.session.userWantsPlay, isTrue);
|
||||||
|
logic.dispose();
|
||||||
|
await _drain(logic);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('history writes', () {
|
group('history writes', () {
|
||||||
|
|||||||
Reference in new issue
Block a user