fix(recommend): 稳定进度拖动与清屏状态
This commit is contained in:
1 parent
76c4f1d411
commit
30b55afdd4
9 files changed
+339
-96
No files matched your search
@@ -59,6 +59,7 @@ class PlayerPage extends StatefulWidget {
|
||||
this.active = true,
|
||||
this.resumeRequest = 0,
|
||||
this.backRequest = 0,
|
||||
this.scrubCancelRequest = 0,
|
||||
this.onDiscover,
|
||||
this.onMy,
|
||||
this.onSearch,
|
||||
@@ -85,6 +86,7 @@ class PlayerPage extends StatefulWidget {
|
||||
final bool active;
|
||||
final int resumeRequest;
|
||||
final int backRequest;
|
||||
final int scrubCancelRequest;
|
||||
final VoidCallback? onDiscover;
|
||||
final VoidCallback? onMy;
|
||||
final VoidCallback? onSearch;
|
||||
@@ -117,6 +119,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
double _playbackSpeed = 1.0;
|
||||
bool _boosting = false;
|
||||
bool _scrubbing = false;
|
||||
bool _clearScreenFromScrub = false;
|
||||
double? _speedBeforeBoost;
|
||||
bool? _chromeBeforeBoost;
|
||||
|
||||
@@ -135,6 +138,9 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
downloads: widget.downloads,
|
||||
);
|
||||
logic.attach(widget, isMounted: () => mounted);
|
||||
if (oldWidget.scrubCancelRequest != widget.scrubCancelRequest) {
|
||||
_cancelFeedScrub();
|
||||
}
|
||||
_thumbnailService = PlaybackThumbnailService(
|
||||
sourceResolver: _resolveThumbnailSource,
|
||||
);
|
||||
@@ -266,7 +272,9 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
}
|
||||
|
||||
void _hideChrome() {
|
||||
if (!_chromeVisible) return;
|
||||
setState(() => _chromeVisible = false);
|
||||
widget.onScrubVisibilityChanged?.call(true);
|
||||
}
|
||||
|
||||
/// 长按两侧:切 2 倍速并清屏,记下进入前的状态用于松手恢复。
|
||||
@@ -281,6 +289,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
_playbackSpeed = _boostPlaybackSpeed;
|
||||
_chromeVisible = false;
|
||||
});
|
||||
widget.onScrubVisibilityChanged?.call(true);
|
||||
unawaited(logic.setPlaybackSpeed(_boostPlaybackSpeed));
|
||||
}
|
||||
|
||||
@@ -296,6 +305,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
_playbackSpeed = speed;
|
||||
_chromeVisible = chrome;
|
||||
});
|
||||
widget.onScrubVisibilityChanged?.call(!chrome);
|
||||
unawaited(logic.setPlaybackSpeed(speed));
|
||||
}
|
||||
|
||||
@@ -305,6 +315,39 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
widget.onScrubVisibilityChanged?.call(value);
|
||||
}
|
||||
|
||||
void _finishFeedScrub() {
|
||||
setState(() {
|
||||
_scrubbing = false;
|
||||
_chromeVisible = false;
|
||||
_clearScreenFromScrub = true;
|
||||
});
|
||||
}
|
||||
|
||||
void _cancelFeedScrub() {
|
||||
logic.cancelScrub();
|
||||
_scrubbing = false;
|
||||
_chromeVisible = true;
|
||||
_clearScreenFromScrub = false;
|
||||
}
|
||||
|
||||
void _restoreFeedChrome() {
|
||||
setState(() {
|
||||
_scrubbing = false;
|
||||
_chromeVisible = true;
|
||||
_clearScreenFromScrub = false;
|
||||
});
|
||||
widget.onScrubVisibilityChanged?.call(false);
|
||||
}
|
||||
|
||||
void _handleFeedSurfaceTap() {
|
||||
if (_scrubbing) return;
|
||||
if (!_chromeVisible) {
|
||||
_restoreFeedChrome();
|
||||
return;
|
||||
}
|
||||
logic.session.setUserWantsPlay(!logic.session.userWantsPlay);
|
||||
}
|
||||
|
||||
/// 收藏状态确认后同步右侧计数(总数没有独立计数接口,按 ±1 跟随)。
|
||||
void _applyFavoriteDelta(String dramaId, {required bool nowSaved}) {
|
||||
setState(() {
|
||||
@@ -374,6 +417,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
if (widget.homeMode &&
|
||||
widget.showHomeFeedHeader &&
|
||||
!_scrubbing &&
|
||||
_chromeVisible &&
|
||||
!_boosting &&
|
||||
!logic.pip &&
|
||||
!logic.pipPreparing)
|
||||
@@ -479,16 +523,14 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
controller: videoPort?.controller,
|
||||
videoUrl: videoPort?.controller.dataSource ?? episode.videoUrl,
|
||||
theater: theater,
|
||||
onTap: () =>
|
||||
logic.session.setUserWantsPlay(!logic.session.userWantsPlay),
|
||||
onTap: () => _handleFeedSurfaceTap(),
|
||||
),
|
||||
if (widget.homeMode && _chromeVisible && !logic.chromeHidden)
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
key: const Key('home-feed-video-toggle'),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () =>
|
||||
logic.session.setUserWantsPlay(!logic.session.userWantsPlay),
|
||||
onTap: _handleFeedSurfaceTap,
|
||||
),
|
||||
),
|
||||
// 票据三态之一:起播前正在向后端要签名地址
|
||||
@@ -595,8 +637,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
boosting: _boosting,
|
||||
onBoostStart: _startBoost,
|
||||
onBoostEnd: _endBoost,
|
||||
onTogglePlay: () =>
|
||||
logic.session.setUserWantsPlay(!logic.session.userWantsPlay),
|
||||
onTogglePlay: _handleFeedSurfaceTap,
|
||||
liked: interactions.isEpisodeLiked(episode.id),
|
||||
likeCount:
|
||||
interactions.episodeLikeCount(episode.id) ?? episode.likeCount,
|
||||
@@ -634,7 +675,9 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
onEpisodes: () => logic.showEpisodes(context),
|
||||
onMore: _openCurrentMore,
|
||||
onScrubStart: ready ? () => logic.beginScrub(videoPort!) : null,
|
||||
onScrubEnd: _finishFeedScrub,
|
||||
onScrubVisibilityChanged: _setScrubbing,
|
||||
cancelScrubRequest: widget.scrubCancelRequest,
|
||||
onSeek: ready
|
||||
? (position) => logic.seekTo(context, videoPort!, position)
|
||||
: null,
|
||||
@@ -706,18 +749,23 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
? null
|
||||
: () => _openUnlockSheet(context, index, episode),
|
||||
),
|
||||
if (widget.homeMode && !_chromeVisible && !_boosting && !_scrubbing)
|
||||
if (widget.homeMode &&
|
||||
!_chromeVisible &&
|
||||
!_boosting &&
|
||||
!_scrubbing &&
|
||||
!_clearScreenFromScrub)
|
||||
Positioned(
|
||||
right: 12,
|
||||
bottom: 56,
|
||||
child: ExitClearScreenButton(
|
||||
key: const Key('home-feed-exit-clear-screen'),
|
||||
tooltip: l10n.exitClearScreen,
|
||||
onPressed: () => setState(() => _chromeVisible = true),
|
||||
onPressed: _restoreFeedChrome,
|
||||
),
|
||||
),
|
||||
if (widget.homeMode &&
|
||||
!_scrubbing &&
|
||||
_chromeVisible &&
|
||||
!logic.chromeHidden &&
|
||||
selected &&
|
||||
!logic.session.userWantsPlay)
|
||||
|
||||
Reference in new issue
Block a user