feat(flutter): 播放页长按手势与加速态

This commit is contained in:
Zhou Weidong committed 2026-10-20 12:36:35 +08:00
1 parent 7bb2714941
commit 96074bc5e8
11 files changed
+231 -4

No files matched your search

+37
View File
@@ -36,6 +36,8 @@ import '../../core/data/repositories/playback_repository.dart';
part 'player_view_actions.dart';
const double _boostPlaybackSpeed = 2.0;
class PlayerPage extends StatefulWidget {
const PlayerPage({
super.key,
@@ -82,6 +84,9 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
late final PlayerLogic logic;
bool _chromeVisible = true;
double _playbackSpeed = 1.0;
bool _boosting = false;
double? _speedBeforeBoost;
bool? _chromeBeforeBoost;
/// 收藏切换后的本地增量:基准是详情快照,切换成功按服务端状态 ±1。
final Map<String, int> _favoriteDelta = {};
@@ -130,6 +135,34 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
setState(() => _chromeVisible = false);
}
/// 长按两侧:切 2 倍速并清屏,记下进入前的状态用于松手恢复。
void _startBoost() {
if (_boosting) return;
setState(() {
_boosting = true;
_speedBeforeBoost = _playbackSpeed;
_chromeBeforeBoost = _chromeVisible;
_playbackSpeed = _boostPlaybackSpeed;
_chromeVisible = false;
});
unawaited(logic.setPlaybackSpeed(_boostPlaybackSpeed));
}
/// 松手或手势取消:恢复长按前的倍速与清屏状态。
void _endBoost() {
if (!_boosting) return;
final speed = _speedBeforeBoost ?? _playbackSpeed;
final chrome = _chromeBeforeBoost ?? true;
setState(() {
_boosting = false;
_speedBeforeBoost = null;
_chromeBeforeBoost = null;
_playbackSpeed = speed;
_chromeVisible = chrome;
});
unawaited(logic.setPlaybackSpeed(speed));
}
/// 收藏状态确认后同步右侧计数(总数没有独立计数接口,按 ±1 跟随)。
void _applyFavoriteDelta(String dramaId, {required bool nowSaved}) {
setState(() {
@@ -397,6 +430,7 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
playing: logic.session.userWantsPlay,
playbackSpeed: _playbackSpeed,
totalEpisodes: logic.visibleIndices.length,
boosting: _boosting,
),
actions: PlayerOverlayActions(
onBack: widget.embedded
@@ -419,6 +453,9 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
onSeek: ready
? (position) => logic.seekTo(context, videoPort!, position)
: null,
onLongPressCenter: () => _openMore(context, episode),
onBoostStart: _startBoost,
onBoostEnd: _endBoost,
),
controlsVisible: _chromeVisible,
),