From 1f8955d0b356432371fdd94cd9c3328a62d84290 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Sun, 23 Mar 2025 21:47:10 +0800 Subject: [PATCH] opt: prev/next play Closes #506 Signed-off-by: bggRGjQaUbCoE --- .../video/detail/introduction/controller.dart | 40 ++++++++++++++----- lib/pages/video/detail/introduction/view.dart | 30 ++++++++------ .../detail/introduction/widgets/season.dart | 13 +++--- lib/pages/video/detail/view.dart | 2 - lib/pages/video/detail/view_v.dart | 2 - 5 files changed, 52 insertions(+), 35 deletions(-) diff --git a/lib/pages/video/detail/introduction/controller.dart b/lib/pages/video/detail/introduction/controller.dart index cd179979..6efd6bd4 100644 --- a/lib/pages/video/detail/introduction/controller.dart +++ b/lib/pages/video/detail/introduction/controller.dart @@ -740,13 +740,18 @@ class VideoIntroController extends GetxController } /// 播放上一个 - bool prevPlay() { + bool prevPlay([bool skipPages = false]) { final List episodes = []; bool isPages = false; - if ((videoDetail.value.pages?.length ?? 0) > 1) { + + final videoDetailCtr = Get.find(tag: heroTag); + + if (skipPages.not && (videoDetail.value.pages?.length ?? 0) > 1) { isPages = true; final List pages = videoDetail.value.pages!; episodes.addAll(pages); + } else if (videoDetailCtr.isPlayAll) { + episodes.addAll(videoDetailCtr.mediaList); } else if (videoDetail.value.ugcSeason != null) { final UgcSeason ugcSeason = videoDetail.value.ugcSeason!; final List sections = ugcSeason.sections!; @@ -755,14 +760,19 @@ class VideoIntroController extends GetxController episodes.addAll(episodesList); } } - final int currentIndex = - episodes.indexWhere((e) => e.cid == lastPlayCid.value); + + final int currentIndex = episodes.indexWhere((e) => + e.cid == + (skipPages ? videoDetail.value.pages!.first.cid : lastPlayCid.value)); int prevIndex = currentIndex - 1; - final videoDetailCtr = Get.find(tag: heroTag); final PlayRepeat playRepeat = videoDetailCtr.plPlayerController.playRepeat; // 列表循环 if (prevIndex < 0) { + if (isPages && + (videoDetailCtr.isPlayAll || videoDetail.value.ugcSeason != null)) { + return prevPlay(true); + } if (playRepeat == PlayRepeat.listCycle) { prevIndex = episodes.length - 1; } else { @@ -777,14 +787,14 @@ class VideoIntroController extends GetxController } /// 列表循环或者顺序播放时,自动播放下一个 - bool nextPlay() { + bool nextPlay([bool skipPages = false]) { try { final List episodes = []; bool isPages = false; final videoDetailCtr = Get.find(tag: heroTag); // part -> playall -> season - if ((videoDetail.value.pages?.length ?? 0) > 1) { + if (skipPages.not && (videoDetail.value.pages?.length ?? 0) > 1) { isPages = true; final List pages = videoDetail.value.pages!; episodes.addAll(pages); @@ -810,16 +820,26 @@ class VideoIntroController extends GetxController return false; } - final int currentIndex = - episodes.indexWhere((e) => e.cid == videoDetailCtr.cid.value); + final int currentIndex = episodes.indexWhere((e) => + e.cid == + (skipPages + ? videoDetail.value.pages!.first.cid + : videoDetailCtr.cid.value)); int nextIndex = currentIndex + 1; - if (videoDetailCtr.isPlayAll && currentIndex == episodes.length - 2) { + if (isPages.not && + videoDetailCtr.isPlayAll && + currentIndex == episodes.length - 2) { videoDetailCtr.getMediaList(); } // 列表循环 if (nextIndex >= episodes.length) { + if (isPages && + (videoDetailCtr.isPlayAll || videoDetail.value.ugcSeason != null)) { + return nextPlay(true); + } + if (playRepeat == PlayRepeat.listCycle) { nextIndex = 0; } else if (playRepeat == PlayRepeat.autoPlayRelated && diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index 89e01e03..6ad39828 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -838,13 +838,14 @@ class _VideoInfoState extends State with TickerProviderStateMixin { (context.orientation != Orientation.landscape || (context.orientation == Orientation.landscape && videoDetailCtr.horizontalSeasonPanel.not))) - SeasonPanel( - heroTag: widget.heroTag, - ugcSeason: videoDetail.ugcSeason!, - changeFuc: videoIntroController.changeSeasonOrbangu, - showEpisodes: widget.showEpisodes, - pages: videoDetail.pages, - videoIntroController: videoIntroController, + Obx( + () => SeasonPanel( + key: ValueKey(videoIntroController.videoDetail.value), + heroTag: widget.heroTag, + changeFuc: videoIntroController.changeSeasonOrbangu, + showEpisodes: widget.showEpisodes, + videoIntroController: videoIntroController, + ), ), if (!widget.loadingStatus && videoDetail.pages != null && @@ -852,12 +853,15 @@ class _VideoInfoState extends State with TickerProviderStateMixin { (context.orientation != Orientation.landscape || (context.orientation == Orientation.landscape && videoDetailCtr.horizontalSeasonPanel.not))) ...[ - PagesPanel( - heroTag: widget.heroTag, - videoIntroController: videoIntroController, - bvid: videoIntroController.bvid, - changeFuc: videoIntroController.changeSeasonOrbangu, - showEpisodes: widget.showEpisodes, + Obx( + () => PagesPanel( + key: ValueKey(videoIntroController.videoDetail.value), + heroTag: widget.heroTag, + videoIntroController: videoIntroController, + bvid: videoIntroController.bvid, + changeFuc: videoIntroController.changeSeasonOrbangu, + showEpisodes: widget.showEpisodes, + ), ), ], ], diff --git a/lib/pages/video/detail/introduction/widgets/season.dart b/lib/pages/video/detail/introduction/widgets/season.dart index 13e88237..95ae5d60 100644 --- a/lib/pages/video/detail/introduction/widgets/season.dart +++ b/lib/pages/video/detail/introduction/widgets/season.dart @@ -10,19 +10,15 @@ import 'package:PiliPlus/pages/video/detail/index.dart'; class SeasonPanel extends StatefulWidget { const SeasonPanel({ super.key, - required this.ugcSeason, required this.changeFuc, required this.heroTag, required this.showEpisodes, - required this.pages, this.onTap, required this.videoIntroController, }); - final UgcSeason ugcSeason; final Function changeFuc; final String heroTag; final Function showEpisodes; - final List? pages; final bool? onTap; final VideoIntroController videoIntroController; @@ -72,7 +68,8 @@ class _SeasonPanelState extends State { (EpisodeItem e) => e.cid == _videoDetailController.seasonCid); _listener = _videoDetailController.cid.listen((int cid) { if (_videoDetailController.seasonCid != cid) { - bool isPart = widget.pages?.indexWhere((item) => item.cid == cid) != -1; + bool isPart = + videoDetail.pages?.indexWhere((item) => item.cid == cid) != -1; if (isPart.not) { _videoDetailController.seasonCid = cid; } @@ -121,7 +118,7 @@ class _SeasonPanelState extends State { ? null : () => widget.showEpisodes( _videoDetailController.seasonIndex.value, - widget.ugcSeason, + videoDetail.ugcSeason, null, _videoDetailController.bvid, null, @@ -133,7 +130,7 @@ class _SeasonPanelState extends State { children: [ Expanded( child: Text( - '合集:${widget.ugcSeason.title!}', + '合集:${videoDetail.ugcSeason!.title!}', style: Theme.of(context).textTheme.labelMedium, overflow: TextOverflow.ellipsis, ), @@ -170,7 +167,7 @@ class _SeasonPanelState extends State { } void _findEpisode() { - final List sections = widget.ugcSeason.sections!; + final List sections = videoDetail.ugcSeason!.sections!; for (int i = 0; i < sections.length; i++) { final List episodesList = sections[i].episodes!; for (int j = 0; j < episodesList.length; j++) { diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index 4b6d84f9..f6875392 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -1657,10 +1657,8 @@ class _VideoDetailPageState extends State child: SeasonPanel( heroTag: heroTag, onTap: false, - ugcSeason: videoIntroController.videoDetail.value.ugcSeason!, changeFuc: videoIntroController.changeSeasonOrbangu, showEpisodes: showEpisodes, - pages: videoIntroController.videoDetail.value.pages, videoIntroController: videoIntroController, ), ), diff --git a/lib/pages/video/detail/view_v.dart b/lib/pages/video/detail/view_v.dart index ab88bfed..adeb2d97 100644 --- a/lib/pages/video/detail/view_v.dart +++ b/lib/pages/video/detail/view_v.dart @@ -2060,10 +2060,8 @@ class _VideoDetailPageVState extends State child: SeasonPanel( heroTag: heroTag, onTap: false, - ugcSeason: videoIntroController.videoDetail.value.ugcSeason!, changeFuc: videoIntroController.changeSeasonOrbangu, showEpisodes: showEpisodes, - pages: videoIntroController.videoDetail.value.pages, videoIntroController: videoIntroController, ), ),