fix(recommend): 稳定进度拖动与清屏状态

This commit is contained in:
Zhou Weidong committed 2026-10-22 20:01:54 +08:00
1 parent 76c4f1d411
commit 30b55afdd4
9 files changed
+339 -96

No files matched your search

+36 -12
View File
@@ -13,13 +13,12 @@ import '../../../core/theme/app_colors.dart';
import '../../../l10n/app_localizations.dart';
import 'home_feed_recommend_panel.dart';
import 'loading_progress_track.dart';
import 'scrub_preview_card.dart';
import 'seek_progress_bar.dart';
part 'home_feed_overlay_parts.dart';
const double _progressHeight = 2;
const double _progressHitHeight = 24;
const double _progressHitHeight = 28;
const double _pageHorizontal = 14;
const double _railRight = 8;
const double _railGap = 12;
@@ -60,6 +59,7 @@ class HomeFeedOverlay extends StatefulWidget {
this.onScrubEnd,
this.onScrubVisibilityChanged,
this.onSeek,
this.cancelScrubRequest = 0,
this.thumbnailService,
this.spriteAxisService,
});
@@ -92,6 +92,7 @@ class HomeFeedOverlay extends StatefulWidget {
final VoidCallback? onScrubEnd;
final ValueChanged<bool>? onScrubVisibilityChanged;
final ValueChanged<Duration>? onSeek;
final int cancelScrubRequest;
final PlaybackThumbnailService? thumbnailService;
final SpriteThumbnailAxisService? spriteAxisService;
@@ -101,6 +102,16 @@ class HomeFeedOverlay extends StatefulWidget {
class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
bool _scrubbing = false;
bool _clearAfterScrub = false;
@override
void didUpdateWidget(covariant HomeFeedOverlay oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.cancelScrubRequest != widget.cancelScrubRequest) {
_scrubbing = false;
_clearAfterScrub = false;
}
}
@override
Widget build(BuildContext context) {
@@ -116,7 +127,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
child: GestureDetector(
key: const Key('home-feed-gesture'),
behavior: HitTestBehavior.opaque,
onTap: widget.onTogglePlay,
onTap: _handleSurfaceTap,
onLongPressStart: (details) =>
_handleLongPressStart(details, constraints.maxWidth),
onLongPressEnd: (_) => widget.onBoostEnd(),
@@ -127,7 +138,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
),
if (widget.boosting)
Positioned(left: 0, right: 0, bottom: 20, child: _boostHint())
else if (widget.visible && !_scrubbing)
else if (widget.visible && !_scrubbing && !_clearAfterScrub)
Positioned(
left: _pageHorizontal,
right: _railRight,
@@ -153,14 +164,10 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
locked: widget.locked,
height: _progressHeight,
hitHeight: _progressHitHeight,
cancelScrubRequest: widget.cancelScrubRequest,
onScrubStart: _startScrub,
onScrubEnd: _endScrub,
onSeek: widget.onSeek,
thumbnailService: widget.thumbnailService,
spriteAxisService: widget.spriteAxisService,
thumbnailsUrl: widget.episode.thumbnailsUrl,
episodeId: widget.episode.id,
posterUrl: widget.drama.posterUrl,
),
),
],
@@ -169,17 +176,34 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
}
void _startScrub() {
if (!_scrubbing) setState(() => _scrubbing = true);
if (!_scrubbing || _clearAfterScrub) {
setState(() {
_scrubbing = true;
_clearAfterScrub = false;
});
}
widget.onScrubVisibilityChanged?.call(true);
widget.onScrubStart?.call();
}
void _endScrub() {
if (_scrubbing) setState(() => _scrubbing = false);
widget.onScrubVisibilityChanged?.call(false);
if (_scrubbing || !_clearAfterScrub) {
setState(() {
_scrubbing = false;
_clearAfterScrub = true;
});
}
widget.onScrubEnd?.call();
}
void _handleSurfaceTap() {
if (_clearAfterScrub) {
setState(() => _clearAfterScrub = false);
widget.onScrubVisibilityChanged?.call(false);
}
widget.onTogglePlay();
}
void _handleLongPressStart(LongPressStartDetails details, double width) {
final third = width / 3;
final dx = details.localPosition.dx;