fix(client): 修正 ChangeNotifier 监听生命周期

This commit is contained in:
Zhou Weidong committed 2026-10-22 19:14:35 +08:00
1 parent 4291031ace
commit 8936c3d6eb
7 files changed
+286 -269

No files matched your search

+54 -29
View File
@@ -69,6 +69,9 @@ class PlayerLogic extends ChangeNotifier {
VideoPlayerPort? trackedPlayer;
Episode? trackedEpisode;
Drama? trackedDrama;
int? _trackedPlayerIndex;
bool _completionHandled = false;
bool _completionProgressSaved = false;
DateTime lastProgressWrite = DateTime.fromMillisecondsSinceEpoch(0);
/// 进度上报节流:契约建议每 10 秒一次
@@ -317,6 +320,7 @@ class PlayerLogic extends ChangeNotifier {
unawaited(saveCurrentProgress());
final previous = session;
sessionEpisodes = List<Episode>.of(nextEpisodes);
_detachTrackedPlayerListener();
trackedPlayer = null;
trackedEpisode = null;
trackedDrama = null;
@@ -601,6 +605,7 @@ class PlayerLogic extends ChangeNotifier {
_disposed = true;
pictureInPicture.setStateListener(null);
unawaited(saveCurrentProgress());
_detachTrackedPlayerListener();
if (_started) {
session.setRouteVisible(false);
cancelScrub();
@@ -696,46 +701,66 @@ class PlayerLogic extends ChangeNotifier {
await player.controller.setVolume(muted ? 0 : 1);
await player.controller.setPlaybackSpeed(playbackSpeed);
if (session.active != player) return;
_detachTrackedPlayerListener();
trackedPlayer = player;
trackedEpisode = episode;
trackedDrama = drama;
_trackedPlayerIndex = index;
_completionHandled = false;
_completionProgressSaved = false;
lastProgressWrite = DateTime.now();
var completionHandled = false;
var completionProgressSaved = false;
player.controller.addListener(() {
if (session.active != player) return;
final snapshot = _readPlaybackSnapshot(player);
if (snapshot == null) return;
_cachePlaybackPosition(drama, episode, snapshot);
if (snapshot.completed && !completionProgressSaved) {
completionProgressSaved = true;
unawaited(
queueProgress(
drama,
episode,
snapshot.duration,
duration: snapshot.duration,
finished: true,
),
);
}
if (!completionHandled &&
snapshot.completed &&
session.canAutoAdvance &&
session.currentIndex == index) {
completionHandled = true;
unawaited(advanceAfterEnd(player, index));
}
if (!shouldReportProgress(DateTime.now())) return;
player.controller.addListener(_handleTrackedPlayerChanged);
}
void _detachTrackedPlayerListener() {
trackedPlayer?.controller.removeListener(_handleTrackedPlayerChanged);
_trackedPlayerIndex = null;
}
void _handleTrackedPlayerChanged() {
if (_disposed) return;
final player = trackedPlayer;
final episode = trackedEpisode;
final drama = trackedDrama;
final index = _trackedPlayerIndex;
if (player == null ||
episode == null ||
drama == null ||
index == null ||
session.active != player) {
return;
}
final snapshot = _readPlaybackSnapshot(player);
if (snapshot == null) return;
_cachePlaybackPosition(drama, episode, snapshot);
if (snapshot.completed && !_completionProgressSaved) {
_completionProgressSaved = true;
unawaited(
queueProgress(
drama,
episode,
snapshot.position,
snapshot.duration,
duration: snapshot.duration,
finished: true,
),
);
});
}
if (!_completionHandled &&
snapshot.completed &&
session.canAutoAdvance &&
session.currentIndex == index) {
_completionHandled = true;
unawaited(advanceAfterEnd(player, index));
}
if (!shouldReportProgress(DateTime.now())) return;
unawaited(
queueProgress(
drama,
episode,
snapshot.position,
duration: snapshot.duration,
),
);
}
Future<void> advanceAfterEnd(VideoPlayerPort player, int index) async {
@@ -79,6 +79,15 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
_trackKeyboardInset(_keyboardHeight(context));
}
@override
void didUpdateWidget(covariant CommentComposerSheet oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.controller != widget.controller) {
oldWidget.controller.removeListener(_onControllerChanged);
widget.controller.addListener(_onControllerChanged);
}
}
Future<void> _prepareInput() async {
if (_isAndroid) {
await _keyboardInset.start();