fix(player): 修复切集返回推荐页黑屏

This commit is contained in:
Zhou Weidong committed 2026-10-26 16:20:31 +08:00
1 parent 9d2d3b97a1
commit 440188f261
5 files changed
+297 -37

No files matched your search

+78 -14
View File
@@ -10,10 +10,12 @@ import 'package:provider/provider.dart';
import '../../core/config/app_config.dart';
import '../../core/data/models/drama.dart';
import '../../core/data/repositories/comment_repository.dart';
import '../../core/data/services/catalog_controller.dart';
import '../../core/data/services/favorite_controller.dart';
import '../../core/data/services/download_controller.dart';
import '../../core/data/services/interaction_controller.dart';
import '../../core/data/services/playback_position_cache.dart';
import '../../core/data/services/playback_queue.dart';
import '../../core/data/services/playback_session.dart';
import '../../core/data/services/sprite_thumbnail_axis.dart';
import '../../core/data/services/playback_thumbnail_service.dart';
@@ -58,12 +60,22 @@ const double _feedRefreshTopGap = 56;
class PlayerPageHandoff {
PlayerPageHandoff({
required this.logic,
required this.initialIndex,
required this.sourceQueue,
required this.sourceEpisodes,
required this.sourceIndex,
required this.seriesDrama,
required this.seriesEpisodes,
required this.episodeIndex,
required this.prepareSource,
});
final PlayerLogic logic;
final int initialIndex;
final PlaybackQueue sourceQueue;
final List<Episode> sourceEpisodes;
final int sourceIndex;
final Drama seriesDrama;
final List<Episode> seriesEpisodes;
final int episodeIndex;
final Future<void> Function() prepareSource;
PageController? destinationController;
VoidCallback? activateDestination;
@@ -150,6 +162,8 @@ class _PlayerPageState extends State<PlayerPage>
bool _presentationSuspended = false;
bool _presentationReturning = false;
bool _leavingHandoff = false;
bool _preparingFullPlayer = false;
PlayerPageHandoff? _activeHandoff;
PageController? _returnPageController;
final Set<String> _precachedPosterUrls = {};
@@ -185,10 +199,12 @@ class _PlayerPageState extends State<PlayerPage>
);
_pageController = logic.pages;
} else {
final position = logic.visibleIndices.indexOf(handoff.initialIndex);
_pageController = PageController(
initialPage: position < 0 ? 0 : position,
logic.adoptSeriesHandoff(
drama: handoff.seriesDrama,
seriesEpisodes: handoff.seriesEpisodes,
episodeIndex: handoff.episodeIndex,
);
_pageController = PageController(initialPage: handoff.episodeIndex);
handoff.destinationController = _pageController;
logic.session.setRouteVisible(widget.active);
}
@@ -1163,13 +1179,56 @@ class _PlayerPageState extends State<PlayerPage>
}
Future<void> _presentFullPlayer(BuildContext context, int index) async {
if (_presentationActive || !_pageController.hasClients) return;
if (_presentationActive ||
_preparingFullPlayer ||
!_pageController.hasClients) {
return;
}
_preparingFullPlayer = true;
final sourceIndex = logic.session.currentIndex;
final sourceEpisode = logic.session.currentEpisode;
final sourceQueue = logic.queue;
final sourceEpisodes = List<Episode>.of(logic.sessionEpisodes);
var seriesDrama = sourceQueue.entryAt(sourceIndex).drama;
try {
seriesDrama = await context.read<CatalogController>().requireDetail(
seriesDrama,
);
} catch (_) {
// 详情不可用时仍使用当前剧已知的集列表。
}
_preparingFullPlayer = false;
if (!mounted ||
!context.mounted ||
logic.session.currentIndex != sourceIndex ||
logic.session.currentEpisode.id != sourceEpisode.id) {
return;
}
final seriesEpisodes = List<Episode>.of(seriesDrama.episodes);
var episodeIndex = seriesEpisodes.indexWhere(
(episode) => episode.id == sourceEpisode.id,
);
if (episodeIndex < 0) {
episodeIndex = seriesEpisodes.indexWhere(
(episode) => episode.number == sourceEpisode.number,
);
}
if (episodeIndex < 0) {
seriesEpisodes.insert(0, sourceEpisode);
episodeIndex = 0;
}
final sourcePageController = _pageController;
final handoff = PlayerPageHandoff(
logic: logic,
initialIndex: index,
sourceQueue: sourceQueue,
sourceEpisodes: sourceEpisodes,
sourceIndex: sourceIndex,
seriesDrama: seriesDrama,
seriesEpisodes: seriesEpisodes,
episodeIndex: episodeIndex,
prepareSource: _prepareSourceAfterFullPlayer,
);
_activeHandoff = handoff;
handoff.activateDestination = () {
final destination = handoff.destinationController;
if (destination != null) logic.pages = destination;
@@ -1179,8 +1238,8 @@ class _PlayerPageState extends State<PlayerPage>
final route = Navigator.of(context).push<void>(
MaterialPageRoute<void>(
builder: (_) => PlayerPage(
drama: logic.queue.entryAt(index).drama,
initialIndex: index,
drama: seriesDrama,
initialIndex: episodeIndex,
handoff: handoff,
wallet: logic.wallet,
downloads: logic.downloads,
@@ -1210,17 +1269,23 @@ class _PlayerPageState extends State<PlayerPage>
_presentationSuspended = false;
_presentationReturning = false;
});
_activeHandoff = null;
logic.session.setRouteVisible(widget.active);
_logFullPlayerRoute('restored');
}
Future<void> _prepareSourceAfterFullPlayer() async {
if (!mounted) return;
final page = logic.visibleIndices.indexOf(logic.session.currentIndex);
_returnPageController = PageController(
initialPage: page < 0 ? 0 : page,
);
final handoff = _activeHandoff;
if (handoff == null) return;
logic.attach(widget, isMounted: () => mounted);
logic.restoreFeedHandoff(
page: widget,
sourceQueue: handoff.sourceQueue,
sourceEpisodes: handoff.sourceEpisodes,
sourceIndex: handoff.sourceIndex,
);
_returnPageController = PageController(initialPage: handoff.sourceIndex);
setState(() {
_presentationSuspended = false;
_presentationReturning = true;
@@ -1247,5 +1312,4 @@ class _PlayerPageState extends State<PlayerPage>
'position=${video?.controller.value.position.inMilliseconds ?? '-'}',
);
}
}